diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ae46186ed..d975ac600 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1,13 +1,11 @@ #define MULTITHREAD_OBJECT_GENERATION 1 - -#ifndef USE_SEPARATE_MODULES -#define USE_SEPARATE_MODULES build_context.use_separate_modules -#endif - #ifndef MULTITHREAD_OBJECT_GENERATION #define MULTITHREAD_OBJECT_GENERATION 0 #endif +#ifndef USE_SEPARATE_MODULES +#define USE_SEPARATE_MODULES build_context.use_separate_modules +#endif #ifndef LLVM_IGNORE_VERIFICATION #define LLVM_IGNORE_VERIFICATION 0 @@ -137,17 +135,18 @@ gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *ot if (other_module == nullptr) { return; } - char const *cname = alloc_cstring(temporary_allocator(), name); + char const *cname = alloc_cstring(permanent_allocator(), name); + mpsc_enqueue(&other_module->gen->entities_to_correct_linkage, lbEntityCorrection{other_module, e, cname}); - LLVMValueRef other_global = nullptr; - if (e->kind == Entity_Variable) { - other_global = LLVMGetNamedGlobal(other_module->mod, cname); - } else if (e->kind == Entity_Procedure) { - other_global = LLVMGetNamedFunction(other_module->mod, cname); - } - if (other_global) { - LLVMSetLinkage(other_global, LLVMExternalLinkage); - } + // LLVMValueRef other_global = nullptr; + // if (e->kind == Entity_Variable) { + // other_global = LLVMGetNamedGlobal(other_module->mod, cname); + // } else if (e->kind == Entity_Procedure) { + // other_global = LLVMGetNamedFunction(other_module->mod, cname); + // } + // if (other_global) { + // LLVMSetLinkage(other_global, LLVMExternalLinkage); + // } } gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) { @@ -3431,6 +3430,19 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Add Foreign Library Paths"); lb_add_foreign_library_paths(gen); + TIME_SECTION("LLVM Correct Entity Linkage"); + for (lbEntityCorrection ec = {}; mpsc_dequeue(&gen->entities_to_correct_linkage, &ec); /**/) { + LLVMValueRef other_global = nullptr; + if (ec.e->kind == Entity_Variable) { + other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); + } else if (ec.e->kind == Entity_Procedure) { + other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); + } + if (other_global) { + LLVMSetLinkage(other_global, LLVMExternalLinkage); + } + } + //////////////////////////////////////////// for (auto const &entry: gen->modules) { diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index deb05528f..c4f2bd884 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -200,6 +200,12 @@ struct lbModule { LLVMPassManagerRef function_pass_managers[lbFunctionPassManager_COUNT]; }; +struct lbEntityCorrection { + lbModule * other_module; + Entity * e; + char const *cname; +}; + struct lbGenerator : LinkerData { CheckerInfo *info; @@ -218,6 +224,8 @@ struct lbGenerator : LinkerData { lbProcedure *startup_runtime; lbProcedure *cleanup_runtime; lbProcedure *objc_names; + + MPSCQueue entities_to_correct_linkage; }; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index f5595b70e..ba8b13bd8 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -71,7 +71,7 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) { map_init(&m->hasher_procs); map_init(&m->map_get_procs); map_init(&m->map_set_procs); - if (build_context.use_separate_modules) { + if (USE_SEPARATE_MODULES) { array_init(&m->procedures_to_generate, a, 0, 1<<10); map_init(&m->procedure_values, 1<<11); } else { @@ -151,6 +151,8 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) { map_set(&gen->modules_through_ctx, ctx, m); } + mpsc_init(&gen->entities_to_correct_linkage, heap_allocator()); + return true; } diff --git a/src/queue.cpp b/src/queue.cpp index 2ad9cb29f..dee9ad1f8 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -16,7 +16,7 @@ struct MPSCQueue { std::atomic count; }; -template gb_internal void mpsc_init (MPSCQueue *q); +template gb_internal void mpsc_init (MPSCQueue *q, gbAllocator const &allocator); template gb_internal void mpsc_destroy(MPSCQueue *q); template gb_internal isize mpsc_enqueue(MPSCQueue *q, T const &value); template gb_internal bool mpsc_dequeue(MPSCQueue *q, T *value_);