diff options
| author | gingerBill <bill@gingerbill.org> | 2024-07-15 11:49:07 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-07-15 11:49:07 +0100 |
| commit | c5decd3eaecf393e1bf216b4d864fc9cfc5db0c2 (patch) | |
| tree | 964ebce0f055d1a0c984290f7388adfbfddd3e8a /src | |
| parent | 664a71454bd2c58ab6f06f8de6d7d34c3eb397d7 (diff) | |
Fix possible race and correct linkage _after_ generation
Diffstat (limited to 'src')
| -rw-r--r-- | src/llvm_backend.cpp | 44 | ||||
| -rw-r--r-- | src/llvm_backend.hpp | 8 | ||||
| -rw-r--r-- | src/llvm_backend_general.cpp | 4 | ||||
| -rw-r--r-- | src/queue.cpp | 2 |
4 files changed, 40 insertions, 18 deletions
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); - - 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); - } + 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); + // } } 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<lbEntityCorrection> 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<isize> count; }; -template <typename T> gb_internal void mpsc_init (MPSCQueue<T> *q); +template <typename T> gb_internal void mpsc_init (MPSCQueue<T> *q, gbAllocator const &allocator); template <typename T> gb_internal void mpsc_destroy(MPSCQueue<T> *q); template <typename T> gb_internal isize mpsc_enqueue(MPSCQueue<T> *q, T const &value); template <typename T> gb_internal bool mpsc_dequeue(MPSCQueue<T> *q, T *value_); |