Commit f6d4e2565e

Andrew Kelley <andrew@ziglang.org>
2019-06-11 05:51:43
use result loc for ref instruction
1 parent a0427d2
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;
 
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();
             }
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<IrInstructionRefGen>(&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<IrInstructionCompileErr>(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<IrInstructionDeclRef>(
-            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<IrInstructionDeclRef>(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<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
         case IrInstructionIdLoadPtrGen:
             return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr;
+        case IrInstructionIdRefGen:
+            return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr;
     }
     zig_unreachable();
 }
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;