aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-03-01 12:15:38 +0000
committergingerBill <bill@gingerbill.org>2021-03-01 12:15:38 +0000
commit9e0210f7f636f6b75376ad9fe385ab2cb736896b (patch)
tree42722970ce80db4b5910258799252ab1c34c0cfb /src/llvm_backend.cpp
parent302742689b68d36e2adc49eda5f480da182d2653 (diff)
parent6ffb4d268304fc098b05cd38a4adc9207256e16b (diff)
Merge branch 'master' of https://github.com/odin-lang/Odin
Diffstat (limited to 'src/llvm_backend.cpp')
-rw-r--r--src/llvm_backend.cpp124
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));