diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-09-28 20:40:26 +0100 |
|---|---|---|
| committer | gingerBill <gingerBill@users.noreply.github.com> | 2025-09-28 20:40:26 +0100 |
| commit | 17204bd1c23934c878c699e026aa8994e430a372 (patch) | |
| tree | 4da593a77dd27132aa864d95b617e8b6437ada04 /src | |
| parent | ffdfbfe2c2d0e09087f166be79f3dbc2859844e6 (diff) | |
Global const unions with `@(rodata)`
Diffstat (limited to 'src')
| -rw-r--r-- | src/llvm_backend.cpp | 75 | ||||
| -rw-r--r-- | src/llvm_backend.hpp | 2 | ||||
| -rw-r--r-- | src/llvm_backend_const.cpp | 47 |
3 files changed, 70 insertions, 54 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 3af473c3a..8ac68d9bf 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3262,36 +3262,13 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { lbModule *m = &gen->default_module; String name = lb_get_entity_name(m, e); + lbGlobalVariable var = {}; + var.decl = decl; + lbValue g = {}; - g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); g.type = alloc_type_pointer(e->type); + g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); - lb_apply_thread_local_model(g.value, e->Variable.thread_local_model); - - if (is_foreign) { - LLVMSetLinkage(g.value, LLVMExternalLinkage); - LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass); - LLVMSetExternallyInitialized(g.value, true); - lb_add_foreign_library_path(m, e->Variable.foreign_library); - } else { - LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); - } - if (is_export) { - LLVMSetLinkage(g.value, LLVMDLLExportLinkage); - LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); - } else if (!is_foreign) { - LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage); - } - lb_set_linkage_from_entity_flags(m, g.value, e->flags); - LLVMSetAlignment(g.value, cast(u32)type_align_of(e->type)); - - if (e->Variable.link_section.len > 0) { - LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section)); - } - - lbGlobalVariable var = {}; - var.var = g; - var.decl = decl; if (decl->init_expr != nullptr) { TypeAndValue tav = type_and_value_of_expr(decl->init_expr); @@ -3305,6 +3282,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { ExactValue v = tav.value; lbValue init = lb_const_value(m, tav.type, v, cc); + + LLVMDeleteGlobal(g.value); + g.value = nullptr; + g.value = LLVMAddGlobal(m->mod, LLVMTypeOf(init.value), alloc_cstring(permanent_allocator(), name)); + LLVMSetInitializer(g.value, init.value); var.is_initialized = true; if (cc.is_rodata) { @@ -3323,15 +3305,32 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetGlobalConstant(g.value, true); } - if (e->flags & EntityFlag_Require) { - lb_append_to_compiler_used(m, g.value); - } - array_add(&global_variables, var); + lb_apply_thread_local_model(g.value, e->Variable.thread_local_model); - lb_add_entity(m, e, g); - lb_add_member(m, name, g); + if (is_foreign) { + LLVMSetLinkage(g.value, LLVMExternalLinkage); + LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass); + LLVMSetExternallyInitialized(g.value, true); + lb_add_foreign_library_path(m, e->Variable.foreign_library); + } else if (!var.is_initialized) { + LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); + } + if (is_export) { + LLVMSetLinkage(g.value, LLVMDLLExportLinkage); + LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass); + } else if (!is_foreign) { + LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMWeakAnyLinkage : LLVMInternalLinkage); + } + lb_set_linkage_from_entity_flags(m, g.value, e->flags); + LLVMSetAlignment(g.value, cast(u32)type_align_of(e->type)); + if (e->Variable.link_section.len > 0) { + LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section)); + } + if (e->flags & EntityFlag_Require) { + lb_append_to_compiler_used(m, g.value); + } if (m->debug_builder) { String global_name = e->token.string; @@ -3361,6 +3360,16 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMGlobalSetMetadata(g.value, 0, global_variable_metadata); } } + + g.value = LLVMConstPointerCast(g.value, lb_type(m, alloc_type_pointer(e->type))); + + var.var = g; + array_add(&global_variables, var); + + lb_add_entity(m, e, g); + lb_add_member(m, name, g); + + } if (build_context.ODIN_DEBUG) { diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 76ec2fe1f..6870f6259 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -604,7 +604,7 @@ gb_internal lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, As gb_internal lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block); gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_); -gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_); +gb_internal LLVMValueRef llvm_const_named_struct_internal(lbModule *m, LLVMTypeRef t, LLVMValueRef *values, isize value_count_); gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name); gb_internal lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t); diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 8cdc889e0..d3e2826ed 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -81,7 +81,7 @@ gb_internal String lb_get_const_string(lbModule *m, lbValue value) { } -gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) { +gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst, bool *failure_) { LLVMTypeRef src = LLVMTypeOf(val); if (src == dst) { return val; @@ -97,10 +97,8 @@ gb_internal LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) { return LLVMConstPointerCast(val, dst); case LLVMStructTypeKind: return val; - default: - GB_PANIC("Unhandled const cast %s to %s", LLVMPrintTypeToString(src), LLVMPrintTypeToString(dst)); } - + if (failure_) *failure_ = true; return val; } @@ -125,13 +123,13 @@ gb_internal LLVMValueRef llvm_const_string_internal(lbModule *m, Type *t, LLVMVa LLVMConstNull(lb_type(m, t_i32)), len, }; - return llvm_const_named_struct_internal(lb_type(m, t), values, 3); + return llvm_const_named_struct_internal(m, lb_type(m, t), values, 3); } else { LLVMValueRef values[2] = { data, len, }; - return llvm_const_named_struct_internal(lb_type(m, t), values, 2); + return llvm_const_named_struct_internal(m, lb_type(m, t), values, 2); } } @@ -143,13 +141,13 @@ gb_internal LLVMValueRef llvm_const_string16_internal(lbModule *m, Type *t, LLVM LLVMConstNull(lb_type(m, t_i32)), len, }; - return llvm_const_named_struct_internal(lb_type(m, t), values, 3); + return llvm_const_named_struct_internal(m, lb_type(m, t), values, 3); } else { LLVMValueRef values[2] = { data, len, }; - return llvm_const_named_struct_internal(lb_type(m, t), values, 2); + return llvm_const_named_struct_internal(m, lb_type(m, t), values, 2); } } @@ -161,7 +159,7 @@ gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValue unsigned value_count = cast(unsigned)value_count_; unsigned elem_count = LLVMCountStructElementTypes(struct_type); if (elem_count == value_count) { - return llvm_const_named_struct_internal(struct_type, values, value_count_); + return llvm_const_named_struct_internal(m, struct_type, values, value_count_); } Type *bt = base_type(t); GB_ASSERT(bt->kind == Type_Struct || bt->kind == Type_Union); @@ -181,24 +179,33 @@ gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValue } } - return llvm_const_named_struct_internal(struct_type, values_with_padding, values_with_padding_count); + return llvm_const_named_struct_internal(m, struct_type, values_with_padding, values_with_padding_count); } -gb_internal LLVMValueRef llvm_const_named_struct_internal(LLVMTypeRef t, LLVMValueRef *values, isize value_count_) { +gb_internal LLVMValueRef llvm_const_named_struct_internal(lbModule *m, LLVMTypeRef t, LLVMValueRef *values, isize value_count_) { unsigned value_count = cast(unsigned)value_count_; unsigned elem_count = LLVMCountStructElementTypes(t); GB_ASSERT_MSG(value_count == elem_count, "%s %u %u", LLVMPrintTypeToString(t), value_count, elem_count); + bool failure = false; for (unsigned i = 0; i < elem_count; i++) { LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i); - values[i] = llvm_const_cast(values[i], elem_type); + values[i] = llvm_const_cast(values[i], elem_type, &failure); + } + + if (failure) { + return LLVMConstStructInContext(m->ctx, values, value_count, true); } return LLVMConstNamedStruct(t, values, value_count); } gb_internal LLVMValueRef llvm_const_array(lbModule *m, LLVMTypeRef elem_type, LLVMValueRef *values, isize value_count_) { unsigned value_count = cast(unsigned)value_count_; + bool failure = false; for (unsigned i = 0; i < value_count; i++) { - values[i] = llvm_const_cast(values[i], elem_type); + values[i] = llvm_const_cast(values[i], elem_type, &failure); + } + if (failure) { + return LLVMConstStructInContext(m->ctx, values, value_count, false); } for (unsigned i = 0; i < value_count; i++) { if (elem_type != LLVMTypeOf(values[i])) { @@ -851,7 +858,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb if (is_type_union_maybe_pointer(type)) { LLVMValueRef values[1] = {cv.value}; - res.value = llvm_const_named_struct_internal(llvm_type, values, 1); + res.value = llvm_const_named_struct_internal(m, llvm_type, values, 1); res.type = original_type; return res; } else { @@ -869,7 +876,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb value_count = 3; padding = LLVMConstNull(LLVMStructGetTypeAtIndex(llvm_type, 2)); } - res.value = llvm_const_named_struct_internal(llvm_type, values, value_count); + res.value = llvm_const_named_struct_internal(m, llvm_type, values, value_count); res.type = original_type; return res; } @@ -1060,7 +1067,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb Type *elem = type->Matrix.elem; lbValue single_elem = lb_const_value(m, elem, value, cc); - single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem)); + single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem), /*failure_*/nullptr); i64 total_elem_count = matrix_type_total_internal_elems(type); LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, cast(isize)total_elem_count); @@ -1082,7 +1089,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb Type *elem = type->SimdVector.elem; lbValue single_elem = lb_const_value(m, elem, value, cc); - single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem)); + single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem), /*failure_*/nullptr); LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count); for (i64 i = 0; i < count; i++) { @@ -1662,7 +1669,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb values[i] = LLVMConstNull(et); } for (isize i = 0; i < total_elem_count; i++) { - values[i] = llvm_const_cast(values[i], et); + values[i] = llvm_const_cast(values[i], et, /*failure_*/nullptr); } res.value = LLVMConstVector(values, cast(unsigned)total_elem_count); @@ -1829,7 +1836,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb } if (is_constant) { - res.value = llvm_const_named_struct_internal(struct_type, values, cast(unsigned)value_count); + res.value = llvm_const_named_struct_internal(m, struct_type, values, cast(unsigned)value_count); return res; } else { // TODO(bill): THIS IS HACK BUT IT WORKS FOR WHAT I NEED @@ -1843,7 +1850,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb new_values[i] = LLVMConstNull(LLVMTypeOf(old_value)); } } - LLVMValueRef constant_value = llvm_const_named_struct_internal(struct_type, new_values, cast(unsigned)value_count); + LLVMValueRef constant_value = llvm_const_named_struct_internal(m, struct_type, new_values, cast(unsigned)value_count); GB_ASSERT(is_local); lbProcedure *p = m->curr_procedure; |