Parcourir la source

Fix value elision on declaration

gingerBill il y a 2 ans
Parent
commit
7c0257fcda

+ 2 - 0
src/llvm_backend.hpp

@@ -337,6 +337,8 @@ struct lbProcedure {
 
 	LLVMMetadataRef debug_info;
 
+	lbAddr current_elision_hint;
+
 	PtrMap<Ast *, lbValue> selector_values;
 	PtrMap<Ast *, lbAddr>  selector_addr;
 	PtrMap<LLVMValueRef, lbTupleFix> tuple_fix_map;

+ 8 - 1
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});

+ 0 - 1
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);

+ 5 - 1
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:

+ 18 - 9
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];