More uses of SSA aggregation values

This commit is contained in:
gingerBill
2026-03-15 19:49:26 +00:00
parent 0dbda03890
commit bb2e42faa6
4 changed files with 29 additions and 60 deletions

View File

@@ -1495,7 +1495,6 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV
}
}
lbAddr res = lb_add_local_generated(p, type, false); // NOTE: initialized in full later
lbValue a = lb_emit_struct_ev(p, lhs, 0);
lbValue b = lb_emit_struct_ev(p, lhs, 1);
lbValue c = lb_emit_struct_ev(p, rhs, 0);
@@ -1533,10 +1532,9 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV
}
}
lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), real);
lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), imag);
return lb_addr_load(p, res);
lbValue fields[2] = {real, imag};
return lb_build_struct_value(p, type, fields, gb_count_of(fields));
} else if (is_type_quaternion(type)) {
lhs = lb_emit_conv(p, lhs, type);
rhs = lb_emit_conv(p, rhs, type);
@@ -1549,7 +1547,6 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV
immediate_type = t_f32;
}
lbAddr res = lb_add_local_generated(p, type, false); // NOTE: initialized in full later
lbValue x0 = lb_emit_struct_ev(p, lhs, 0);
lbValue x1 = lb_emit_struct_ev(p, lhs, 1);
lbValue x2 = lb_emit_struct_ev(p, lhs, 2);
@@ -1577,10 +1574,6 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV
lbValue z2 = lb_emit_arith(p, op, x2, y2, immediate_type);
lbValue z3 = lb_emit_arith(p, op, x3, y3, immediate_type);
lbValue d0 = lb_emit_struct_ep(p, res.addr, 0);
lbValue d1 = lb_emit_struct_ep(p, res.addr, 1);
lbValue d2 = lb_emit_struct_ep(p, res.addr, 2);
lbValue d3 = lb_emit_struct_ep(p, res.addr, 3);
if (immediate_type != ft) {
z0 = lb_emit_conv(p, z0, ft);
@@ -1589,12 +1582,9 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV
z3 = lb_emit_conv(p, z3, ft);
}
lb_emit_store(p, d0, z0);
lb_emit_store(p, d1, z1);
lb_emit_store(p, d2, z2);
lb_emit_store(p, d3, z3);
return lb_addr_load(p, res);
lbValue fields[4] = {z0, z1, z2, z3};
return lb_build_struct_value(p, type, fields, gb_count_of(fields));
} else if (op == Token_Mul) {
TEMPORARY_ALLOCATOR_GUARD();
@@ -2232,29 +2222,23 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
if (is_type_complex(src) && is_type_complex(dst)) {
Type *ft = base_complex_elem_type(dst);
lbAddr gen = lb_add_local_generated(p, t, false);
lbValue gp = lb_addr_get_ptr(p, gen);
lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
lb_emit_store(p, lb_emit_struct_ep(p, gp, 1), imag);
return lb_addr_load(p, gen);
lbValue fields[2] = {real, imag};
return lb_build_struct_value(p, t, fields, gb_count_of(fields));
}
if (is_type_quaternion(src) && is_type_quaternion(dst)) {
// @QuaternionLayout
Type *ft = base_complex_elem_type(dst);
lbAddr gen = lb_add_local_generated(p, t, false);
lbValue gp = lb_addr_get_ptr(p, gen);
lbValue q0 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
lbValue q1 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
lbValue q2 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 2), ft);
lbValue q3 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 3), ft);
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), q0);
lb_emit_store(p, lb_emit_struct_ep(p, gp, 1), q1);
lb_emit_store(p, lb_emit_struct_ep(p, gp, 2), q2);
lb_emit_store(p, lb_emit_struct_ep(p, gp, 3), q3);
return lb_addr_load(p, gen);
lbValue fields[4] = {q0, q1, q2, q2};
return lb_build_struct_value(p, t, fields, gb_count_of(fields));
}
if (is_type_integer(src) && is_type_complex(dst)) {
@@ -2844,8 +2828,6 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
return lb_const_nil(p->module, t);
}
lbAddr result = lb_add_local_generated(p, t, true);
Type *st = default_type(src_type);
lbValue data = lb_address_from_load_or_generate_local(p, value);
@@ -2854,13 +2836,8 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
data = lb_emit_conv(p, data, t_rawptr);
lbValue id = lb_typeid(p->module, st);
lbValue any_data = lb_emit_struct_ep(p, result.addr, 0);
lbValue any_id = lb_emit_struct_ep(p, result.addr, 1);
lb_emit_store(p, any_data, data);
lb_emit_store(p, any_id, id);
return lb_addr_load(p, result);
lbValue fields[2] = {data, id};
return lb_build_struct_value(p, t, fields, gb_count_of(fields));
}

View File

@@ -1028,15 +1028,14 @@ gb_internal lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
lbValue res = {};
Type *t = val.type;
if (is_type_complex(t)) {
res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
lbValue real = lb_emit_struct_ev(p, val, 0);
lbValue imag = lb_emit_struct_ev(p, val, 1);
imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real);
lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag);
lbValue fields[2] = {real, imag};
return lb_build_struct_value(p, type, fields, gb_count_of(fields));
} else if (is_type_quaternion(t)) {
// @QuaternionLayout
res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
lbValue real = lb_emit_struct_ev(p, val, 3);
lbValue imag = lb_emit_struct_ev(p, val, 0);
lbValue jmag = lb_emit_struct_ev(p, val, 1);
@@ -1044,10 +1043,9 @@ gb_internal lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type);
kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type);
lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real);
lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag);
lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag);
lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag);
lbValue fields[4] = {imag, jmag, kmag, real};
return lb_build_struct_value(p, type, fields, gb_count_of(fields));
} else if (is_type_array_like(t)) {
res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
Type *elem_type = base_array_type(t);

View File

@@ -2537,33 +2537,26 @@ gb_internal void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return
} else {
Type *ret_type = p->type->Proc.results;
// NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
if (return_by_pointer) {
res = p->return_ptr.addr;
} else {
res = lb_add_local_generated(p, ret_type, false).addr;
}
auto result_values = slice_make<lbValue>(temporary_allocator(), results.count);
auto result_eps = slice_make<lbValue>(temporary_allocator(), results.count);
for_array(i, results) {
result_values[i] = lb_emit_conv(p, results[i], tuple->variables[i]->type);
}
for_array(i, results) {
result_eps[i] = lb_emit_struct_ep(p, res, cast(i32)i);
}
for_array(i, result_eps) {
lb_emit_store(p, result_eps[i], result_values[i]);
}
if (return_by_pointer) {
res = p->return_ptr.addr;
auto result_eps = slice_make<lbValue>(temporary_allocator(), results.count);
for_array(i, results) {
result_eps[i] = lb_emit_struct_ep(p, res, cast(i32)i);
}
for_array(i, result_eps) {
lb_emit_store(p, result_eps[i], result_values[i]);
}
lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr, pos);
LLVMBuildRetVoid(p->builder);
return;
}
res = lb_emit_load(p, res);
res = lb_build_struct_value(p, ret_type, result_values.data, result_values.count);
}
}
lb_build_return_stmt_internal(p, res, pos);

View File

@@ -1736,7 +1736,8 @@ gb_internal lbValue lb_emit_struct_iv(lbProcedure *p, lbValue agg, lbValue field
gb_internal lbValue lb_build_struct_value(lbProcedure *p, Type *type, lbValue *fields, isize count) {
LLVMTypeRef llvm_type = lb_type(p->module, type);
lbValue agg = {};
agg.value = LLVMGetPoison(llvm_type);
// agg.value = LLVMGetPoison(llvm_type);
agg.value = LLVMConstNull(llvm_type);
agg.type = type;
for (isize i = 0; i < count; i++) {
agg = lb_emit_struct_iv(p, agg, fields[i], cast(i32)i);