aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-05-03 19:39:36 +0100
committergingerBill <bill@gingerbill.org>2021-05-03 19:39:36 +0100
commitdfe1dedeb1f948bebd6121e3cc31fcd4562ab0cd (patch)
treee5b6467beb36526075e58dfb60c22697cf9d8133 /src
parentd027a5f1a470233a0307bcf3c7c4fe0b6494cd87 (diff)
Experimental support for `-use-separate-modules`
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp4
-rw-r--r--src/llvm_backend.cpp56
-rw-r--r--src/llvm_backend.hpp1
-rw-r--r--src/main.cpp42
4 files changed, 66 insertions, 37 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 77046cf6d..09d860cfc 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -809,10 +809,6 @@ 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 9649af6c9..2acbbcff8 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -2721,6 +2721,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
if (ignore_body) {
p->body = nullptr;
+ LLVMSetLinkage(p->value, LLVMExternalLinkage);
}
@@ -5762,7 +5763,7 @@ lbValue lb_find_value_from_entity(lbModule *m, Entity *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);
+ LLVMSetLinkage(g.value, LLVMExternalLinkage);
lb_add_entity(m, e, g);
lb_add_member(m, name, g);
@@ -11179,15 +11180,19 @@ lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
return lb_addr_load(p, lb_build_addr(p, expr));
}
+ if (e->kind == Entity_Procedure) {
+ return lb_find_procedure_value_from_entity(m, e);
+ }
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);
+ LLVMSetLinkage(g.value, LLVMExternalLinkage);
lb_add_entity(m, e, g);
lb_add_member(m, name, g);
@@ -12995,13 +13000,15 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
void lb_init_module(lbModule *m, Checker *c) {
m->info = &c->info;
- gbString module_name = nullptr;
+ gbString module_name = gb_string_make(heap_allocator(), "odin_package-");
if (m->pkg) {
- module_name = gb_string_make(heap_allocator(), "odin_package-");
module_name = gb_string_append_length(module_name, m->pkg->name.text, m->pkg->name.len);
+ } else if (USE_SEPARTE_MODULES) {
+ module_name = gb_string_appendc(module_name, "builtin");
+ } else {
+ module_name = "odin_package";
}
-
m->ctx = LLVMContextCreate();
m->mod = LLVMModuleCreateWithNameInContext(module_name ? module_name : "odin_package", m->ctx);
// m->debug_builder = nullptr;
@@ -13089,6 +13096,7 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
}
gbAllocator ha = heap_allocator();
array_init(&gen->output_object_paths, ha);
+ array_init(&gen->output_temp_paths, ha);
gen->output_base = path_to_full_path(ha, gen->output_base);
@@ -14110,8 +14118,20 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
lb_fill_slice(p, args, argv, argc);
}
+ {
+ auto args = array_make<lbValue>(permanent_allocator(), 1);
+ args[0] = lb_const_string(p->module, str_lit("Here0\n"));
+ lb_emit_runtime_call(p, "print_string", args);
+ }
+
LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_runtime->type)), startup_runtime->value, nullptr, 0, "");
+ {
+ auto args = array_make<lbValue>(permanent_allocator(), 1);
+ args[0] = lb_const_string(p->module, str_lit("Here1\n"));
+ lb_emit_runtime_call(p, "print_string", args);
+ }
+
if (build_context.command_kind == Command_test) {
Type *t_Internal_Test = find_type_in_pkg(m->info, str_lit("testing"), str_lit("Internal_Test"));
Type *array_type = alloc_type_array(t_Internal_Test, m->info->testing_procedures.count);
@@ -14189,6 +14209,8 @@ 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);
+ } else if (USE_SEPARTE_MODULES) {
+ path = concatenate_strings(permanent_allocator(), path, STR_LIT("-builtin"));
}
path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll"));
@@ -14522,6 +14544,7 @@ void lb_generate_code(lbGenerator *gen) {
LLVMSetThreadLocalMode(g.value, mode);
}
if (is_foreign) {
+ LLVMSetLinkage(g.value, LLVMExternalLinkage);
LLVMSetExternallyInitialized(g.value, true);
lb_add_foreign_library_path(m, e->Variable.foreign_library);
} else {
@@ -14840,12 +14863,20 @@ void lb_generate_code(lbGenerator *gen) {
for_array(j, gen->modules.entries) {
lbModule *m = gen->modules.entries[j].value;
+
+ if (LLVMGetFirstFunction(m->mod) == nullptr &&
+ LLVMGetFirstGlobal(m->mod) == nullptr) {
+ continue;
+ }
+
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;
}
+ array_add(&gen->output_temp_paths, filepath_ll);
+
}
if (build_context.build_mode == BuildMode_LLVM_IR) {
gb_exit(0);
@@ -14857,6 +14888,16 @@ void lb_generate_code(lbGenerator *gen) {
for_array(j, gen->modules.entries) {
lbModule *m = gen->modules.entries[j].value;
+ 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);
+ }
+
+ if (LLVMGetFirstFunction(m->mod) == nullptr &&
+ LLVMGetFirstGlobal(m->mod) == nullptr) {
+ continue;
+ }
+
String filepath_obj = lb_filepath_obj_for_module(m);
if (LLVMTargetMachineEmitToFile(target_machine, m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
@@ -14866,10 +14907,7 @@ void lb_generate_code(lbGenerator *gen) {
}
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);
- }
+
}
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 8a4f06117..4338edbc7 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -128,6 +128,7 @@ struct lbGenerator {
CheckerInfo *info;
Array<String> output_object_paths;
+ Array<String> output_temp_paths;
String output_base;
String output_name;
Map<lbModule *> modules; // Key: AstPackage *
diff --git a/src/main.cpp b/src/main.cpp
index 530492cbb..19b22ef4f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -596,6 +596,7 @@ enum BuildFlagKind {
BuildFlag_NoCRT,
BuildFlag_NoEntryPoint,
BuildFlag_UseLLD,
+ BuildFlag_UseSeparateModules,
BuildFlag_Vet,
BuildFlag_VetExtra,
BuildFlag_UseLLVMApi,
@@ -716,6 +717,7 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test);
add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build);
+ add_flag(&build_flags, BuildFlag_UseSeparateModules,str_lit("use-separate-modules"),BuildFlagParam_None, Command__does_build);
add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check);
add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build);
@@ -1195,6 +1197,10 @@ bool parse_build_flags(Array<String> args) {
build_context.use_lld = true;
break;
+ case BuildFlag_UseSeparateModules:
+ build_context.use_separate_modules = true;
+ break;
+
case BuildFlag_Vet:
build_context.vet = true;
break;
@@ -1545,35 +1551,17 @@ void show_timings(Checker *c, Timings *t) {
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];
+ for_array(i, gen->output_temp_paths) {
+ String path = gen->output_temp_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 { \
- gb_memmove(data.data+n, s, gb_size_of(s)); \
- gb_file_remove(cast(char const *)data.data); \
- } while (0)
- EXT_REMOVE(".ll");
- EXT_REMOVE(".bc");
- EXT_REMOVE("_memcpy_pass.bc");
if (build_context.build_mode != BuildMode_Object && !build_context.keep_object_files) {
- #if defined(GB_SYSTEM_WINDOWS)
- EXT_REMOVE(".obj");
- EXT_REMOVE(".res");
- #else
- EXT_REMOVE(".o");
- #endif
+ for_array(i, gen->output_object_paths) {
+ String path = gen->output_object_paths[i];
+ gb_file_remove(cast(char const *)path.text);
+ }
}
-
-#undef EXT_REMOVE
}
@@ -1734,6 +1722,12 @@ void print_show_help(String const arg0, String const &command) {
print_usage_line(1, "-use-lld");
print_usage_line(2, "Use the LLD linker rather than the default");
print_usage_line(0, "");
+
+ print_usage_line(1, "-use-separate-modules");
+ print_usage_line(2, "The backend generates multiple build units which are then linked together");
+ print_usage_line(2, "Normally, a single build unit is generated for a standard project");
+ print_usage_line(0, "");
+
}
if (check) {