| ... | @@ -53,6 +53,7 @@ pub const Instruction = struct { | ... | @@ -53,6 +53,7 @@ pub const Instruction = struct { |
| 53 | val: IrVal, | 53 | val: IrVal, |
| 54 | ref_count: usize, | 54 | ref_count: usize, |
| 55 | span: Span, | 55 | span: Span, |
| | 56 | owner_bb: *BasicBlock, |
| 56 | | 57 | |
| 57 | /// true if this instruction was generated by zig and not from user code | 58 | /// true if this instruction was generated by zig and not from user code |
| 58 | is_generated: bool, | 59 | is_generated: bool, |
| ... | @@ -132,6 +133,13 @@ pub const Instruction = struct { | ... | @@ -132,6 +133,13 @@ pub const Instruction = struct { |
| 132 | } | 133 | } |
| 133 | } | 134 | } |
| 134 | | 135 | |
| | 136 | fn ref(base: *Instruction, builder: *Builder) void { |
| | 137 | base.ref_count += 1; |
| | 138 | if (base.owner_bb != builder.current_basic_block and !base.isCompTime()) { |
| | 139 | base.owner_bb.ref(); |
| | 140 | } |
| | 141 | } |
| | 142 | |
| 135 | fn getAsParam(param: *Instruction) !*Instruction { | 143 | fn getAsParam(param: *Instruction) !*Instruction { |
| 136 | const child = param.child orelse return error.SemanticAnalysisFailed; | 144 | const child = param.child orelse return error.SemanticAnalysisFailed; |
| 137 | switch (child.val) { | 145 | switch (child.val) { |
| ... | @@ -161,6 +169,10 @@ pub const Instruction = struct { | ... | @@ -161,6 +169,10 @@ pub const Instruction = struct { |
| 161 | } | 169 | } |
| 162 | } | 170 | } |
| 163 | | 171 | |
| | 172 | pub fn isCompTime(base: *const Instruction) bool { |
| | 173 | return base.val == IrVal.KnownValue; |
| | 174 | } |
| | 175 | |
| 164 | pub fn linkToParent(self: *Instruction, parent: *Instruction) void { | 176 | pub fn linkToParent(self: *Instruction, parent: *Instruction) void { |
| 165 | assert(self.parent == null); | 177 | assert(self.parent == null); |
| 166 | assert(parent.child == null); | 178 | assert(parent.child == null); |
| ... | @@ -816,6 +828,7 @@ pub const Builder = struct { | ... | @@ -816,6 +828,7 @@ pub const Builder = struct { |
| 816 | .child = null, | 828 | .child = null, |
| 817 | .parent = null, | 829 | .parent = null, |
| 818 | .llvm_value = undefined, | 830 | .llvm_value = undefined, |
| | 831 | .owner_bb = self.current_basic_block, |
| 819 | }, | 832 | }, |
| 820 | .params = params, | 833 | .params = params, |
| 821 | }); | 834 | }); |
| ... | @@ -825,8 +838,8 @@ pub const Builder = struct { | ... | @@ -825,8 +838,8 @@ pub const Builder = struct { |
| 825 | inline while (i < @memberCount(I.Params)) : (i += 1) { | 838 | inline while (i < @memberCount(I.Params)) : (i += 1) { |
| 826 | const FieldType = comptime @typeOf(@field(I.Params(undefined), @memberName(I.Params, i))); | 839 | const FieldType = comptime @typeOf(@field(I.Params(undefined), @memberName(I.Params, i))); |
| 827 | switch (FieldType) { | 840 | switch (FieldType) { |
| 828 | *Instruction => @field(inst.params, @memberName(I.Params, i)).ref_count += 1, | 841 | *Instruction => @field(inst.params, @memberName(I.Params, i)).ref(self), |
| 829 | ?*Instruction => if (@field(inst.params, @memberName(I.Params, i))) |other| other.ref_count += 1, | 842 | ?*Instruction => if (@field(inst.params, @memberName(I.Params, i))) |other| other.ref(self), |
| 830 | else => {}, | 843 | else => {}, |
| 831 | } | 844 | } |
| 832 | } | 845 | } |