Commit 1a7cf4cbce

Andrew Kelley <superjoe30@gmail.com>
2018-07-17 16:42:44
port 69e3b4e to self-hosted compiler
See #1249
1 parent 3cbf59b
Changed files (1)
src-self-hosted
src-self-hosted/ir.zig
@@ -53,6 +53,7 @@ pub const Instruction = struct {
     val: IrVal,
     ref_count: usize,
     span: Span,
+    owner_bb: *BasicBlock,
 
     /// true if this instruction was generated by zig and not from user code
     is_generated: bool,
@@ -132,6 +133,13 @@ pub const Instruction = struct {
         }
     }
 
+    fn ref(base: *Instruction, builder: *Builder) void {
+        base.ref_count += 1;
+        if (base.owner_bb != builder.current_basic_block and !base.isCompTime()) {
+            base.owner_bb.ref();
+        }
+    }
+
     fn getAsParam(param: *Instruction) !*Instruction {
         const child = param.child orelse return error.SemanticAnalysisFailed;
         switch (child.val) {
@@ -161,6 +169,10 @@ pub const Instruction = struct {
         }
     }
 
+    pub fn isCompTime(base: *const Instruction) bool {
+        return base.val == IrVal.KnownValue;
+    }
+
     pub fn linkToParent(self: *Instruction, parent: *Instruction) void {
         assert(self.parent == null);
         assert(parent.child == null);
@@ -816,6 +828,7 @@ pub const Builder = struct {
                 .child = null,
                 .parent = null,
                 .llvm_value = undefined,
+                .owner_bb = self.current_basic_block,
             },
             .params = params,
         });
@@ -825,8 +838,8 @@ pub const Builder = struct {
         inline while (i < @memberCount(I.Params)) : (i += 1) {
             const FieldType = comptime @typeOf(@field(I.Params(undefined), @memberName(I.Params, i)));
             switch (FieldType) {
-                *Instruction => @field(inst.params, @memberName(I.Params, i)).ref_count += 1,
-                ?*Instruction => if (@field(inst.params, @memberName(I.Params, i))) |other| other.ref_count += 1,
+                *Instruction => @field(inst.params, @memberName(I.Params, i)).ref(self),
+                ?*Instruction => if (@field(inst.params, @memberName(I.Params, i))) |other| other.ref(self),
                 else => {},
             }
         }