diff options
| author | gingerBill <bill@gingerbill.org> | 2021-03-01 12:15:38 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-03-01 12:15:38 +0000 |
| commit | 9e0210f7f636f6b75376ad9fe385ab2cb736896b (patch) | |
| tree | 42722970ce80db4b5910258799252ab1c34c0cfb /src/llvm_backend.cpp | |
| parent | 302742689b68d36e2adc49eda5f480da182d2653 (diff) | |
| parent | 6ffb4d268304fc098b05cd38a4adc9207256e16b (diff) | |
Merge branch 'master' of https://github.com/odin-lang/Odin
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 124 |
1 files changed, 76 insertions, 48 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 97e88cb2b..872ea3281 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -429,6 +429,14 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { GB_ASSERT(value.value != nullptr); value = lb_emit_conv(p, value, lb_addr_type(addr)); + if (lb_is_const_or_global(value)) { + // NOTE(bill): Just bypass the actual storage and set the initializer + if (LLVMGetValueKind(addr.addr.value) == LLVMGlobalVariableValueKind) { + LLVMSetInitializer(addr.addr.value, value.value); + return; + } + } + lb_emit_store(p, addr.addr, value); } @@ -882,10 +890,6 @@ String lb_get_entity_name(lbModule *m, Entity *e, String default_name) { } if (e->kind == Entity_TypeName) { - if ((e->scope->flags & ScopeFlag_File) == 0) { - gb_printf_err("<<< %.*s %.*s %p\n", LIT(e->token.string), LIT(name), e); - } - e->TypeName.ir_mangled_name = name; } else if (e->kind == Entity_Procedure) { e->Procedure.link_name = name; @@ -1200,7 +1204,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { for_array(i, type->Struct.fields) { Entity *field = type->Struct.fields[i]; - fields[i+offset] = lb_type(m, field->type); + fields[i+offset] = lb_type(m, field->type); } @@ -1271,7 +1275,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { } case Type_Proc: - if (m->internal_type_level > 256) { // TODO HACK(bill): is this really enough? + // if (m->internal_type_level > 256) { // TODO HACK(bill): is this really enough? + if (m->internal_type_level > 1) { // TODO HACK(bill): is this really enough? return LLVMPointerType(LLVMIntTypeInContext(m->ctx, 8), 0); } else { unsigned param_count = 0; @@ -8511,6 +8516,13 @@ bool lb_is_const(lbValue value) { } return false; } + + +bool lb_is_const_or_global(lbValue value) { + return (LLVMGetValueKind(value.value) == LLVMGlobalVariableValueKind) || lb_is_const(value); +} + + bool lb_is_const_nil(lbValue value) { LLVMValueRef v = value.value; if (LLVMIsConstant(v)) { @@ -10048,7 +10060,7 @@ lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) { LLVMValueRef len = LLVMConstExtractValue(key.value, len_indices, gb_count_of(len_indices)); isize length = LLVMConstIntGetSExtValue(len); char const *text = nullptr; - if (length != 0) { + if (false && length != 0) { if (LLVMGetConstOpcode(data) != LLVMGetElementPtr) { return {}; } @@ -11523,8 +11535,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da for_array(type_info_type_index, info->type_info_types) { Type *t = info->type_info_types[type_info_type_index]; - t = default_type(t); - if (t == t_invalid) { + if (t == nullptr || t == t_invalid) { continue; } @@ -12452,6 +12463,7 @@ void lb_generate_code(lbGenerator *gen) { } if (is_foreign) { LLVMSetExternallyInitialized(g.value, true); + lb_add_foreign_library_path(m, e->Variable.foreign_library); } else { LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); } @@ -12460,6 +12472,10 @@ void lb_generate_code(lbGenerator *gen) { LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); } + if (e->flags & EntityFlag_Static) { + LLVMSetLinkage(g.value, LLVMInternalLinkage); + } + GlobalVariable var = {}; var.var = g; var.decl = decl; @@ -12551,6 +12567,8 @@ void lb_generate_code(lbGenerator *gen) { LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(mod); defer (LLVMDisposePassManager(default_function_pass_manager)); + + LLVMInitializeFunctionPassManager(default_function_pass_manager); { auto dfpm = default_function_pass_manager; @@ -12615,10 +12633,12 @@ void lb_generate_code(lbGenerator *gen) { } while (repeat_count --> 0); } } + LLVMFinalizeFunctionPassManager(default_function_pass_manager); LLVMPassManagerRef default_function_pass_manager_without_memcpy = LLVMCreateFunctionPassManagerForModule(mod); defer (LLVMDisposePassManager(default_function_pass_manager_without_memcpy)); + LLVMInitializeFunctionPassManager(default_function_pass_manager_without_memcpy); { auto dfpm = default_function_pass_manager_without_memcpy; LLVMAddPromoteMemoryToRegisterPass(dfpm); @@ -12631,8 +12651,9 @@ void lb_generate_code(lbGenerator *gen) { LLVMAddCFGSimplificationPass(dfpm); // LLVMAddUnifyFunctionExitNodesPass(dfpm); } + LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy); - TIME_SECTION("LLVM Runtime Creation"); + TIME_SECTION("LLVM Runtime Type Information Creation"); lbProcedure *startup_type_info = nullptr; lbProcedure *startup_runtime = nullptr; @@ -12661,6 +12682,7 @@ void lb_generate_code(lbGenerator *gen) { LLVMRunFunctionPassManager(default_function_pass_manager, p->value); } + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); { // Startup Runtime Type *params = alloc_type_tuple(); Type *results = alloc_type_tuple(); @@ -12678,30 +12700,30 @@ void lb_generate_code(lbGenerator *gen) { for_array(i, global_variables) { auto *var = &global_variables[i]; + if (var->is_initialized) { + continue; + } + + Entity *e = var->decl->entity; + GB_ASSERT(e->kind == Entity_Variable); + if (var->decl->init_expr != nullptr) { + // gb_printf_err("%s\n", expr_to_string(var->decl->init_expr)); lbValue init = lb_build_expr(p, var->decl->init_expr); - if (lb_is_const(init)) { + LLVMValueKind value_kind = LLVMGetValueKind(init.value); + // gb_printf_err("%s %d\n", LLVMPrintValueToString(init.value)); + + if (lb_is_const_or_global(init)) { if (!var->is_initialized) { LLVMSetInitializer(var->var.value, init.value); var->is_initialized = true; + continue; } } else { var->init = init; } } - Entity *e = var->decl->entity; - GB_ASSERT(e->kind == Entity_Variable); - - if (e->Variable.is_foreign) { - Entity *fl = e->Procedure.foreign_library; - lb_add_foreign_library_path(m, fl); - } - - if (e->flags & EntityFlag_Static) { - LLVMSetLinkage(var->var.value, LLVMInternalLinkage); - } - if (var->init.value != nullptr) { GB_ASSERT(!var->is_initialized); Type *t = type_deref(var->var.type); @@ -12718,7 +12740,12 @@ void lb_generate_code(lbGenerator *gen) { lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr)); lb_emit_store(p, ti, lb_type_info(m, var_type)); } else { - lb_emit_store(p, var->var, lb_emit_conv(p, var->init, t)); + LLVMTypeRef pvt = LLVMTypeOf(var->var.value); + LLVMTypeRef vt = LLVMGetElementType(pvt); + lbValue src0 = lb_emit_conv(p, var->init, t); + LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt); + LLVMValueRef dst = var->var.value; + LLVMBuildStore(p->builder, src, dst); } var->is_initialized = true; @@ -12758,6 +12785,7 @@ void lb_generate_code(lbGenerator *gen) { } if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { + TIME_SECTION("LLVM DLL main"); Type *params = alloc_type_tuple(); @@ -12858,30 +12886,30 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Function Pass"); - - for_array(i, m->procedures_to_generate) { - lbProcedure *p = m->procedures_to_generate[i]; - if (p->body != nullptr) { // Build Procedure - for (i32 i = 0; i <= build_context.optimization_level; i++) { - if (p->flags & lbProcedureFlag_WithoutMemcpyPass) { - LLVMRunFunctionPassManager(default_function_pass_manager_without_memcpy, p->value); - } else { - LLVMRunFunctionPassManager(default_function_pass_manager, p->value); + { + for_array(i, m->procedures_to_generate) { + lbProcedure *p = m->procedures_to_generate[i]; + if (p->body != nullptr) { // Build Procedure + for (i32 i = 0; i <= build_context.optimization_level; i++) { + if (p->flags & lbProcedureFlag_WithoutMemcpyPass) { + LLVMRunFunctionPassManager(default_function_pass_manager_without_memcpy, p->value); + } else { + LLVMRunFunctionPassManager(default_function_pass_manager, p->value); + } } } } - } - for_array(i, m->equal_procs.entries) { - lbProcedure *p = m->equal_procs.entries[i].value; - LLVMRunFunctionPassManager(default_function_pass_manager, p->value); - } - for_array(i, m->hasher_procs.entries) { - lbProcedure *p = m->hasher_procs.entries[i].value; - LLVMRunFunctionPassManager(default_function_pass_manager, p->value); + for_array(i, m->equal_procs.entries) { + lbProcedure *p = m->equal_procs.entries[i].value; + LLVMRunFunctionPassManager(default_function_pass_manager, p->value); + } + for_array(i, m->hasher_procs.entries) { + lbProcedure *p = m->hasher_procs.entries[i].value; + LLVMRunFunctionPassManager(default_function_pass_manager, p->value); + } } - TIME_SECTION("LLVM Module Pass"); LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager(); @@ -12889,12 +12917,12 @@ void lb_generate_code(lbGenerator *gen) { LLVMAddAlwaysInlinerPass(module_pass_manager); LLVMAddStripDeadPrototypesPass(module_pass_manager); LLVMAddAnalysisPasses(target_machine, module_pass_manager); - // if (build_context.optimization_level >= 2) { - // LLVMAddArgumentPromotionPass(module_pass_manager); - // LLVMAddConstantMergePass(module_pass_manager); - // LLVMAddGlobalDCEPass(module_pass_manager); - // LLVMAddDeadArgEliminationPass(module_pass_manager); - // } + if (build_context.optimization_level >= 2) { + LLVMAddArgumentPromotionPass(module_pass_manager); + LLVMAddConstantMergePass(module_pass_manager); + LLVMAddGlobalDCEPass(module_pass_manager); + LLVMAddDeadArgEliminationPass(module_pass_manager); + } LLVMPassManagerBuilderRef pass_manager_builder = LLVMPassManagerBuilderCreate(); defer (LLVMPassManagerBuilderDispose(pass_manager_builder)); |