diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig index c1f9c97001..e0c09b1e4b 100644 --- a/src-self-hosted/ir.zig +++ b/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 => {}, } }