diff options
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f1aef4150..82da5c13a 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -6063,12 +6063,48 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc values[0] = LLVMConstNull(lb_alignment_prefix_type_hack(m, type->Struct.custom_align)); } + bool is_constant = true; + for (isize i = 0; i < value_count; i++) { - GB_ASSERT(LLVMIsConstant(values[i]) || LLVMIsGlobalConstant(values[i])); + LLVMValueRef val = values[i]; + if (!LLVMIsConstant(val)) { + GB_ASSERT(is_local); + GB_ASSERT(LLVMGetInstructionOpcode(val) == LLVMLoad); + is_constant = false; + } } - res.value = llvm_const_named_struct(lb_type(m, original_type), values, cast(unsigned)value_count); - return res; + if (is_constant) { + res.value = llvm_const_named_struct(lb_type(m, original_type), values, cast(unsigned)value_count); + return res; + } else { + // TODO(bill): THIS IS HACK BUT IT WORKS FOR WHAT I NEED + LLVMValueRef *new_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count); + for (isize i = 0; i < value_count; i++) { + LLVMValueRef val = values[i]; + if (LLVMIsConstant(val)) { + new_values[i] = val; + } else { + values[i] = lb_const_nil(m, get_struct_field_type(type, i-offset)).value; + } + } + LLVMValueRef constant_value = llvm_const_named_struct(lb_type(m, original_type), values, cast(unsigned)value_count); + + + GB_ASSERT(is_local); + lbProcedure *p = m->curr_procedure; + lbAddr v = lb_add_local_generated(p, res.type, false); + LLVMBuildStore(p->builder, constant_value, v.addr.value); + for (isize i = 0; i < value_count; i++) { + LLVMValueRef val = values[i]; + if (!LLVMIsConstant(val)) { + LLVMValueRef dst = LLVMBuildStructGEP(p->builder, v.addr.value, cast(unsigned)i, ""); + LLVMBuildStore(p->builder, dst, val); + } + } + return lb_addr_load(p, v); + + } } else if (is_type_bit_set(type)) { ast_node(cl, CompoundLit, value.value_compound); if (cl->elems.count == 0) { |