From 7c0257fcdad00cbb66d1d089715ec0ad684fd4c0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 Mar 2023 15:39:41 +0000 Subject: [PATCH] Fix value elision on declaration --- src/llvm_backend.hpp | 2 ++ src/llvm_backend_const.cpp | 9 ++++++++- src/llvm_backend_debug.cpp | 1 - src/llvm_backend_opt.cpp | 6 +++++- src/llvm_backend_stmt.cpp | 27 ++++++++++++++++++--------- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 4a78ca3a9..4104d5b5f 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -337,6 +337,8 @@ struct lbProcedure { LLVMMetadataRef debug_info; + lbAddr current_elision_hint; + PtrMap selector_values; PtrMap selector_addr; PtrMap tuple_fix_map; diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 3da768cd1..286c01f74 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -484,7 +484,14 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)}; 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); + + lbAddr slice = {}; + if (p->current_elision_hint.addr.value && are_types_identical(lb_addr_type(p->current_elision_hint), type)) { + slice = p->current_elision_hint; + p->current_elision_hint = {}; + } else { + 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}); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index f65656494..fd26c41a0 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -989,7 +989,6 @@ gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, T return; } - AstFile *file = p->body->file(); LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p); diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index e06042341..61f51b15b 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -275,6 +275,9 @@ gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_mac **************************************************************************/ gb_internal void lb_run_remove_dead_instruction_pass(lbProcedure *p) { + unsigned debug_declare_id = LLVMLookupIntrinsicID("llvm.dbg.declare", 16); + GB_ASSERT(debug_declare_id != 0); + isize removal_count = 0; isize pass_count = 0; isize const max_pass_count = 10; @@ -310,6 +313,8 @@ gb_internal void lb_run_remove_dead_instruction_pass(lbProcedure *p) { // NOTE(bill): Explicit instructions are set here because some instructions could have side effects switch (LLVMGetInstructionOpcode(curr_instr)) { + // case LLVMAlloca: + case LLVMFNeg: case LLVMAdd: case LLVMFAdd: @@ -329,7 +334,6 @@ gb_internal void lb_run_remove_dead_instruction_pass(lbProcedure *p) { case LLVMAnd: case LLVMOr: case LLVMXor: - case LLVMAlloca: case LLVMLoad: case LLVMGetElementPtr: case LLVMTrunc: diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index ec6ac5886..456a262a4 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2287,18 +2287,25 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { isize lval_index = 0; for (Ast *rhs : values) { + p->current_elision_hint = lvals[lval_index]; + 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 + if (p->current_elision_hint.addr.value != lvals[lval_index].addr.value) { + lvals[lval_index] = {}; // do nothing so that nothing will assign to it + } else { + // 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) { + GB_ASSERT(p->current_elision_hint.addr.value == nullptr); + GB_ASSERT(p->current_elision_hint.addr.value != lvals[lval_index].addr.value); + lvals[lval_index] = {}; // do nothing so that nothing will assign to it + } } } } @@ -2308,6 +2315,8 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { } GB_ASSERT(lval_index == lvals.count); + p->current_elision_hint = {}; + GB_ASSERT(lvals.count == inits.count); for_array(i, inits) { lbAddr lval = lvals[i];