aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend.cpp
diff options
context:
space:
mode:
authorRilleP <rikkypikki@hotmail.com>2024-04-10 19:10:33 +0200
committerGitHub <noreply@github.com>2024-04-10 19:10:33 +0200
commit95a38d5a96322cd9adbb03bd5b7425b93469e62f (patch)
tree8cdc3b962506ddc4b7b1883f0e2ecb9dce54e2f9 /src/llvm_backend.cpp
parent239d4e10762a12e96280bd91003acbf2170cadf2 (diff)
parent13e459980b0143b49762cdfd04dd5cf1bbf83daa (diff)
Merge branch 'master' into parsing-package-fixes
Diffstat (limited to 'src/llvm_backend.cpp')
-rw-r--r--src/llvm_backend.cpp95
1 files changed, 28 insertions, 67 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 003424e0a..645a091b0 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -334,7 +334,7 @@ gb_internal void lb_add_callsite_force_inline(lbProcedure *p, lbValue ret_value)
gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) {
type = core_type(type);
- GB_ASSERT_MSG(is_type_valid_for_keys(type), "%s", type_to_string(type));
+ GB_ASSERT_MSG(is_type_comparable(type), "%s", type_to_string(type));
Type *pt = alloc_type_pointer(type);
@@ -1053,36 +1053,6 @@ struct lbGlobalVariable {
bool is_initialized;
};
-gb_internal lbProcedure *lb_create_startup_type_info(lbModule *m) {
- if (build_context.no_rtti) {
- return nullptr;
- }
- Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl);
-
- lbProcedure *p = lb_create_dummy_procedure(m, str_lit(LB_STARTUP_TYPE_INFO_PROC_NAME), proc_type);
- p->is_startup = true;
- LLVMSetLinkage(p->value, LLVMInternalLinkage);
-
- lb_add_attribute_to_proc(m, p->value, "nounwind");
- if (!LB_USE_GIANT_PACKED_STRUCT) {
- lb_add_attribute_to_proc(m, p->value, "optnone");
- lb_add_attribute_to_proc(m, p->value, "noinline");
- }
-
- lb_begin_procedure_body(p);
-
- lb_setup_type_info_data(p);
-
- lb_end_procedure_body(p);
-
- if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
- gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
- LLVMDumpValue(p->value);
- gb_printf_err("\n\n\n\n");
- LLVMVerifyFunction(p->value, LLVMAbortProcessAction);
- }
- return p;
-}
gb_internal lbProcedure *lb_create_objc_names(lbModule *main_module) {
if (build_context.metrics.os != TargetOs_darwin) {
@@ -1124,7 +1094,7 @@ gb_internal void lb_finalize_objc_names(lbProcedure *p) {
lb_end_procedure_body(p);
}
-gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, lbProcedure *objc_names, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
+gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *objc_names, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_STARTUP_RUNTIME_PROC_NAME), proc_type);
@@ -1134,9 +1104,7 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
lb_begin_procedure_body(p);
- if (startup_type_info) {
- LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, startup_type_info->type), startup_type_info->value, nullptr, 0, "");
- }
+ lb_setup_type_info_data(main_module);
if (objc_names) {
LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, objc_names->type), objc_names->value, nullptr, 0, "");
@@ -1196,7 +1164,7 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
lbValue data = lb_emit_struct_ep(p, var.var, 0);
lbValue ti = lb_emit_struct_ep(p, var.var, 1);
lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
- lb_emit_store(p, ti, lb_type_info(main_module, var_type));
+ lb_emit_store(p, ti, lb_type_info(p, var_type));
} else {
LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
lbValue src0 = lb_emit_conv(p, var.init, t);
@@ -1382,7 +1350,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
if (LLVMTargetMachineEmitToFile(wd->target_machine, wd->m->mod, cast(char *)wd->filepath_obj.text, wd->code_gen_file_type, &llvm_error)) {
gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
+ exit_with_errors();
}
debugf("Generated File: %.*s\n", LIT(wd->filepath_obj));
return 0;
@@ -1421,7 +1389,6 @@ gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) {
}
if (m == &m->gen->default_module) {
- lb_llvm_function_pass_per_function_internal(m, m->gen->startup_type_info);
lb_llvm_function_pass_per_function_internal(m, m->gen->startup_runtime);
lb_llvm_function_pass_per_function_internal(m, m->gen->cleanup_runtime);
lb_llvm_function_pass_per_function_internal(m, m->gen->objc_names);
@@ -1952,7 +1919,7 @@ verify
gb_printf_err("LLVM Error: %s\n", llvm_error);
}
}
- gb_exit(1);
+ exit_with_errors();
return 1;
}
#endif
@@ -2011,12 +1978,6 @@ gb_internal void lb_debug_info_complete_types_and_finalize(lbGenerator *gen) {
for (auto const &entry : gen->modules) {
lbModule *m = entry.value;
if (m->debug_builder != nullptr) {
- lb_debug_complete_types(m);
- }
- }
- for (auto const &entry : gen->modules) {
- lbModule *m = entry.value;
- if (m->debug_builder != nullptr) {
LLVMDIBuilderFinalize(m->debug_builder);
}
}
@@ -2137,11 +2098,11 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_verification_worker_proc) {
String filepath_ll = lb_filepath_ll_for_module(m);
if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
+ exit_with_errors();
return false;
}
}
- gb_exit(1);
+ exit_with_errors();
return 1;
}
return 0;
@@ -2226,7 +2187,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading)
if (LLVMTargetMachineEmitToFile(m->target_machine, m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
+ exit_with_errors();
return false;
}
debugf("Generated File: %.*s\n", LIT(filepath_obj));
@@ -2426,7 +2387,7 @@ gb_internal void lb_generate_procedure(lbModule *m, lbProcedure *p) {
gb_printf_err("LLVM Error: %s\n", llvm_error);
}
LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
- gb_exit(1);
+ exit_with_errors();
}
}
@@ -2597,8 +2558,8 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
switch (build_context.reloc_mode) {
case RelocMode_Default:
- if (build_context.metrics.os == TargetOs_openbsd) {
- // Always use PIC for OpenBSD: it defaults to PIE
+ if (build_context.metrics.os == TargetOs_openbsd || build_context.metrics.os == TargetOs_haiku) {
+ // Always use PIC for OpenBSD and Haiku: they default to PIE
reloc_mode = LLVMRelocPIC;
}
break;
@@ -2686,17 +2647,19 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
{ // Add type info data
isize max_type_info_count = info->minimum_dependency_type_info_set.count+1;
- Type *t = alloc_type_array(t_type_info, max_type_info_count);
+ Type *t = alloc_type_array(t_type_info_ptr, max_type_info_count);
// IMPORTANT NOTE(bill): As LLVM does not have a union type, an array of unions cannot be initialized
// at compile time without cheating in some way. This means to emulate an array of unions is to use
// a giant packed struct of "corrected" data types.
- LLVMTypeRef internal_llvm_type = lb_setup_type_info_data_internal_type(m, max_type_info_count);
+ LLVMTypeRef internal_llvm_type = lb_type(m, t);
LLVMValueRef g = LLVMAddGlobal(m->mod, internal_llvm_type, LB_TYPE_INFO_DATA_NAME);
LLVMSetInitializer(g, LLVMConstNull(internal_llvm_type));
LLVMSetLinkage(g, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage);
+ LLVMSetUnnamedAddress(g, LLVMGlobalUnnamedAddr);
+ LLVMSetGlobalConstant(g, /*true*/false);
lbValue value = {};
value.value = g;
@@ -2705,15 +2668,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
lb_global_type_info_data_entity = alloc_entity_variable(nullptr, make_token_ident(LB_TYPE_INFO_DATA_NAME), t, EntityState_Resolved);
lb_add_entity(m, lb_global_type_info_data_entity, value);
- if (LB_USE_GIANT_PACKED_STRUCT) {
- LLVMSetLinkage(g, LLVMPrivateLinkage);
- LLVMSetUnnamedAddress(g, LLVMGlobalUnnamedAddr);
- LLVMSetGlobalConstant(g, /*true*/false);
- }
}
{ // Type info member buffer
// NOTE(bill): Removes need for heap allocation by making it global memory
isize count = 0;
+ isize offsets_extra = 0;
for (Type *t : m->info->type_info_types) {
isize index = lb_type_info_index(m->info, t, false);
@@ -2731,6 +2690,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
case Type_Tuple:
count += t->Tuple.variables.count;
break;
+ case Type_BitField:
+ count += t->BitField.fields.count;
+ // Twice is needed for the bit_offsets
+ offsets_extra += t->BitField.fields.count;
+ break;
}
}
@@ -2739,15 +2703,13 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
LLVMSetLinkage(g, LLVMInternalLinkage);
- if (LB_USE_GIANT_PACKED_STRUCT) {
- lb_make_global_private_const(g);
- }
+ lb_make_global_private_const(g);
return lb_addr({g, alloc_type_pointer(t)});
};
lb_global_type_info_member_types = global_type_info_make(m, LB_TYPE_INFO_TYPES_NAME, t_type_info_ptr, count);
lb_global_type_info_member_names = global_type_info_make(m, LB_TYPE_INFO_NAMES_NAME, t_string, count);
- lb_global_type_info_member_offsets = global_type_info_make(m, LB_TYPE_INFO_OFFSETS_NAME, t_uintptr, count);
+ lb_global_type_info_member_offsets = global_type_info_make(m, LB_TYPE_INFO_OFFSETS_NAME, t_uintptr, count+offsets_extra);
lb_global_type_info_member_usings = global_type_info_make(m, LB_TYPE_INFO_USINGS_NAME, t_bool, count);
lb_global_type_info_member_tags = global_type_info_make(m, LB_TYPE_INFO_TAGS_NAME, t_string, count);
}
@@ -2910,12 +2872,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
}
}
- TIME_SECTION("LLVM Runtime Type Information Creation");
- gen->startup_type_info = lb_create_startup_type_info(default_module);
+ TIME_SECTION("LLVM Runtime Objective-C Names Creation");
gen->objc_names = lb_create_objc_names(default_module);
TIME_SECTION("LLVM Runtime Startup Creation (Global Variables & @(init))");
- gen->startup_runtime = lb_create_startup_runtime(default_module, gen->startup_type_info, gen->objc_names, global_variables);
+ gen->startup_runtime = lb_create_startup_runtime(default_module, gen->objc_names, global_variables);
TIME_SECTION("LLVM Runtime Cleanup Creation & @(fini)");
gen->cleanup_runtime = lb_create_cleanup_runtime(default_module);
@@ -2995,7 +2956,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
String filepath_ll = lb_filepath_ll_for_module(m);
if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
+ exit_with_errors();
return false;
}
array_add(&gen->output_temp_paths, filepath_ll);
@@ -3054,7 +3015,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
}
}
- gb_sort_array(gen->foreign_libraries.data, gen->foreign_libraries.count, foreign_library_cmp);
+ array_sort(gen->foreign_libraries, foreign_library_cmp);
return true;
}