Browse Source

Fix possible race and correct linkage _after_ generation

gingerBill 1 year ago
parent
commit
c5decd3eae
4 changed files with 40 additions and 18 deletions
  1. 28 16
      src/llvm_backend.cpp
  2. 8 0
      src/llvm_backend.hpp
  3. 3 1
      src/llvm_backend_general.cpp
  4. 1 1
      src/queue.cpp

+ 28 - 16
src/llvm_backend.cpp

@@ -1,13 +1,11 @@
 #define MULTITHREAD_OBJECT_GENERATION 1
 #define MULTITHREAD_OBJECT_GENERATION 1
-
-#ifndef USE_SEPARATE_MODULES
-#define USE_SEPARATE_MODULES build_context.use_separate_modules
-#endif
-
 #ifndef MULTITHREAD_OBJECT_GENERATION
 #ifndef MULTITHREAD_OBJECT_GENERATION
 #define MULTITHREAD_OBJECT_GENERATION 0
 #define MULTITHREAD_OBJECT_GENERATION 0
 #endif
 #endif
 
 
+#ifndef USE_SEPARATE_MODULES
+#define USE_SEPARATE_MODULES build_context.use_separate_modules
+#endif
 
 
 #ifndef LLVM_IGNORE_VERIFICATION
 #ifndef LLVM_IGNORE_VERIFICATION
 #define LLVM_IGNORE_VERIFICATION 0
 #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) {
 	if (other_module == nullptr) {
 		return;
 		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) {
 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");
 	TIME_SECTION("LLVM Add Foreign Library Paths");
 	lb_add_foreign_library_paths(gen);
 	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) {
 	for (auto const &entry: gen->modules) {

+ 8 - 0
src/llvm_backend.hpp

@@ -200,6 +200,12 @@ struct lbModule {
 	LLVMPassManagerRef function_pass_managers[lbFunctionPassManager_COUNT];
 	LLVMPassManagerRef function_pass_managers[lbFunctionPassManager_COUNT];
 };
 };
 
 
+struct lbEntityCorrection {
+	lbModule *  other_module;
+	Entity *    e;
+	char const *cname;
+};
+
 struct lbGenerator : LinkerData {
 struct lbGenerator : LinkerData {
 	CheckerInfo *info;
 	CheckerInfo *info;
 
 
@@ -218,6 +224,8 @@ struct lbGenerator : LinkerData {
 	lbProcedure *startup_runtime;
 	lbProcedure *startup_runtime;
 	lbProcedure *cleanup_runtime;
 	lbProcedure *cleanup_runtime;
 	lbProcedure *objc_names;
 	lbProcedure *objc_names;
+
+	MPSCQueue<lbEntityCorrection> entities_to_correct_linkage;
 };
 };
 
 
 
 

+ 3 - 1
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->hasher_procs);
 	map_init(&m->map_get_procs);
 	map_init(&m->map_get_procs);
 	map_init(&m->map_set_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);
 		array_init(&m->procedures_to_generate, a, 0, 1<<10);
 		map_init(&m->procedure_values,               1<<11);
 		map_init(&m->procedure_values,               1<<11);
 	} else {
 	} else {
@@ -151,6 +151,8 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) {
 		map_set(&gen->modules_through_ctx, ctx, m);
 		map_set(&gen->modules_through_ctx, ctx, m);
 	}
 	}
 
 
+	mpsc_init(&gen->entities_to_correct_linkage, heap_allocator());
+
 	return true;
 	return true;
 }
 }
 
 

+ 1 - 1
src/queue.cpp

@@ -16,7 +16,7 @@ struct MPSCQueue {
 	std::atomic<isize> count;
 	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 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 isize mpsc_enqueue(MPSCQueue<T> *q, T const &value);
 template <typename T> gb_internal bool  mpsc_dequeue(MPSCQueue<T> *q, T *value_);
 template <typename T> gb_internal bool  mpsc_dequeue(MPSCQueue<T> *q, T *value_);