Make linkage weak in certain places

This commit is contained in:
gingerBill
2024-07-15 12:30:32 +01:00
parent 549311fac9
commit 7d643bcae3
2 changed files with 49 additions and 49 deletions
+10 -5
View File
@@ -144,11 +144,14 @@ gb_internal void lb_correct_entity_linkage(lbGenerator *gen) {
LLVMValueRef other_global = nullptr; LLVMValueRef other_global = nullptr;
if (ec.e->kind == Entity_Variable) { if (ec.e->kind == Entity_Variable) {
other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname);
if (other_global) {
LLVMSetLinkage(other_global, LLVMWeakAnyLinkage);
}
} else if (ec.e->kind == Entity_Procedure) { } else if (ec.e->kind == Entity_Procedure) {
other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname);
} if (other_global) {
if (other_global) { LLVMSetLinkage(other_global, LLVMWeakAnyLinkage);
LLVMSetLinkage(other_global, LLVMExternalLinkage); }
} }
} }
} }
@@ -1437,7 +1440,9 @@ gb_internal bool lb_is_module_empty(lbModule *m) {
} }
for (auto g = LLVMGetFirstGlobal(m->mod); g != nullptr; g = LLVMGetNextGlobal(g)) { 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; continue;
} }
if (!LLVMIsExternallyInitialized(g)) { if (!LLVMIsExternallyInitialized(g)) {
@@ -3266,7 +3271,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
LLVMSetLinkage(g.value, LLVMDLLExportLinkage); LLVMSetLinkage(g.value, LLVMDLLExportLinkage);
LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass);
} else if (!is_foreign) { } 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); lb_set_linkage_from_entity_flags(m, g.value, e->flags);
+39 -44
View File
@@ -3043,61 +3043,56 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
return *found; return *found;
} }
lbValue g = {}; if (USE_SEPARATE_MODULES) {
String name = {}; lbModule *other_module = lb_module_of_entity(m->gen, e);
if (!USE_SEPARATE_MODULES) { bool is_external = other_module != m;
goto failed; if (!is_external) {
} if (e->code_gen_module != nullptr) {
lbModule *other_module = lb_module_of_entity(m->gen, e); other_module = e->code_gen_module;
} else {
bool is_external = other_module != m; other_module = &m->gen->default_module;
if (!is_external) { }
if (e->code_gen_module != nullptr) { is_external = other_module != m;
other_module = e->code_gen_module;
} else {
other_module = &m->gen->default_module;
} }
is_external = other_module != m;
}
if (!is_external) { if (is_external) {
goto failed; String name = lb_get_entity_name(other_module, e);
}
name = lb_get_entity_name(other_module, e);
g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); lbValue g = {};
g.type = alloc_type_pointer(e->type); g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
lb_add_entity(m, e, g); g.type = alloc_type_pointer(e->type);
lb_add_member(m, name, g); 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 != "") { if (e->Variable.thread_local_model != "") {
LLVMSetThreadLocal(g.value, true); LLVMSetThreadLocal(g.value, true);
String m = e->Variable.thread_local_model; String m = e->Variable.thread_local_model;
LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel; LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
if (m == "default") { if (m == "default") {
mode = LLVMGeneralDynamicTLSModel; mode = LLVMGeneralDynamicTLSModel;
} else if (m == "localdynamic") { } else if (m == "localdynamic") {
mode = LLVMLocalDynamicTLSModel; mode = LLVMLocalDynamicTLSModel;
} else if (m == "initialexec") { } else if (m == "initialexec") {
mode = LLVMInitialExecTLSModel; mode = LLVMInitialExecTLSModel;
} else if (m == "localexec") { } else if (m == "localexec") {
mode = LLVMLocalExecTLSModel; mode = LLVMLocalExecTLSModel;
} else { } else {
GB_PANIC("Unhandled thread local mode %.*s", LIT(m)); GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
}
LLVMSetThreadLocalMode(g.value, mode);
}
return g;
} }
LLVMSetThreadLocalMode(g.value, mode);
} }
return g;
failed:;
GB_PANIC("\n\tError in: %s, missing value '%.*s' in module %s\n", 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); token_pos_to_string(e->token.pos), LIT(e->token.string), m->module_name);
return {}; return {};