aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-05-03 17:43:14 +0100
committergingerBill <bill@gingerbill.org>2021-05-03 17:43:14 +0100
commit746e880eb521e6cf5b6a452004da9bc5d2095076 (patch)
tree7174a4d70632e65d11824d956df00e14bad13188 /src
parente4286d0ff9d383d03b220ac8fc52934853b35c34 (diff)
Begin work on making LLVM backend work with multiple modules for possible faster compilation
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp6
-rw-r--r--src/llvm_backend.cpp668
-rw-r--r--src/llvm_backend.hpp11
-rw-r--r--src/main.cpp11
4 files changed, 417 insertions, 279 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 77d9cc506..77046cf6d 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -207,6 +207,8 @@ struct BuildContext {
bool ignore_microsoft_magic;
bool linker_map_file;
+ bool use_separate_modules;
+
u32 cmd_doc_flags;
Array<String> extra_packages;
@@ -807,6 +809,10 @@ void init_build_context(TargetMetrics *cross_target) {
bc->max_align = metrics->max_align;
bc->link_flags = str_lit(" ");
+ if (bc->metrics.os == TargetOs_windows) {
+ // bc->use_separate_modules = bc->optimization_level == 0;
+ }
+
// NOTE(zangent): The linker flags to set the build architecture are different
// across OSs. It doesn't make sense to allocate extra data on the heap
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 2c61132dd..a7c149f06 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -1,3 +1,7 @@
+#ifndef USE_SEPARTE_MODULES
+#define USE_SEPARTE_MODULES build_context.use_separate_modules
+#endif
+
#include "llvm_backend.hpp"
#include "llvm_abi.cpp"
#include "llvm_backend_opt.cpp"
@@ -74,6 +78,15 @@ bool lb_is_instr_terminating(LLVMValueRef instr) {
+lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
+ auto *found = map_get(&gen->modules, hash_pointer(pkg));
+ if (found) {
+ return *found;
+ }
+ return &gen->default_module;
+}
+
+
lbAddr lb_addr(lbValue addr) {
lbAddr v = {lbAddr_Default, addr};
if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
@@ -2528,10 +2541,17 @@ void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
GB_ASSERT(p->abi_function_type != nullptr);
}
-lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
+lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
GB_ASSERT(entity != nullptr);
- String link_name = lb_get_entity_name(m, entity);
+ String link_name = {};
+
+ if (ignore_body) {
+ lbModule *other_module = lb_pkg_module(m->gen, entity->pkg);
+ link_name = lb_get_entity_name(other_module, entity);
+ } else {
+ link_name = lb_get_entity_name(m, entity);
+ }
{
StringHashKey key = string_hash_string(link_name);
@@ -2699,6 +2719,10 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
}
}
+ if (ignore_body) {
+ p->body = nullptr;
+ }
+
if (m->debug_builder) { // Debug Information
Type *bt = base_type(p->type);
@@ -5484,9 +5508,10 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
isize max_len = 7+8+1;
char *name = gb_alloc_array(permanent_allocator(), char, max_len);
- isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index);
+
+ u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_array_index, 1);
+ isize len = gb_snprintf(name, max_len, "csbs$%x", id);
len -= 1;
- m->global_array_index++;
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
LLVMSetInitializer(global_data, data);
@@ -5526,9 +5551,9 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
{
isize max_len = 7+8+1;
name = gb_alloc_array(permanent_allocator(), char, max_len);
- isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index);
+ u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_array_index, 1);
+ isize len = gb_snprintf(name, max_len, "csbs$%x", id);
len -= 1;
- m->global_array_index++;
}
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
LLVMSetInitializer(global_data, data);
@@ -5684,6 +5709,7 @@ LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_
}
lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
+ GB_ASSERT(is_type_proc(e->type));
e = strip_entity_wrapping(e);
GB_ASSERT(e != nullptr);
auto *found = map_get(&m->values, hash_entity(e));
@@ -5691,8 +5717,14 @@ lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
return *found;
}
- // TODO(bill): this is
- lbProcedure *missing_proc = lb_create_procedure(m, e);
+ bool ignore_body = false;
+
+ if (USE_SEPARTE_MODULES) {
+ lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
+ ignore_body = other_module != m;
+ }
+
+ lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body);
found = map_get(&m->values, hash_entity(e));
if (found) {
return *found;
@@ -5702,6 +5734,47 @@ lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
return {};
}
+lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
+ e = strip_entity_wrapping(e);
+ GB_ASSERT(e != nullptr);
+ if (is_type_proc(e->type)) {
+ return lb_find_procedure_value_from_entity(m, e);
+ }
+
+ auto *found = map_get(&m->values, hash_entity(e));
+ if (found) {
+ return *found;
+ }
+
+ if (USE_SEPARTE_MODULES) {
+ lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
+ bool is_external = other_module != m;
+ if (!is_external) {
+ other_module = e->code_gen_module;
+ is_external = other_module != m;
+ }
+
+ if (is_external) {
+ String name = lb_get_entity_name(other_module, e);
+
+ lbValue g = {};
+ g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
+ g.type = alloc_type_pointer(e->type);
+ LLVMSetExternallyInitialized(g.value, true);
+
+ lb_add_entity(m, e, g);
+ lb_add_member(m, name, g);
+ return g;
+ }
+ }
+
+ GB_PANIC("\n\tError in: %s, missing value %.*s\n", token_pos_to_string(e->token.pos), LIT(e->token.string));
+ return {};
+}
+
+
+
+
lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local) {
LLVMContextRef ctx = m->ctx;
@@ -5777,8 +5850,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
} else {
isize max_len = 7+8+1;
char *str = gb_alloc_array(permanent_allocator(), char, max_len);
- isize len = gb_snprintf(str, max_len, "csba$%x", m->global_array_index);
- m->global_array_index++;
+ u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_array_index, 1);
+ isize len = gb_snprintf(str, max_len, "csba$%x", id);
String name = make_string(cast(u8 *)str, len-1);
@@ -8192,31 +8265,18 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
}
}
-lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
- // LLVMMetadataRef curr_loc = LLVMGetCurrentDebugLocation2(p->builder);
- // LLVMSetCurrentDebugLocation2(p->builder, nullptr);
- // defer (if (curr_loc) {
- // LLVMSetCurrentDebugLocation2(p->builder, curr_loc);
- // });
- String name = make_string_c(c_name);
-
-
- AstPackage *pkg = p->module->info->runtime_package;
+lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
+ AstPackage *pkg = m->info->runtime_package;
Entity *e = scope_lookup_current(pkg->scope, name);
+ return lb_find_procedure_value_from_entity(m, e);
+}
- lbValue *found = nullptr;
- if (p->module != e->code_gen_module) {
- gb_mutex_lock(&p->module->mutex);
- }
- GB_ASSERT(e->code_gen_module != nullptr);
- found = map_get(&e->code_gen_module->values, hash_entity(e));
- if (p->module != e->code_gen_module) {
- gb_mutex_unlock(&p->module->mutex);
- }
- GB_ASSERT_MSG(found != nullptr, "%s", c_name);
- return lb_emit_call(p, *found, args);
+lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
+ String name = make_string_c(c_name);
+ lbValue proc = lb_lookup_runtime_procedure(p->module, name);
+ return lb_emit_call(p, proc, args);
}
lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, bool use_return_ptr_hint) {
@@ -9946,24 +10006,6 @@ void lb_emit_increment(lbProcedure *p, lbValue addr) {
}
-LLVMValueRef lb_lookup_runtime_procedure(lbModule *m, String const &name) {
- AstPackage *pkg = m->info->runtime_package;
- Entity *e = scope_lookup_current(pkg->scope, name);
-
- lbValue *found = nullptr;
- if (m != e->code_gen_module) {
- gb_mutex_lock(&m->mutex);
- }
- GB_ASSERT(e->code_gen_module != nullptr);
- found = map_get(&e->code_gen_module->values, hash_entity(e));
- if (m != e->code_gen_module) {
- gb_mutex_unlock(&m->mutex);
- }
- GB_ASSERT(found != nullptr);
-
- return found->value;
-}
-
lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
GB_ASSERT(type_size_of(value.type) == type_size_of(end_type));
@@ -11122,6 +11164,44 @@ lbValue lb_emit_any_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos
}
+lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
+ auto *found = map_get(&m->values, hash_entity(e));
+ if (found) {
+ auto v = *found;
+ // NOTE(bill): This is because pointers are already pointers in LLVM
+ if (is_type_proc(v.type)) {
+ return v;
+ }
+ return lb_emit_load(p, v);
+ } else if (e != nullptr && e->kind == Entity_Variable) {
+ return lb_addr_load(p, lb_build_addr(p, expr));
+ }
+
+ if (USE_SEPARTE_MODULES) {
+ lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
+ if (other_module != m) {
+ String name = lb_get_entity_name(other_module, e);
+
+ lbValue g = {};
+ g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
+ g.type = alloc_type_pointer(e->type);
+ LLVMSetExternallyInitialized(g.value, true);
+
+ lb_add_entity(m, e, g);
+ lb_add_member(m, name, g);
+ return lb_emit_load(p, g);
+ }
+ }
+
+ String pkg = {};
+ if (e->pkg) {
+ pkg = e->pkg->name;
+ }
+ gb_printf_err("Error in: %s\n", token_pos_to_string(ast_token(expr).pos));
+ GB_PANIC("nullptr value for expression from identifier: %.*s.%.*s (%p) : %s @ %p", LIT(pkg), LIT(e->token.string), e, type_to_string(e->type), expr);
+ return {};
+}
+
lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
lbModule *m = p->module;
@@ -11211,24 +11291,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
}
GB_ASSERT(e->kind != Entity_ProcGroup);
- auto *found = map_get(&p->module->values, hash_entity(e));
- if (found) {
- auto v = *found;
- // NOTE(bill): This is because pointers are already pointers in LLVM
- if (is_type_proc(v.type)) {
- return v;
- }
- return lb_emit_load(p, v);
- } else if (e != nullptr && e->kind == Entity_Variable) {
- return lb_addr_load(p, lb_build_addr(p, expr));
- }
- gb_printf_err("Error in: %s\n", token_pos_to_string(i->token.pos));
- String pkg = {};
- if (e->pkg) {
- pkg = e->pkg->name;
- }
- GB_PANIC("nullptr value for expression from identifier: %.*s.%.*s (%p) : %s @ %p", LIT(pkg), LIT(e->token.string), e, type_to_string(e->type), expr);
- return {};
+ return lb_find_ident(p, m, e, expr);
case_end;
case_ast_node(de, DerefExpr, expr);
@@ -11609,11 +11672,14 @@ lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) {
return lb_get_soa_variable_addr(p, e);
}
+
if (v.value == nullptr) {
- error(expr, "%.*s Unknown value: %.*s, entity: %p %.*s",
- LIT(p->name),
- LIT(e->token.string), e, LIT(entity_strings[e->kind]));
- GB_PANIC("Unknown value");
+ return lb_addr(lb_find_value_from_entity(p->module, e));
+
+ // error(expr, "%.*s Unknown value: %.*s, entity: %p %.*s",
+ // LIT(p->name),
+ // LIT(e->token.string), e, LIT(entity_strings[e->kind]));
+ // GB_PANIC("Unknown value");
}
return lb_addr(v);
@@ -13031,18 +13097,31 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
gen->info = &c->info;
map_init(&gen->modules, permanent_allocator(), gen->info->packages.entries.count*2);
+ map_init(&gen->modules_through_ctx, permanent_allocator(), gen->info->packages.entries.count*2);
- for_array(i, gen->info->packages.entries) {
- AstPackage *pkg = gen->info->packages.entries[i].value;
+ if (USE_SEPARTE_MODULES) {
+ for_array(i, gen->info->packages.entries) {
+ AstPackage *pkg = gen->info->packages.entries[i].value;
- auto m = gb_alloc_item(permanent_allocator(), lbModule);
- m->pkg = pkg;
- map_set(&gen->modules, hash_pointer(pkg), m);
- lb_init_module(m, c);
+ auto m = gb_alloc_item(permanent_allocator(), lbModule);
+ m->pkg = pkg;
+ m->gen = gen;
+ map_set(&gen->modules, hash_pointer(pkg), m);
+ lb_init_module(m, c);
+ }
}
+
+ gen->default_module.gen = gen;
map_set(&gen->modules, hash_pointer(nullptr), &gen->default_module);
lb_init_module(&gen->default_module, c);
+
+ for_array(i, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[i].value;
+ LLVMContextRef ctx = LLVMGetModuleContext(m->mod);
+ map_set(&gen->modules_through_ctx, hash_pointer(ctx), m);
+ }
+
return true;
}
@@ -13052,8 +13131,10 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) {
isize max_len = 7+8+1;
u8 *str = cast(u8 *)gb_alloc_array(permanent_allocator(), u8, max_len);
- isize len = gb_snprintf(cast(char *)str, max_len, "ggv$%x", m->global_generated_index);
- m->global_generated_index++;
+
+ u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_generated_index, 1);
+
+ isize len = gb_snprintf(cast(char *)str, max_len, "ggv$%x", id);
String name = make_string(str, len-1);
Scope *scope = nullptr;
@@ -13076,17 +13157,12 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) {
lbValue lb_find_runtime_value(lbModule *m, String const &name) {
AstPackage *p = m->info->runtime_package;
Entity *e = scope_lookup_current(p->scope, name);
- lbValue *found = map_get(&m->values, hash_entity(e));
- GB_ASSERT_MSG(found != nullptr, "Unable to find runtime value '%.*s'", LIT(name));
- lbValue value = *found;
- return value;
+ return lb_find_value_from_entity(m, e);
}
lbValue lb_find_package_value(lbModule *m, String const &pkg, String const &name) {
Entity *e = find_entity_in_pkg(m->info, pkg, name);
lbValue *found = map_get(&m->values, hash_entity(e));
- GB_ASSERT_MSG(found != nullptr, "Unable to find value '%.*s.%.*s'", LIT(pkg), LIT(name));
- lbValue value = *found;
- return value;
+ return lb_find_value_from_entity(m, e);
}
lbValue lb_get_type_info_ptr(lbModule *m, Type *type) {
@@ -13900,8 +13976,8 @@ lbProcedure *lb_create_startup_type_info(lbModule *m) {
return p;
}
-lbProcedure *lb_create_startup_runtime(lbModule *m, lbProcedure *startup_type_info, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
- LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
+lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
+ LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(main_module->mod);
defer (LLVMDisposePassManager(default_function_pass_manager));
lb_populate_function_pass_manager(default_function_pass_manager, false, build_context.optimization_level);
LLVMFinalizeFunctionPassManager(default_function_pass_manager);
@@ -13911,12 +13987,12 @@ lbProcedure *lb_create_startup_runtime(lbModule *m, lbProcedure *startup_type_in
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_RUNTIME_PROC_NAME), proc_type);
+ lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_STARTUP_RUNTIME_PROC_NAME), proc_type);
p->is_startup = true;
lb_begin_procedure_body(p);
- LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
+ LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
for_array(i, global_variables) {
auto *var = &global_variables[i];
@@ -13924,8 +14000,11 @@ lbProcedure *lb_create_startup_runtime(lbModule *m, lbProcedure *startup_type_in
continue;
}
+ lbModule *entity_module = main_module;
+
Entity *e = var->decl->entity;
GB_ASSERT(e->kind == Entity_Variable);
+ e->code_gen_module = entity_module;
if (var->decl->init_expr != nullptr) {
// gb_printf_err("%s\n", expr_to_string(var->decl->init_expr));
@@ -13951,14 +14030,14 @@ lbProcedure *lb_create_startup_runtime(lbModule *m, lbProcedure *startup_type_in
if (is_type_any(t)) {
// NOTE(bill): Edge case for 'any' type
Type *var_type = default_type(var->init.type);
- lbAddr g = lb_add_global_generated(m, var_type, var->init);
+ lbAddr g = lb_add_global_generated(main_module, var_type, var->init);
lb_addr_store(p, g, var->init);
lbValue gp = lb_addr_get_ptr(p, g);
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(m, var_type));
+ lb_emit_store(p, ti, lb_type_info(main_module, var_type));
} else {
LLVMTypeRef pvt = LLVMTypeOf(var->var.value);
LLVMTypeRef vt = LLVMGetElementType(pvt);
@@ -13975,7 +14054,7 @@ lbProcedure *lb_create_startup_runtime(lbModule *m, lbProcedure *startup_type_in
lb_end_procedure_body(p);
- if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
+ if (!main_module->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");
@@ -14085,9 +14164,8 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
args[0] = lb_addr_load(p, all_tests_slice);
lb_emit_call(p, runner, args);
} else {
- lbValue *found = map_get(&m->values, hash_entity(m->info->entry_point));
- GB_ASSERT(found != nullptr);
- lb_emit_call(p, *found, {});
+ lbValue entry_point = lb_find_procedure_value_from_entity(m, m->info->entry_point);
+ lb_emit_call(p, entry_point, {});
}
LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false));
@@ -14105,13 +14183,51 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
return p;
}
+String lb_filepath_ll_for_module(lbModule *m) {
+ String path = m->gen->output_base;
+ if (m->pkg) {
+ path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
+ }
+ path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll"));
+
+ return path;
+}
+String lb_filepath_obj_for_module(lbModule *m) {
+ String path = m->gen->output_base;
+ if (m->pkg) {
+ path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
+ }
+
+ String ext = {};
+
+ if (build_context.build_mode == BuildMode_Assembly) {
+ ext = STR_LIT(".S");
+ } else {
+ switch (build_context.metrics.os) {
+ case TargetOs_windows:
+ ext = STR_LIT(".obj");
+ break;
+ case TargetOs_darwin:
+ case TargetOs_linux:
+ case TargetOs_essence:
+ ext = STR_LIT(".o");
+ break;
+ case TargetOs_js:
+ ext = STR_LIT(".wasm-obj");
+ break;
+ }
+ }
+
+ return concatenate_strings(permanent_allocator(), path, ext);
+}
+
void lb_generate_code(lbGenerator *gen) {
#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
TIME_SECTION("LLVM Initializtion");
- lbModule *m = &gen->default_module;
+ lbModule *default_module = &gen->default_module;
CheckerInfo *info = gen->info;
auto *min_dep_set = &info->minimum_dependency_set;
@@ -14183,62 +14299,67 @@ void lb_generate_code(lbGenerator *gen) {
LLVMSetModuleDataLayout(gen->modules.entries[i].value->mod, LLVMCreateTargetDataLayout(target_machine));
}
- if (m->debug_builder) { // Debug Info
- for_array(i, info->files.entries) {
- AstFile *f = info->files.entries[i].value;
- String fullpath = f->fullpath;
- String filename = remove_directory_from_path(fullpath);
- String directory = directory_from_path(fullpath);
- LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
- cast(char const *)filename.text, filename.len,
- cast(char const *)directory.text, directory.len);
- lb_set_llvm_metadata(m, f, res);
- }
-
- gbString producer = gb_string_make(heap_allocator(), "odin");
- // producer = gb_string_append_fmt(producer, " version %.*s", LIT(ODIN_VERSION));
- // #ifdef NIGHTLY
- // producer = gb_string_appendc(producer, "-nightly");
- // #endif
- // #ifdef GIT_SHA
- // producer = gb_string_append_fmt(producer, "-%s", GIT_SHA);
- // #endif
-
- gbString split_name = gb_string_make(heap_allocator(), "");
-
- LLVMBool is_optimized = build_context.optimization_level > 0;
- AstFile *init_file = m->info->init_package->files[0];
- if (m->info->entry_point && m->info->entry_point->identifier && m->info->entry_point->identifier->file) {
- init_file = m->info->entry_point->identifier->file;
- }
-
- LLVMBool split_debug_inlining = false;
- LLVMBool debug_info_for_profiling = false;
-
- m->debug_compile_unit = LLVMDIBuilderCreateCompileUnit(m->debug_builder, LLVMDWARFSourceLanguageC99,
- lb_get_llvm_metadata(m, init_file),
- producer, gb_string_length(producer),
- is_optimized, "", 0,
- 1, split_name, gb_string_length(split_name),
- LLVMDWARFEmissionFull,
- 0, split_debug_inlining,
- debug_info_for_profiling,
- "", 0, // sys_root
- "", 0 // SDK
- );
- GB_ASSERT(m->debug_compile_unit != nullptr);
+ for_array(i, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[i].value;
+ if (m->debug_builder) { // Debug Info
+ for_array(i, info->files.entries) {
+ AstFile *f = info->files.entries[i].value;
+ String fullpath = f->fullpath;
+ String filename = remove_directory_from_path(fullpath);
+ String directory = directory_from_path(fullpath);
+ LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
+ cast(char const *)filename.text, filename.len,
+ cast(char const *)directory.text, directory.len);
+ lb_set_llvm_metadata(m, f, res);
+ }
+
+ gbString producer = gb_string_make(heap_allocator(), "odin");
+ // producer = gb_string_append_fmt(producer, " version %.*s", LIT(ODIN_VERSION));
+ // #ifdef NIGHTLY
+ // producer = gb_string_appendc(producer, "-nightly");
+ // #endif
+ // #ifdef GIT_SHA
+ // producer = gb_string_append_fmt(producer, "-%s", GIT_SHA);
+ // #endif
+
+ gbString split_name = gb_string_make(heap_allocator(), "");
+
+ LLVMBool is_optimized = build_context.optimization_level > 0;
+ AstFile *init_file = m->info->init_package->files[0];
+ if (m->info->entry_point && m->info->entry_point->identifier && m->info->entry_point->identifier->file) {
+ init_file = m->info->entry_point->identifier->file;
+ }
+
+ LLVMBool split_debug_inlining = false;
+ LLVMBool debug_info_for_profiling = false;
+
+ m->debug_compile_unit = LLVMDIBuilderCreateCompileUnit(m->debug_builder, LLVMDWARFSourceLanguageC99,
+ lb_get_llvm_metadata(m, init_file),
+ producer, gb_string_length(producer),
+ is_optimized, "", 0,
+ 1, split_name, gb_string_length(split_name),
+ LLVMDWARFEmissionFull,
+ 0, split_debug_inlining,
+ debug_info_for_profiling,
+ "", 0, // sys_root
+ "", 0 // SDK
+ );
+ GB_ASSERT(m->debug_compile_unit != nullptr);
+ }
}
TIME_SECTION("LLVM Global Variables");
{
+ lbModule *m = default_module;
+
{ // Add type info data
isize max_type_info_count = info->minimum_dependency_type_info_set.entries.count+1;
// gb_printf_err("max_type_info_count: %td\n", max_type_info_count);
Type *t = alloc_type_array(t_type_info, max_type_info_count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), LB_TYPE_INFO_DATA_NAME);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
+ // LLVMSetLinkage(g, LLVMInternalLinkage);
lbValue value = {};
value.value = g;
@@ -14276,7 +14397,7 @@ void lb_generate_code(lbGenerator *gen) {
Type *t = alloc_type_array(t_type_info_ptr, count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
+ // LLVMSetLinkage(g, LLVMInternalLinkage);
lb_global_type_info_member_types = lb_addr({g, alloc_type_pointer(t)});
}
@@ -14285,7 +14406,7 @@ void lb_generate_code(lbGenerator *gen) {
Type *t = alloc_type_array(t_string, count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
+ // LLVMSetLinkage(g, LLVMInternalLinkage);
lb_global_type_info_member_names = lb_addr({g, alloc_type_pointer(t)});
}
{
@@ -14293,7 +14414,7 @@ void lb_generate_code(lbGenerator *gen) {
Type *t = alloc_type_array(t_uintptr, count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
+ // LLVMSetLinkage(g, LLVMInternalLinkage);
lb_global_type_info_member_offsets = lb_addr({g, alloc_type_pointer(t)});
}
@@ -14302,7 +14423,7 @@ void lb_generate_code(lbGenerator *gen) {
Type *t = alloc_type_array(t_bool, count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
+ // LLVMSetLinkage(g, LLVMInternalLinkage);
lb_global_type_info_member_usings = lb_addr({g, alloc_type_pointer(t)});
}
@@ -14311,7 +14432,7 @@ void lb_generate_code(lbGenerator *gen) {
Type *t = alloc_type_array(t_string, count);
LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
- LLVMSetLinkage(g, LLVMInternalLinkage);
+ // LLVMSetLinkage(g, LLVMInternalLinkage);
lb_global_type_info_member_tags = lb_addr({g, alloc_type_pointer(t)});
}
}
@@ -14373,8 +14494,9 @@ void lb_generate_code(lbGenerator *gen) {
bool is_foreign = e->Variable.is_foreign;
bool is_export = e->Variable.is_export;
- String name = lb_get_entity_name(m, e);
+ lbModule *m = &gen->default_module;
+ String name = lb_get_entity_name(m, e);
lbValue g = {};
g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
@@ -14409,7 +14531,7 @@ void lb_generate_code(lbGenerator *gen) {
}
if (e->flags & EntityFlag_Static) {
- LLVMSetLinkage(g.value, LLVMInternalLinkage);
+ // LLVMSetLinkage(g.value, LLVMInternalLinkage);
}
lbGlobalVariable var = {};
@@ -14439,6 +14561,7 @@ void lb_generate_code(lbGenerator *gen) {
lb_add_entity(m, e, g);
lb_add_member(m, name, g);
+
if (m->debug_builder) {
String global_name = e->token.string;
if (global_name.len != 0 && global_name != "_") {
@@ -14509,6 +14632,10 @@ void lb_generate_code(lbGenerator *gen) {
continue;
}
+ lbModule *m = &gen->default_module;
+ if (USE_SEPARTE_MODULES) {
+ m = lb_pkg_module(gen, e->pkg);
+ }
String mangled_name = lb_get_entity_name(m, e);
@@ -14526,108 +14653,70 @@ void lb_generate_code(lbGenerator *gen) {
}
- TIME_SECTION("LLVM Registry Initializtion");
-
- LLVMPassRegistryRef pass_registry = LLVMGetGlobalPassRegistry();
-
- LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
- LLVMPassManagerRef function_pass_manager_minimal = LLVMCreateFunctionPassManagerForModule(m->mod);
- LLVMPassManagerRef function_pass_manager_size = LLVMCreateFunctionPassManagerForModule(m->mod);
- LLVMPassManagerRef function_pass_manager_speed = LLVMCreateFunctionPassManagerForModule(m->mod);
- defer (LLVMDisposePassManager(default_function_pass_manager));
- defer (LLVMDisposePassManager(function_pass_manager_minimal));
- defer (LLVMDisposePassManager(function_pass_manager_size));
- defer (LLVMDisposePassManager(function_pass_manager_speed));
-
- LLVMInitializeFunctionPassManager(default_function_pass_manager);
- LLVMInitializeFunctionPassManager(function_pass_manager_minimal);
- LLVMInitializeFunctionPassManager(function_pass_manager_size);
- LLVMInitializeFunctionPassManager(function_pass_manager_speed);
-
- lb_populate_function_pass_manager(default_function_pass_manager, false, build_context.optimization_level);
- lb_populate_function_pass_manager_specific(function_pass_manager_minimal, 0);
- lb_populate_function_pass_manager_specific(function_pass_manager_size, 1);
- lb_populate_function_pass_manager_specific(function_pass_manager_speed, 2);
-
- LLVMFinalizeFunctionPassManager(default_function_pass_manager);
- LLVMFinalizeFunctionPassManager(function_pass_manager_minimal);
- LLVMFinalizeFunctionPassManager(function_pass_manager_size);
- LLVMFinalizeFunctionPassManager(function_pass_manager_speed);
-
-
- LLVMPassManagerRef default_function_pass_manager_without_memcpy = LLVMCreateFunctionPassManagerForModule(m->mod);
- defer (LLVMDisposePassManager(default_function_pass_manager_without_memcpy));
- LLVMInitializeFunctionPassManager(default_function_pass_manager_without_memcpy);
- lb_populate_function_pass_manager(default_function_pass_manager_without_memcpy, true, build_context.optimization_level);
- LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy);
-
TIME_SECTION("LLVM Runtime Type Information Creation");
- lbProcedure *startup_type_info = lb_create_startup_type_info(m);
+ lbProcedure *startup_type_info = lb_create_startup_type_info(default_module);
TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)");
- lbProcedure *startup_runtime = lb_create_startup_runtime(m, startup_type_info, global_variables);
-
+ lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables);
- String filepath_ll = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".ll"));
TIME_SECTION("LLVM Procedure Generation");
- for_array(i, m->procedures_to_generate) {
- lbProcedure *p = m->procedures_to_generate[i];
- if (p->is_done) {
- continue;
- }
- if (p->body != nullptr) { // Build Procedure
- m->curr_procedure = p;
- lb_begin_procedure_body(p);
- lb_build_stmt(p, p->body);
- lb_end_procedure_body(p);
- p->is_done = true;
- m->curr_procedure = nullptr;
- }
- lb_end_procedure(p);
-
- // Add Flags
- if (p->body != nullptr) {
- if (p->name == "memcpy" || p->name == "memmove" ||
- p->name == "runtime.mem_copy" || p->name == "mem_copy_non_overlapping" ||
- string_starts_with(p->name, str_lit("llvm.memcpy")) ||
- string_starts_with(p->name, str_lit("llvm.memmove"))) {
- p->flags |= lbProcedureFlag_WithoutMemcpyPass;
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ for_array(i, m->procedures_to_generate) {
+ lbProcedure *p = m->procedures_to_generate[i];
+ if (p->is_done) {
+ continue;
}
- }
-
- if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
- gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %.*s\n", LIT(p->name));
- LLVMDumpValue(p->value);
- gb_printf_err("\n\n\n\n");
- if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
- gb_printf_err("LLVM Error: %s\n", llvm_error);
+ if (p->body != nullptr) { // Build Procedure
+ m->curr_procedure = p;
+ lb_begin_procedure_body(p);
+ lb_build_stmt(p, p->body);
+ lb_end_procedure_body(p);
+ p->is_done = true;
+ m->curr_procedure = nullptr;
+ }
+ lb_end_procedure(p);
+
+ // Add Flags
+ if (p->body != nullptr) {
+ if (p->name == "memcpy" || p->name == "memmove" ||
+ p->name == "runtime.mem_copy" || p->name == "mem_copy_non_overlapping" ||
+ string_starts_with(p->name, str_lit("llvm.memcpy")) ||
+ string_starts_with(p->name, str_lit("llvm.memmove"))) {
+ p->flags |= lbProcedureFlag_WithoutMemcpyPass;
+ }
+ }
+
+ if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
+ gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %.*s\n", LIT(p->name));
+ LLVMDumpValue(p->value);
+ gb_printf_err("\n\n\n\n");
+ 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);
+ }
+ LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
+ gb_exit(1);
}
- LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
- gb_exit(1);
}
}
if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) {
TIME_SECTION("LLVM main");
- lb_create_main_procedure(m, startup_runtime);
+ lb_create_main_procedure(default_module, startup_runtime);
}
-
- if (m->debug_builder != nullptr) {
- TIME_SECTION("LLVM Debug Info Complete Types");
- lb_debug_complete_types(m);
-
-
- TIME_SECTION("LLVM Print Module to File");
- if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
- gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
- return;
+ if (build_context.ODIN_DEBUG) {
+ TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ if (m->debug_builder != nullptr) {
+ lb_debug_complete_types(m);
+ LLVMDIBuilderFinalize(m->debug_builder);
+ }
}
- TIME_SECTION("LLVM Debug Info Builder Finalize");
- LLVMDIBuilderFinalize(m->debug_builder);
}
@@ -14635,6 +14724,38 @@ void lb_generate_code(lbGenerator *gen) {
for_array(i, gen->modules.entries) {
lbModule *m = gen->modules.entries[i].value;
+ LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
+ LLVMPassManagerRef function_pass_manager_minimal = LLVMCreateFunctionPassManagerForModule(m->mod);
+ LLVMPassManagerRef function_pass_manager_size = LLVMCreateFunctionPassManagerForModule(m->mod);
+ LLVMPassManagerRef function_pass_manager_speed = LLVMCreateFunctionPassManagerForModule(m->mod);
+ defer (LLVMDisposePassManager(default_function_pass_manager));
+ defer (LLVMDisposePassManager(function_pass_manager_minimal));
+ defer (LLVMDisposePassManager(function_pass_manager_size));
+ defer (LLVMDisposePassManager(function_pass_manager_speed));
+
+ LLVMInitializeFunctionPassManager(default_function_pass_manager);
+ LLVMInitializeFunctionPassManager(function_pass_manager_minimal);
+ LLVMInitializeFunctionPassManager(function_pass_manager_size);
+ LLVMInitializeFunctionPassManager(function_pass_manager_speed);
+
+ lb_populate_function_pass_manager(default_function_pass_manager, false, build_context.optimization_level);
+ lb_populate_function_pass_manager_specific(function_pass_manager_minimal, 0);
+ lb_populate_function_pass_manager_specific(function_pass_manager_size, 1);
+ lb_populate_function_pass_manager_specific(function_pass_manager_speed, 2);
+
+ LLVMFinalizeFunctionPassManager(default_function_pass_manager);
+ LLVMFinalizeFunctionPassManager(function_pass_manager_minimal);
+ LLVMFinalizeFunctionPassManager(function_pass_manager_size);
+ LLVMFinalizeFunctionPassManager(function_pass_manager_speed);
+
+
+ LLVMPassManagerRef default_function_pass_manager_without_memcpy = LLVMCreateFunctionPassManagerForModule(m->mod);
+ defer (LLVMDisposePassManager(default_function_pass_manager_without_memcpy));
+ LLVMInitializeFunctionPassManager(default_function_pass_manager_without_memcpy);
+ lb_populate_function_pass_manager(default_function_pass_manager_without_memcpy, true, build_context.optimization_level);
+ LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy);
+
+
for_array(i, m->procedures_to_generate) {
lbProcedure *p = m->procedures_to_generate[i];
if (p->body != nullptr) { // Build Procedure
@@ -14688,49 +14809,41 @@ void lb_generate_code(lbGenerator *gen) {
llvm_error = nullptr;
defer (LLVMDisposeMessage(llvm_error));
- String filepath_obj = {};
LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
-
if (build_context.build_mode == BuildMode_Assembly) {
- filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".S"));
code_gen_file_type = LLVMAssemblyFile;
- } else {
- switch (build_context.metrics.os) {
- case TargetOs_windows:
- filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".obj"));
- break;
- case TargetOs_darwin:
- case TargetOs_linux:
- case TargetOs_essence:
- filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".o"));
- break;
- case TargetOs_js:
- filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".wasm-obj"));
- break;
- }
}
- if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
- gb_printf_err("LLVM Error:\n%s\n", llvm_error);
- if (build_context.keep_temp_files) {
- TIME_SECTION("LLVM Print Module to File");
- if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
- gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
- return;
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
+ gb_printf_err("LLVM Error:\n%s\n", llvm_error);
+ if (build_context.keep_temp_files) {
+ TIME_SECTION("LLVM Print Module to File");
+ 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);
+ return;
+ }
}
+ gb_exit(1);
+ return;
}
- gb_exit(1);
- return;
}
llvm_error = nullptr;
if (build_context.keep_temp_files ||
build_context.build_mode == BuildMode_LLVM_IR) {
TIME_SECTION("LLVM Print Module to File");
- if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
- gb_printf_err("LLVM Error: %s\n", llvm_error);
- gb_exit(1);
- return;
+
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ 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);
+ return;
+ }
}
if (build_context.build_mode == BuildMode_LLVM_IR) {
gb_exit(0);
@@ -14740,18 +14853,25 @@ void lb_generate_code(lbGenerator *gen) {
TIME_SECTION("LLVM Object Generation");
- if (LLVMTargetMachineEmitToFile(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);
- return;
- }
+ for_array(j, gen->modules.entries) {
+ lbModule *m = gen->modules.entries[j].value;
+ String filepath_obj = lb_filepath_obj_for_module(m);
- array_add(&gen->output_object_paths, filepath_obj);
+ if (LLVMTargetMachineEmitToFile(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);
+ return;
+ }
- for_array(i, m->info->required_foreign_imports_through_force) {
- Entity *e = m->info->required_foreign_imports_through_force[i];
- lb_add_foreign_library_path(m, e);
+ array_add(&gen->output_object_paths, filepath_obj);
+ for_array(i, m->info->required_foreign_imports_through_force) {
+ Entity *e = m->info->required_foreign_imports_through_force[i];
+ lb_add_foreign_library_path(m, e);
+ }
}
+
+
+
#undef TIME_SECTION
}
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 392c15ea4..8a4f06117 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -85,6 +85,8 @@ struct lbModule {
LLVMModuleRef mod;
LLVMContextRef ctx;
+ struct lbGenerator *gen;
+
CheckerInfo *info;
AstPackage *pkg; // associated
@@ -108,8 +110,6 @@ struct lbModule {
Map<lbProcedure *> equal_procs; // Key: Type *
Map<lbProcedure *> hasher_procs; // Key: Type *
- u32 global_array_index;
- u32 global_generated_index;
u32 nested_type_name_guid;
Array<lbProcedure *> procedures_to_generate;
@@ -131,7 +131,11 @@ struct lbGenerator {
String output_base;
String output_name;
Map<lbModule *> modules; // Key: AstPackage *
+ Map<lbModule *> modules_through_ctx; // Key: LLVMContextRef *
lbModule default_module;
+
+ gbAtomic32 global_array_index;
+ gbAtomic32 global_generated_index;
};
@@ -271,7 +275,7 @@ String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);
void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value);
void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name);
-lbProcedure *lb_create_procedure(lbModule *module, Entity *entity);
+lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false);
void lb_end_procedure(lbProcedure *p);
@@ -383,6 +387,7 @@ lbValue lb_gen_map_hash(lbProcedure *p, lbValue key, Type *key_type);
void lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbAddr addr, Type *map_type, lbValue map_key, lbValue map_value, Ast *node);
+
void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
diff --git a/src/main.cpp b/src/main.cpp
index 48fb4dcc3..530492cbb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1542,12 +1542,19 @@ void show_timings(Checker *c, Timings *t) {
}
}
-void remove_temp_files(String output_base) {
+void remove_temp_files(lbGenerator *gen) {
if (build_context.keep_temp_files) return;
+ String output_base = gen->output_base;
+
auto data = array_make<u8>(heap_allocator(), output_base.len + 30);
defer (array_free(&data));
+ for_array(i, gen->output_object_paths) {
+ String path = gen->output_object_paths[i];
+ gb_file_remove(cast(char const *)path.text);
+ }
+
isize n = output_base.len;
gb_memmove(data.data, output_base.text, n);
#define EXT_REMOVE(s) do { \
@@ -2183,7 +2190,7 @@ int main(int arg_count, char const **arg_ptr) {
show_timings(&checker, timings);
}
- remove_temp_files(gen.output_base);
+ remove_temp_files(&gen);
if (run_output) {
#if defined(GB_SYSTEM_WINDOWS)