aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-07-15 11:49:07 +0100
committergingerBill <bill@gingerbill.org>2024-07-15 11:49:07 +0100
commitc5decd3eaecf393e1bf216b4d864fc9cfc5db0c2 (patch)
tree964ebce0f055d1a0c984290f7388adfbfddd3e8a
parent664a71454bd2c58ab6f06f8de6d7d34c3eb397d7 (diff)
Fix possible race and correct linkage _after_ generation
-rw-r--r--src/llvm_backend.cpp44
-rw-r--r--src/llvm_backend.hpp8
-rw-r--r--src/llvm_backend_general.cpp4
-rw-r--r--src/queue.cpp2
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_);