diff --git a/src/all_types.hpp b/src/all_types.hpp index a758f5d90..bd72a4fcc 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2234,6 +2234,7 @@ enum IrInstructionId { IrInstructionIdCDefine, IrInstructionIdCUndef, IrInstructionIdRef, + IrInstructionIdRefGen, IrInstructionIdCompileErr, IrInstructionIdCompileLog, IrInstructionIdErrName, @@ -2812,11 +2813,17 @@ struct IrInstructionRef { IrInstruction base; IrInstruction *value; - LLVMValueRef tmp_ptr; bool is_const; bool is_volatile; }; +struct IrInstructionRefGen { + IrInstruction base; + + IrInstruction *operand; + IrInstruction *result_loc; +}; + struct IrInstructionCompileErr { IrInstruction base; diff --git a/src/codegen.cpp b/src/codegen.cpp index 53800d4ee..5e3938a4a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4212,17 +4212,17 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru return phi; } -static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRef *instruction) { +static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRefGen *instruction) { if (!type_has_bits(instruction->base.value.type)) { return nullptr; } - LLVMValueRef value = ir_llvm_value(g, instruction->value); - if (handle_is_ptr(instruction->value->value.type)) { + LLVMValueRef value = ir_llvm_value(g, instruction->operand); + if (handle_is_ptr(instruction->operand->value.type)) { return value; } else { - assert(instruction->tmp_ptr); - gen_store_untyped(g, value, instruction->tmp_ptr, 0, false); - return instruction->tmp_ptr; + LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); + gen_store_untyped(g, value, result_loc, 0, false); + return result_loc; } } @@ -5530,6 +5530,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdResolveResult: case IrInstructionIdContainerInitList: case IrInstructionIdSliceSrc: + case IrInstructionIdRef: zig_unreachable(); case IrInstructionIdDeclVarGen: @@ -5584,8 +5585,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); case IrInstructionIdPhi: return ir_render_phi(g, executable, (IrInstructionPhi *)instruction); - case IrInstructionIdRef: - return ir_render_ref(g, executable, (IrInstructionRef *)instruction); + case IrInstructionIdRefGen: + return ir_render_ref(g, executable, (IrInstructionRefGen *)instruction); case IrInstructionIdErrName: return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction); case IrInstructionIdCmpxchgGen: @@ -6833,11 +6834,6 @@ static void do_code_gen(CodeGen *g) { if (instruction->id == IrInstructionIdCast) { IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction; slot = &cast_instruction->tmp_ptr; - } else if (instruction->id == IrInstructionIdRef) { - IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction; - slot = &ref_instruction->tmp_ptr; - assert(instruction->value.type->id == ZigTypeIdPointer); - slot_type = instruction->value.type->data.pointer.child_type; } else { zig_unreachable(); } diff --git a/src/ir.cpp b/src/ir.cpp index 16638de6b..d132f5110 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -617,6 +617,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { return IrInstructionIdRef; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) { + return IrInstructionIdRefGen; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { return IrInstructionIdCompileErr; } @@ -1961,6 +1965,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source return &instruction->base; } +static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, + IrInstruction *operand, IrInstruction *result_loc) +{ + IrInstructionRefGen *instruction = ir_build_instruction(&ira->new_irb, + source_instruction->scope, source_instruction->source_node); + instruction->base.value.type = result_type; + instruction->operand = operand; + instruction->result_loc = result_loc; + + ir_ref_instruction(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { IrInstructionCompileErr *instruction = ir_build_instruction(irb, scope, source_node); instruction->msg = msg; @@ -2636,11 +2655,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, - Tld *tld, LVal lval) -{ - IrInstructionDeclRef *instruction = ir_build_instruction( - irb, scope, source_node); +static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { + IrInstructionDeclRef *instruction = ir_build_instruction(irb, scope, source_node); instruction->tld = tld; instruction->lval = lval; @@ -11335,15 +11351,16 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); - IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, - source_instruction->source_node, value, is_const, is_volatile); - new_instruction->value.type = ptr_type; - new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; + + IrInstruction *result_loc; if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - assert(fn_entry); - fn_entry->alloca_list.append(new_instruction); + result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr); + } else { + result_loc = nullptr; } + + IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); + new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; return new_instruction; } @@ -24119,6 +24136,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction case IrInstructionIdReturnPtr: case IrInstructionIdAllocaGen: case IrInstructionIdSliceGen: + case IrInstructionIdRefGen: zig_unreachable(); case IrInstructionIdReturn: @@ -24653,6 +24671,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { return reinterpret_cast(instruction)->result_loc != nullptr; case IrInstructionIdLoadPtrGen: return reinterpret_cast(instruction)->result_loc != nullptr; + case IrInstructionIdRefGen: + return reinterpret_cast(instruction)->result_loc != nullptr; } zig_unreachable(); } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 90fd5aa06..1935c0d7f 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -668,6 +668,13 @@ static void ir_print_ref(IrPrint *irp, IrInstructionRef *instruction) { ir_print_other_instruction(irp, instruction->value); } +static void ir_print_ref_gen(IrPrint *irp, IrInstructionRefGen *instruction) { + fprintf(irp->f, "@ref("); + ir_print_other_instruction(irp, instruction->operand); + fprintf(irp->f, ")result="); + ir_print_other_instruction(irp, instruction->result_loc); +} + static void ir_print_compile_err(IrPrint *irp, IrInstructionCompileErr *instruction) { fprintf(irp->f, "@compileError("); ir_print_other_instruction(irp, instruction->msg); @@ -1711,6 +1718,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdRef: ir_print_ref(irp, (IrInstructionRef *)instruction); break; + case IrInstructionIdRefGen: + ir_print_ref_gen(irp, (IrInstructionRefGen *)instruction); + break; case IrInstructionIdCompileErr: ir_print_compile_err(irp, (IrInstructionCompileErr *)instruction); break;