Browse Source

Fix global variables being "missing" with `-use-separate-modules`

gingerBill 1 year ago
parent
commit
549311fac9
4 changed files with 73 additions and 67 deletions
  1. 16 21
      src/llvm_backend.cpp
  2. 2 1
      src/llvm_backend.hpp
  3. 1 0
      src/llvm_backend_debug.cpp
  4. 54 45
      src/llvm_backend_general.cpp

+ 16 - 21
src/llvm_backend.cpp

@@ -137,18 +137,23 @@ gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *ot
 	}
 	}
 	char const *cname = alloc_cstring(permanent_allocator(), name);
 	char const *cname = alloc_cstring(permanent_allocator(), name);
 	mpsc_enqueue(&other_module->gen->entities_to_correct_linkage, lbEntityCorrection{other_module, e, cname});
 	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_correct_entity_linkage(lbGenerator *gen) {
+	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);
+		}
+	}
 }
 }
 
 
+
 gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
 gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
 	TEMPORARY_ALLOCATOR_GUARD();
 	TEMPORARY_ALLOCATOR_GUARD();
 
 
@@ -1386,6 +1391,7 @@ gb_internal void lb_create_global_procedures_and_types(lbGenerator *gen, Checker
 		if (USE_SEPARATE_MODULES) {
 		if (USE_SEPARATE_MODULES) {
 			m = lb_module_of_entity(gen, e);
 			m = lb_module_of_entity(gen, e);
 		}
 		}
+		GB_ASSERT(m != nullptr);
 
 
 		if (e->kind == Entity_Procedure) {
 		if (e->kind == Entity_Procedure) {
 			array_add(&m->global_procedures_to_create, e);
 			array_add(&m->global_procedures_to_create, e);
@@ -3431,18 +3437,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
 	lb_add_foreign_library_paths(gen);
 	lb_add_foreign_library_paths(gen);
 
 
 	TIME_SECTION("LLVM Correct Entity Linkage");
 	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);
-		}
-	}
-
+	lb_correct_entity_linkage(gen);
 
 
 	////////////////////////////////////////////
 	////////////////////////////////////////////
 	for (auto const &entry: gen->modules) {
 	for (auto const &entry: gen->modules) {

+ 2 - 1
src/llvm_backend.hpp

@@ -147,6 +147,7 @@ struct lbModule {
 	CheckerInfo *info;
 	CheckerInfo *info;
 	AstPackage *pkg; // possibly associated
 	AstPackage *pkg; // possibly associated
 	AstFile *file;   // possibly associated
 	AstFile *file;   // possibly associated
+	char const *module_name;
 
 
 	PtrMap<Type *, LLVMTypeRef> types;                             // mutex: types_mutex
 	PtrMap<Type *, LLVMTypeRef> types;                             // mutex: types_mutex
 	PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *, mutex: types_mutex
 	PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *, mutex: types_mutex
@@ -379,7 +380,7 @@ struct lbProcedure {
 
 
 gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c);
 gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c);
 
 
-gb_internal String lb_mangle_name(lbModule *m, Entity *e);
+gb_internal String lb_mangle_name(Entity *e);
 gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
 gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String name = {});
 
 
 gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);
 gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0);

+ 1 - 0
src/llvm_backend_debug.cpp

@@ -1187,6 +1187,7 @@ gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen
 	if (USE_SEPARATE_MODULES) {
 	if (USE_SEPARATE_MODULES) {
 		m = lb_module_of_entity(gen, e);
 		m = lb_module_of_entity(gen, e);
 	}
 	}
+	GB_ASSERT(m != nullptr);
 
 
 	if (is_type_integer(e->type)) {
 	if (is_type_integer(e->type)) {
 		ExactValue const &value = e->Constant.value;
 		ExactValue const &value = e->Constant.value;

+ 54 - 45
src/llvm_backend_general.cpp

@@ -29,8 +29,9 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) {
 		module_name = gb_string_appendc(module_name, "-builtin");
 		module_name = gb_string_appendc(module_name, "-builtin");
 	}
 	}
 
 
+	m->module_name = module_name ? module_name : "odin_package";
 	m->ctx = LLVMContextCreate();
 	m->ctx = LLVMContextCreate();
-	m->mod = LLVMModuleCreateWithNameInContext(module_name ? module_name : "odin_package", m->ctx);
+	m->mod = LLVMModuleCreateWithNameInContext(m->module_name, m->ctx);
 	// m->debug_builder = nullptr;
 	// m->debug_builder = nullptr;
 	if (build_context.ODIN_DEBUG) {
 	if (build_context.ODIN_DEBUG) {
 		enum {DEBUG_METADATA_VERSION = 3};
 		enum {DEBUG_METADATA_VERSION = 3};
@@ -389,12 +390,14 @@ gb_internal lbModule *lb_module_of_entity(lbGenerator *gen, Entity *e) {
 	if (e->file) {
 	if (e->file) {
 		found = map_get(&gen->modules, cast(void *)e->file);
 		found = map_get(&gen->modules, cast(void *)e->file);
 		if (found) {
 		if (found) {
+			GB_ASSERT(*found != nullptr);
 			return *found;
 			return *found;
 		}
 		}
 	}
 	}
 	if (e->pkg) {
 	if (e->pkg) {
 		found = map_get(&gen->modules, cast(void *)e->pkg);
 		found = map_get(&gen->modules, cast(void *)e->pkg);
 		if (found) {
 		if (found) {
+			GB_ASSERT(*found != nullptr);
 			return *found;
 			return *found;
 		}
 		}
 	}
 	}
@@ -1532,7 +1535,7 @@ gb_internal void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) {
 	LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src));
 	LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src));
 }
 }
 
 
-gb_internal String lb_mangle_name(lbModule *m, Entity *e) {
+gb_internal String lb_mangle_name(Entity *e) {
 	String name = e->token.string;
 	String name = e->token.string;
 
 
 	AstPackage *pkg = e->pkg;
 	AstPackage *pkg = e->pkg;
@@ -1632,6 +1635,7 @@ gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedur
 }
 }
 
 
 gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
 gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
+	GB_ASSERT(m != nullptr);
 	if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) {
 	if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) {
 		return e->TypeName.ir_mangled_name;
 		return e->TypeName.ir_mangled_name;
 	}
 	}
@@ -1663,7 +1667,7 @@ gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_nam
 	}
 	}
 
 
 	if (!no_name_mangle) {
 	if (!no_name_mangle) {
-		name = lb_mangle_name(m, e);
+		name = lb_mangle_name(e);
 	}
 	}
 	if (name.len == 0) {
 	if (name.len == 0) {
 		name = e->token.string;
 		name = e->token.string;
@@ -3039,58 +3043,63 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
 		return *found;
 		return *found;
 	}
 	}
 
 
-	if (USE_SEPARATE_MODULES) {
-		lbModule *other_module = lb_module_of_entity(m->gen, e);
+	lbValue g = {};
+	String name = {};
 
 
-		bool is_external = other_module != m;
-		if (!is_external) {
-			if (e->code_gen_module != nullptr) {
-				other_module = e->code_gen_module;
-			} else {
-				other_module = nullptr;
-			}
-			is_external = other_module != m;
-		}
+	if (!USE_SEPARATE_MODULES) {
+		goto failed;
+	}
+	lbModule *other_module = lb_module_of_entity(m->gen, e);
 
 
-		if (is_external) {
-			String name = lb_get_entity_name(other_module, 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;
+		}
+		is_external = other_module != m;
+	}
 
 
-			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);
+	if (!is_external) {
+		goto failed;
+	}
+	name = lb_get_entity_name(other_module, e);
 
 
-			LLVMSetLinkage(g.value, LLVMExternalLinkage);
+	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);
 
 
-			lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name);
+	LLVMSetLinkage(g.value, LLVMExternalLinkage);
 
 
-			// LLVMSetLinkage(other_g.value, LLVMExternalLinkage);
-
-			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);
-			}
+	lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name);
 
 
+	if (e->Variable.thread_local_model != "") {
+		LLVMSetThreadLocal(g.value, true);
 
 
-			return g;
+		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);
 	}
 	}
-	GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string));
+
+
+	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 {};
 	return {};
 }
 }