Browse Source

Make linkage weak in certain places

gingerBill 1 year ago
parent
commit
7d643bcae3
2 changed files with 49 additions and 49 deletions
  1. 10 5
      src/llvm_backend.cpp
  2. 39 44
      src/llvm_backend_general.cpp

+ 10 - 5
src/llvm_backend.cpp

@@ -144,11 +144,14 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) {
 		LLVMValueRef other_global = nullptr;
 		if (ec.e->kind == Entity_Variable) {
 			other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname);
+			if (other_global) {
+				LLVMSetLinkage(other_global, LLVMWeakAnyLinkage);
+			}
 		} else if (ec.e->kind == Entity_Procedure) {
 			other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname);
-		}
-		if (other_global) {
-			LLVMSetLinkage(other_global, LLVMExternalLinkage);
+			if (other_global) {
+				LLVMSetLinkage(other_global, LLVMWeakAnyLinkage);
+			}
 		}
 	}
 }
@@ -1437,7 +1440,9 @@ gb_internal bool lb_is_module_empty(lbModule *m) {
 	}
 
 	for (auto g = LLVMGetFirstGlobal(m->mod); g != nullptr; g = LLVMGetNextGlobal(g)) {
-		if (LLVMGetLinkage(g) == LLVMExternalLinkage) {
+		LLVMLinkage linkage = LLVMGetLinkage(g);
+		if (linkage == LLVMExternalLinkage ||
+		    linkage == LLVMWeakAnyLinkage) {
 			continue;
 		}
 		if (!LLVMIsExternallyInitialized(g)) {
@@ -3266,7 +3271,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
 			LLVMSetLinkage(g.value, LLVMDLLExportLinkage);
 			LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass);
 		} else if (!is_foreign) {
-			LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage);
+			LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage);
 		}
 		lb_set_linkage_from_entity_flags(m, g.value, e->flags);
 		

+ 39 - 44
src/llvm_backend_general.cpp

@@ -3043,61 +3043,56 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
 		return *found;
 	}
 
-	lbValue g = {};
-	String name = {};
-
-	if (!USE_SEPARATE_MODULES) {
-		goto failed;
-	}
-	lbModule *other_module = lb_module_of_entity(m->gen, e);
+	if (USE_SEPARATE_MODULES) {
+		lbModule *other_module = lb_module_of_entity(m->gen, e);
 
-	bool is_external = other_module != m;
-	if (!is_external) {
-		if (e->code_gen_module != nullptr) {
-			other_module = e->code_gen_module;
-		} else {
-			other_module = &m->gen->default_module;
+		bool is_external = other_module != m;
+		if (!is_external) {
+			if (e->code_gen_module != nullptr) {
+				other_module = e->code_gen_module;
+			} else {
+				other_module = &m->gen->default_module;
+			}
+			is_external = other_module != m;
 		}
-		is_external = other_module != m;
-	}
 
-	if (!is_external) {
-		goto failed;
-	}
-	name = lb_get_entity_name(other_module, e);
+		if (is_external) {
+			String name = lb_get_entity_name(other_module, e);
 
-	g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
-	g.type = alloc_type_pointer(e->type);
-	lb_add_entity(m, e, g);
-	lb_add_member(m, name, g);
+			lbValue g = {};
+			g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
+			g.type = alloc_type_pointer(e->type);
+			lb_add_entity(m, e, g);
+			lb_add_member(m, name, g);
 
-	LLVMSetLinkage(g.value, LLVMExternalLinkage);
+			LLVMSetLinkage(g.value, LLVMExternalLinkage);
+
+			lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name);
 
-	lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name);
+			if (e->Variable.thread_local_model != "") {
+				LLVMSetThreadLocal(g.value, true);
+
+				String m = e->Variable.thread_local_model;
+				LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
+				if (m == "default") {
+					mode = LLVMGeneralDynamicTLSModel;
+				} else if (m == "localdynamic") {
+					mode = LLVMLocalDynamicTLSModel;
+				} else if (m == "initialexec") {
+					mode = LLVMInitialExecTLSModel;
+				} else if (m == "localexec") {
+					mode = LLVMLocalExecTLSModel;
+				} else {
+					GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
+				}
+				LLVMSetThreadLocalMode(g.value, mode);
+			}
 
-	if (e->Variable.thread_local_model != "") {
-		LLVMSetThreadLocal(g.value, true);
 
-		String m = e->Variable.thread_local_model;
-		LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
-		if (m == "default") {
-			mode = LLVMGeneralDynamicTLSModel;
-		} else if (m == "localdynamic") {
-			mode = LLVMLocalDynamicTLSModel;
-		} else if (m == "initialexec") {
-			mode = LLVMInitialExecTLSModel;
-		} else if (m == "localexec") {
-			mode = LLVMLocalExecTLSModel;
-		} else {
-			GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
+			return g;
 		}
-		LLVMSetThreadLocalMode(g.value, mode);
 	}
 
-
-	return g;
-
-failed:;
 	GB_PANIC("\n\tError in: %s, missing value '%.*s' in module %s\n",
 	         token_pos_to_string(e->token.pos), LIT(e->token.string), m->module_name);
 	return {};