mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-20 12:44:59 -07:00
Minimize stack wastage with compound literals defining variables
This commit is contained in:
@@ -182,6 +182,8 @@ struct lbModule {
|
||||
PtrMap<Type *, lbAddr> map_cell_info_map; // address of runtime.Map_Info
|
||||
PtrMap<Type *, lbAddr> map_info_map; // address of runtime.Map_Cell_Info
|
||||
|
||||
PtrMap<Ast *, lbAddr> exact_value_compound_literal_addr_map; // Key: Ast_CompoundLit
|
||||
|
||||
LLVMPassManagerRef function_pass_managers[lbFunctionPassManager_COUNT];
|
||||
};
|
||||
|
||||
|
||||
@@ -460,6 +460,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
|
||||
LLVMValueRef ptr = LLVMBuildInBoundsGEP2(p->builder, llvm_type, array_data, indices, 2, "");
|
||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
||||
lbAddr slice = lb_add_local_generated(p, type, false);
|
||||
map_set(&m->exact_value_compound_literal_addr_map, value.value_compound, slice);
|
||||
|
||||
lb_fill_slice(p, slice, {ptr, alloc_type_pointer(elem)}, {len, t_int});
|
||||
return lb_addr_load(p, slice);
|
||||
}
|
||||
@@ -1042,6 +1044,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
|
||||
GB_ASSERT(is_local);
|
||||
lbProcedure *p = m->curr_procedure;
|
||||
lbAddr v = lb_add_local_generated(p, res.type, true);
|
||||
map_set(&m->exact_value_compound_literal_addr_map, value.value_compound, v);
|
||||
|
||||
LLVMBuildStore(p->builder, constant_value, v.addr.value);
|
||||
for (isize i = 0; i < value_count; i++) {
|
||||
LLVMValueRef val = old_values[i];
|
||||
|
||||
@@ -82,6 +82,7 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) {
|
||||
|
||||
map_init(&m->map_info_map, 0);
|
||||
map_init(&m->map_cell_info_map, 0);
|
||||
map_init(&m->exact_value_compound_literal_addr_map, 1024);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1523,7 +1523,8 @@ gb_internal void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) {
|
||||
lb_add_member(p->module, mangled_name, global_val);
|
||||
}
|
||||
}
|
||||
gb_internal void lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_values, lbValue src_value) {
|
||||
gb_internal isize lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_values, lbValue src_value) {
|
||||
isize init_count = dst_values->count;
|
||||
Type *t = src_value.type;
|
||||
if (t->kind == Type_Tuple) {
|
||||
lbTupleFix *tf = map_get(&p->tuple_fix_map, src_value.value);
|
||||
@@ -1540,6 +1541,7 @@ gb_internal void lb_append_tuple_values(lbProcedure *p, Array<lbValue> *dst_valu
|
||||
} else {
|
||||
array_add(dst_values, src_value);
|
||||
}
|
||||
return dst_values->count - init_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -2218,7 +2220,41 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
}
|
||||
array_add(&lvals, lval);
|
||||
}
|
||||
lb_build_assignment(p, lvals, vd->values);
|
||||
|
||||
auto const &values = vd->values;
|
||||
if (values.count > 0) {
|
||||
auto inits = array_make<lbValue>(permanent_allocator(), 0, lvals.count);
|
||||
|
||||
isize lval_index = 0;
|
||||
for (Ast *rhs : values) {
|
||||
rhs = unparen_expr(rhs);
|
||||
lbValue init = lb_build_expr(p, rhs);
|
||||
#if 1
|
||||
// NOTE(bill, 2023-02-17): lb_const_value might produce a stack local variable for the
|
||||
// compound literal, so reusing that variable should minimize the stack wastage
|
||||
if (rhs->kind == Ast_CompoundLit) {
|
||||
lbAddr *comp_lit_addr = map_get(&p->module->exact_value_compound_literal_addr_map, rhs);
|
||||
if (comp_lit_addr) {
|
||||
Entity *e = entity_of_node(vd->names[lval_index]);
|
||||
if (e) {
|
||||
lb_add_entity(p->module, e, comp_lit_addr->addr);
|
||||
lvals[lval_index] = {}; // do nothing so that nothing will assign to it
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lval_index += lb_append_tuple_values(p, &inits, init);
|
||||
}
|
||||
GB_ASSERT(lval_index == lvals.count);
|
||||
|
||||
GB_ASSERT(lvals.count == inits.count);
|
||||
for_array(i, inits) {
|
||||
lbAddr lval = lvals[i];
|
||||
lbValue init = inits[i];
|
||||
lb_addr_store(p, lval, init);
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(as, AssignStmt, node);
|
||||
|
||||
Reference in New Issue
Block a user