Commit 1a7cf4cbce
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 => {},
}
}