This commit is contained in:
gingerBill
2025-03-24 13:11:41 +00:00
parent acb578f184
commit 56e0ab7655
2 changed files with 46 additions and 6 deletions

View File

@@ -1125,10 +1125,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
visited[index] = true;
} else {
if (!visited[index]) {
values[index] = lb_const_value(m, f->type, {}, false).value;
values[index] = lb_const_value(m, f->type, {}, allow_local, is_rodata).value;
visited[index] = true;
}
unsigned idx_list_len = cast(unsigned)sel.index.count-1;
unsigned *idx_list = gb_alloc_array(temporary_allocator(), unsigned, idx_list_len);
@@ -1139,6 +1140,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
i32 index = sel.index[j];
Type *cvt = base_type(cv_type);
if (cvt->kind == Type_Struct) {
if (cvt->Struct.is_raw_union) {
// sanity check which should have been caught by `lb_is_nested_possibly_constant`
@@ -1164,9 +1166,38 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
}
if (is_constant) {
LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local, is_rodata).value;
if (LLVMIsConstant(elem_value)) {
if (LLVMIsConstant(elem_value) && LLVMIsConstant(values[index])) {
values[index] = llvm_const_insert_value(m, values[index], elem_value, idx_list, idx_list_len);
} else {
} else if (is_local) {
lbProcedure *p = m->curr_procedure;
GB_ASSERT(p != nullptr);
if (LLVMIsConstant(values[index])) {
lbAddr addr = lb_add_local_generated(p, f->type, false);
lb_addr_store(p, addr, lbValue{values[index], f->type});
values[index] = lb_addr_load(p, addr).value;
}
GB_ASSERT(LLVMIsALoadInst(values[index]));
LLVMValueRef ptr = LLVMGetOperand(values[index], 0);
LLVMValueRef *indices = gb_alloc_array(temporary_allocator(), LLVMValueRef, idx_list_len);
LLVMTypeRef lt_u32 = lb_type(m, t_u32);
for (unsigned i = 0; i < idx_list_len; i++) {
indices[i] = LLVMConstInt(lt_u32, idx_list[i], false);
}
ptr = LLVMBuildGEP2(p->builder, lb_type(m, f->type), ptr, indices, idx_list_len, "");
ptr = LLVMBuildPointerCast(p->builder, ptr, lb_type(m, alloc_type_pointer(tav.type)), "");
if (LLVMIsALoadInst(elem_value)) {
i64 sz = type_size_of(tav.type);
LLVMValueRef src = LLVMGetOperand(elem_value, 0);
lb_mem_copy_non_overlapping(p, {ptr, t_rawptr}, {src, t_rawptr}, lb_const_int(m, t_int, sz), false);
} else {
LLVMBuildStore(p->builder, elem_value, ptr);
}
is_constant = false;
}
}
@@ -1205,7 +1236,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
LLVMValueRef val = values[i];
if (!LLVMIsConstant(val)) {
GB_ASSERT(is_local);
GB_ASSERT(LLVMGetInstructionOpcode(val) == LLVMLoad);
GB_ASSERT(LLVMIsALoadInst(val));
is_constant = false;
}
}
@@ -1237,7 +1268,15 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
LLVMValueRef val = old_values[i];
if (!LLVMIsConstant(val)) {
LLVMValueRef dst = LLVMBuildStructGEP2(p->builder, llvm_addr_type(p->module, v.addr), v.addr.value, cast(unsigned)i, "");
LLVMBuildStore(p->builder, val, dst);
if (LLVMIsALoadInst(val)) {
Type *ptr_type = v.addr.type;
i64 sz = type_size_of(type_deref(ptr_type));
LLVMValueRef src = LLVMGetOperand(val, 0);
lb_mem_copy_non_overlapping(p, {dst, ptr_type}, {src, ptr_type}, lb_const_int(m, t_int, sz), false);
} else {
LLVMBuildStore(p->builder, val, dst);
}
}
}
return lb_addr_load(p, v);

View File

@@ -3493,7 +3493,8 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
if (tv.value.kind != ExactValue_Invalid) {
// NOTE(bill): Short on constant values
return lb_const_value(p->module, type, tv.value);
bool allow_local = true;
return lb_const_value(p->module, type, tv.value, allow_local);
} else if (tv.mode == Addressing_Type) {
// NOTE(bill, 2023-01-16): is this correct? I hope so at least
return lb_typeid(m, tv.type);