Commit 06d8bb32e3
Changed files (4)
src/Compilation.zig
@@ -2795,6 +2795,7 @@ const Header = extern struct {
extra_len: u32,
limbs_len: u32,
string_bytes_len: u32,
+ tracked_insts_len: u32,
},
};
@@ -2802,7 +2803,7 @@ const Header = extern struct {
/// saved, such as the target and most CLI flags. A cache hit will only occur
/// when subsequent compiler invocations use the same set of flags.
pub fn saveState(comp: *Compilation) !void {
- var bufs_list: [6]std.os.iovec_const = undefined;
+ var bufs_list: [7]std.os.iovec_const = undefined;
var bufs_len: usize = 0;
const lf = comp.bin_file orelse return;
@@ -2815,6 +2816,7 @@ pub fn saveState(comp: *Compilation) !void {
.extra_len = @intCast(ip.extra.items.len),
.limbs_len = @intCast(ip.limbs.items.len),
.string_bytes_len = @intCast(ip.string_bytes.items.len),
+ .tracked_insts_len = @intCast(ip.tracked_insts.count()),
},
};
addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
@@ -2823,6 +2825,7 @@ pub fn saveState(comp: *Compilation) !void {
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
+ addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
// TODO: compilation errors
// TODO: files
src/InternPool.zig
@@ -54,6 +54,34 @@ string_table: std.HashMapUnmanaged(
std.hash_map.default_max_load_percentage,
) = .{},
+/// An index into `tracked_insts` gives a reference to a single ZIR instruction which
+/// persists across incremental updates.
+tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{},
+
+pub const TrackedInst = extern struct {
+ path_digest: Cache.BinDigest,
+ inst: Zir.Inst.Index,
+ comptime {
+ // The fields should be tightly packed. See also serialiation logic in `Compilation.saveState`.
+ assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Zir.Inst.Index));
+ }
+ pub const Index = enum(u32) {
+ _,
+ pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index {
+ return ip.tracked_insts.keys()[@intFromEnum(i)].inst;
+ }
+ };
+};
+
+pub fn trackZir(ip: *InternPool, gpa: Allocator, file: *Module.File, inst: Zir.Inst.Index) Allocator.Error!TrackedInst.Index {
+ const key: TrackedInst = .{
+ .path_digest = file.path_digest,
+ .inst = inst,
+ };
+ const gop = try ip.tracked_insts.getOrPut(gpa, key);
+ return @enumFromInt(gop.index);
+}
+
const FieldMap = std.ArrayHashMapUnmanaged(void, void, std.array_hash_map.AutoContext(void), false);
const builtin = @import("builtin");
@@ -62,11 +90,13 @@ const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const BigIntConst = std.math.big.int.Const;
const BigIntMutable = std.math.big.int.Mutable;
+const Cache = std.Build.Cache;
const Limb = std.math.big.Limb;
const Hash = std.hash.Wyhash;
const InternPool = @This();
const Module = @import("Module.zig");
+const Zcu = Module;
const Zir = @import("Zir.zig");
const KeyAdapter = struct {
@@ -409,7 +439,7 @@ pub const Key = union(enum) {
/// `none` when the struct has no declarations.
namespace: OptionalNamespaceIndex,
/// Index of the struct_decl ZIR instruction.
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
layout: std.builtin.Type.ContainerLayout,
field_names: NullTerminatedString.Slice,
field_types: Index.Slice,
@@ -653,7 +683,7 @@ pub const Key = union(enum) {
}
/// Asserts the struct is not packed.
- pub fn setZirIndex(s: @This(), ip: *InternPool, new_zir_index: Zir.Inst.Index) void {
+ pub fn setZirIndex(s: @This(), ip: *InternPool, new_zir_index: TrackedInst.Index) void {
assert(s.layout != .Packed);
const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?;
ip.extra.items[s.extra_index + field_index] = @intFromEnum(new_zir_index);
@@ -769,7 +799,7 @@ pub const Key = union(enum) {
flags: Tag.TypeUnion.Flags,
/// The enum that provides the list of field names and values.
enum_tag_ty: Index,
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
/// The returned pointer expires with any addition to the `InternPool`.
pub fn flagsPtr(self: @This(), ip: *const InternPool) *Tag.TypeUnion.Flags {
@@ -1056,7 +1086,7 @@ pub const Key = union(enum) {
/// the body. We store this rather than the body directly so that when ZIR
/// is regenerated on update(), we can map this to the new corresponding
/// ZIR instruction.
- zir_body_inst: Zir.Inst.Index,
+ zir_body_inst: TrackedInst.Index,
/// Relative to owner Decl.
lbrace_line: u32,
/// Relative to owner Decl.
@@ -1082,7 +1112,7 @@ pub const Key = union(enum) {
}
/// Returns a pointer that becomes invalid after any additions to the `InternPool`.
- pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *Zir.Inst.Index {
+ pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index {
return @ptrCast(&ip.extra.items[func.zir_body_inst_extra_index]);
}
@@ -1860,7 +1890,7 @@ pub const UnionType = struct {
/// If this slice has length 0 it means all elements are `none`.
field_aligns: Alignment.Slice,
/// Index of the union_decl ZIR instruction.
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
/// Index into extra array of the `flags` field.
flags_index: u32,
/// Copied from `enum_tag_ty`.
@@ -1954,10 +1984,10 @@ pub const UnionType = struct {
}
/// This does not mutate the field of UnionType.
- pub fn setZirIndex(self: @This(), ip: *InternPool, new_zir_index: Zir.Inst.Index) void {
+ pub fn setZirIndex(self: @This(), ip: *InternPool, new_zir_index: TrackedInst.Index) void {
const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;
- const ptr: *Zir.Inst.Index =
+ const ptr: *TrackedInst.Index =
@ptrCast(&ip.extra.items[self.flags_index - flags_field_index + zir_index_field_index]);
ptr.* = new_zir_index;
}
@@ -2976,7 +3006,7 @@ pub const Tag = enum(u8) {
analysis: FuncAnalysis,
owner_decl: DeclIndex,
ty: Index,
- zir_body_inst: Zir.Inst.Index,
+ zir_body_inst: TrackedInst.Index,
lbrace_line: u32,
rbrace_line: u32,
lbrace_column: u32,
@@ -3050,7 +3080,7 @@ pub const Tag = enum(u8) {
namespace: NamespaceIndex,
/// The enum that provides the list of field names and values.
tag_ty: Index,
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
pub const Flags = packed struct(u32) {
runtime_tag: UnionType.RuntimeTag,
@@ -3072,7 +3102,7 @@ pub const Tag = enum(u8) {
/// 2. init: Index for each fields_len // if tag is type_struct_packed_inits
pub const TypeStructPacked = struct {
decl: DeclIndex,
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
fields_len: u32,
namespace: OptionalNamespaceIndex,
backing_int_ty: Index,
@@ -3119,7 +3149,7 @@ pub const Tag = enum(u8) {
/// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved
pub const TypeStruct = struct {
decl: DeclIndex,
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
fields_len: u32,
flags: Flags,
size: u32,
@@ -3708,6 +3738,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
ip.string_table.deinit(gpa);
+ ip.tracked_insts.deinit(gpa);
+
ip.* = undefined;
}
@@ -5358,7 +5390,7 @@ pub const UnionTypeInit = struct {
flags: Tag.TypeUnion.Flags,
decl: DeclIndex,
namespace: NamespaceIndex,
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
fields_len: u32,
enum_tag_ty: Index,
/// May have length 0 which leaves the values unset until later.
@@ -5430,7 +5462,7 @@ pub const StructTypeInit = struct {
decl: DeclIndex,
namespace: OptionalNamespaceIndex,
layout: std.builtin.Type.ContainerLayout,
- zir_index: Zir.Inst.Index,
+ zir_index: TrackedInst.Index,
fields_len: u32,
known_non_opv: bool,
requires_comptime: RequiresComptime,
@@ -5704,7 +5736,7 @@ pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Alloc
pub const GetFuncDeclKey = struct {
owner_decl: DeclIndex,
ty: Index,
- zir_body_inst: Zir.Inst.Index,
+ zir_body_inst: TrackedInst.Index,
lbrace_line: u32,
rbrace_line: u32,
lbrace_column: u32,
@@ -5773,7 +5805,7 @@ pub const GetFuncDeclIesKey = struct {
is_var_args: bool,
is_generic: bool,
is_noinline: bool,
- zir_body_inst: Zir.Inst.Index,
+ zir_body_inst: TrackedInst.Index,
lbrace_line: u32,
rbrace_line: u32,
lbrace_column: u32,
@@ -6535,7 +6567,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
NullTerminatedString,
OptionalNullTerminatedString,
Tag.TypePointer.VectorIndex,
- Zir.Inst.Index,
+ TrackedInst.Index,
=> @intFromEnum(@field(extra, field.name)),
u32,
@@ -6611,7 +6643,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
NullTerminatedString,
OptionalNullTerminatedString,
Tag.TypePointer.VectorIndex,
- Zir.Inst.Index,
+ TrackedInst.Index,
=> @enumFromInt(int32),
u32,
@@ -8317,7 +8349,7 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
return funcAnalysis(ip, i).inferred_error_set;
}
-pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index {
+pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {
assert(i != .none);
const item = ip.items.get(@intFromEnum(i));
const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
src/Module.zig
@@ -834,6 +834,9 @@ pub const File = struct {
multi_pkg: bool = false,
/// List of references to this file, used for multi-package errors.
references: std.ArrayListUnmanaged(Reference) = .{},
+ /// The hash of the path to this file, used to store `InternPool.TrackedInst`.
+ /// undefined until `zir_loaded == true`.
+ path_digest: Cache.BinDigest = undefined,
/// Used by change detection algorithm, after astgen, contains the
/// set of decls that existed in the previous ZIR but not in the new one.
@@ -2594,7 +2597,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
const stat = try source_file.stat();
const want_local_cache = file.mod == mod.main_mod;
- const digest = hash: {
+ const bin_digest = hash: {
var path_hash: Cache.HashHelper = .{};
path_hash.addBytes(build_options.version);
path_hash.add(builtin.zig_backend);
@@ -2603,7 +2606,19 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
path_hash.addBytes(file.mod.root.sub_path);
}
path_hash.addBytes(file.sub_file_path);
- break :hash path_hash.final();
+ var bin: Cache.BinDigest = undefined;
+ path_hash.hasher.final(&bin);
+ break :hash bin;
+ };
+ file.path_digest = bin_digest;
+ const hex_digest = hex: {
+ var hex: Cache.HexDigest = undefined;
+ _ = std.fmt.bufPrint(
+ &hex,
+ "{s}",
+ .{std.fmt.fmtSliceHexLower(&bin_digest)},
+ ) catch unreachable;
+ break :hex hex;
};
const cache_directory = if (want_local_cache) mod.local_zir_cache else mod.global_zir_cache;
const zir_dir = cache_directory.handle;
@@ -2613,7 +2628,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
.never_loaded, .retryable_failure => lock: {
// First, load the cached ZIR code, if any.
log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{
- file.sub_file_path, want_local_cache, &digest,
+ file.sub_file_path, want_local_cache, &hex_digest,
});
break :lock .shared;
@@ -2640,7 +2655,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
// version. Likewise if we're working on AstGen and another process asks for
// the cached file, they'll get it.
const cache_file = while (true) {
- break zir_dir.createFile(&digest, .{
+ break zir_dir.createFile(&hex_digest, .{
.read = true,
.truncate = false,
.lock = lock,
@@ -2826,7 +2841,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
};
cache_file.writevAll(&iovecs) catch |err| {
log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{
- file.mod.root, file.sub_file_path, cache_directory, &digest, @errorName(err),
+ file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err),
});
};
@@ -2935,89 +2950,22 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)
return zir;
}
-/// Patch ups:
-/// * Struct.zir_index
-/// * Decl.zir_index
-/// * Fn.zir_body_inst
-/// * Decl.zir_decl_index
-fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
- const gpa = mod.gpa;
- const new_zir = file.zir;
-
- // The root decl will be null if the previous ZIR had AST errors.
- const root_decl = file.root_decl.unwrap() orelse return;
+fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir) !void {
+ const gpa = zcu.gpa;
- // Maps from old ZIR to new ZIR, declaration, struct_decl, enum_decl, etc. Any instruction which
- // creates a namespace, and any `declaration` instruction, gets mapped from old to new here.
var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{};
defer inst_map.deinit(gpa);
- try mapOldZirToNew(gpa, old_zir, new_zir, &inst_map);
-
- // Walk the Decl graph, updating ZIR indexes, strings, and populating
- // the deleted and outdated lists.
-
- var decl_stack: ArrayListUnmanaged(Decl.Index) = .{};
- defer decl_stack.deinit(gpa);
-
- try decl_stack.append(gpa, root_decl);
-
- file.deleted_decls.clearRetainingCapacity();
- file.outdated_decls.clearRetainingCapacity();
-
- // The root decl is always outdated; otherwise we would not have had
- // to re-generate ZIR for the File.
- try file.outdated_decls.append(gpa, root_decl);
-
- const ip = &mod.intern_pool;
-
- while (decl_stack.popOrNull()) |decl_index| {
- const decl = mod.declPtr(decl_index);
- // Anonymous decls and the root decl have this set to 0. We still need
- // to walk them but we do not need to modify this value.
- // Anonymous decls should not be marked outdated. They will be re-generated
- // if their owner decl is marked outdated.
- if (decl.zir_decl_index.unwrap()) |old_zir_decl_index| {
- const new_zir_decl_index = inst_map.get(old_zir_decl_index) orelse {
- try file.deleted_decls.append(gpa, decl_index);
- continue;
- };
- const old_hash = decl.contentsHashZir(old_zir);
- decl.zir_decl_index = new_zir_decl_index.toOptional();
- const new_hash = decl.contentsHashZir(new_zir);
- if (!std.zig.srcHashEql(old_hash, new_hash)) {
- try file.outdated_decls.append(gpa, decl_index);
- }
- }
+ try mapOldZirToNew(gpa, old_zir, file.zir, &inst_map);
- if (!decl.owns_tv) continue;
-
- if (decl.getOwnedStruct(mod)) |struct_type| {
- struct_type.setZirIndex(ip, inst_map.get(struct_type.zir_index) orelse {
- try file.deleted_decls.append(gpa, decl_index);
- continue;
- });
- }
-
- if (decl.getOwnedUnion(mod)) |union_type| {
- union_type.setZirIndex(ip, inst_map.get(union_type.zir_index) orelse {
- try file.deleted_decls.append(gpa, decl_index);
- continue;
- });
- }
-
- if (decl.getOwnedFunction(mod)) |func| {
- func.zirBodyInst(ip).* = inst_map.get(func.zir_body_inst) orelse {
- try file.deleted_decls.append(gpa, decl_index);
- continue;
- };
- }
-
- if (decl.getOwnedInnerNamespace(mod)) |namespace| {
- for (namespace.decls.keys()) |sub_decl| {
- try decl_stack.append(gpa, sub_decl);
- }
- }
+ // TODO: this should be done after all AstGen workers complete, to avoid
+ // iterating over this full set for every updated file.
+ for (zcu.intern_pool.tracked_insts.keys()) |*ti| {
+ if (!std.mem.eql(u8, &ti.path_digest, &file.path_digest)) continue;
+ ti.inst = inst_map.get(ti.inst) orelse {
+ // TODO: invalidate this `TrackedInst` via the dependency mechanism
+ continue;
+ };
}
}
@@ -3494,7 +3442,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
const struct_ty = sema.getStructType(
new_decl_index,
new_namespace_index,
- .main_struct_inst,
+ try mod.intern_pool.trackZir(gpa, file, .main_struct_inst),
) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
};
@@ -4472,7 +4420,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
};
defer inner_block.instructions.deinit(gpa);
- const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).*);
+ const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip));
// Here we are performing "runtime semantic analysis" for a function body, which means
// we must map the parameter ZIR instructions to `arg` AIR instructions.
@@ -6125,7 +6073,7 @@ pub fn getParamName(mod: *Module, func_index: InternPool.Index, index: u32) [:0]
const tags = file.zir.instructions.items(.tag);
const data = file.zir.instructions.items(.data);
- const param_body = file.zir.getParamBody(func.zir_body_inst);
+ const param_body = file.zir.getParamBody(func.zir_body_inst.resolve(&mod.intern_pool));
const param = param_body[index];
return switch (tags[@intFromEnum(param)]) {
src/Sema.zig
@@ -2708,11 +2708,12 @@ pub fn getStructType(
sema: *Sema,
decl: InternPool.DeclIndex,
namespace: InternPool.NamespaceIndex,
- zir_index: Zir.Inst.Index,
+ tracked_inst: InternPool.TrackedInst.Index,
) !InternPool.Index {
const mod = sema.mod;
const gpa = sema.gpa;
const ip = &mod.intern_pool;
+ const zir_index = tracked_inst.resolve(ip);
const extended = sema.code.instructions.items(.data)[@intFromEnum(zir_index)].extended;
assert(extended.opcode == .struct_decl);
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
@@ -2747,7 +2748,7 @@ pub fn getStructType(
const ty = try ip.getStructType(gpa, .{
.decl = decl,
.namespace = namespace.toOptional(),
- .zir_index = zir_index,
+ .zir_index = tracked_inst,
.layout = small.layout,
.known_non_opv = small.known_non_opv,
.is_tuple = small.is_tuple,
@@ -2797,7 +2798,8 @@ fn zirStructDecl(
errdefer mod.destroyNamespace(new_namespace_index);
const struct_ty = ty: {
- const ty = try sema.getStructType(new_decl_index, new_namespace_index, inst);
+ const tracked_inst = try ip.trackZir(mod.gpa, block.getFileScope(mod), inst);
+ const ty = try sema.getStructType(new_decl_index, new_namespace_index, tracked_inst);
if (sema.builtin_type_target_index != .none) {
ip.resolveBuiltinType(sema.builtin_type_target_index, ty);
break :ty sema.builtin_type_target_index;
@@ -2856,7 +2858,7 @@ fn createAnonymousDeclTypeNamed(
return new_decl_index;
},
.func => {
- const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index));
+ const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));
const zir_tags = sema.code.instructions.items(.tag);
var buf = std.ArrayList(u8).init(gpa);
@@ -3252,7 +3254,7 @@ fn zirUnionDecl(
},
.decl = new_decl_index,
.namespace = new_namespace_index,
- .zir_index = inst,
+ .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst),
.fields_len = fields_len,
.enum_tag_ty = .none,
.field_types = &.{},
@@ -7446,7 +7448,7 @@ fn analyzeCall(
// the AIR instructions of the callsite. The callee could be a generic function
// which means its parameter type expressions must be resolved in order and used
// to successively coerce the arguments.
- const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst);
+ const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst.resolve(ip));
try ics.callee().inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body);
var arg_i: u32 = 0;
@@ -7494,7 +7496,7 @@ fn analyzeCall(
// each of the parameters, resolving the return type and providing it to the child
// `Sema` so that it can be used for the `ret_ptr` instruction.
const ret_ty_inst = if (fn_info.ret_ty_body.len != 0)
- try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst)
+ try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip))
else
try sema.resolveInst(fn_info.ret_ty_ref);
const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
@@ -7885,7 +7887,7 @@ fn instantiateGenericCall(
const namespace_index = fn_owner_decl.src_namespace;
const namespace = mod.namespacePtr(namespace_index);
const fn_zir = namespace.file_scope.zir;
- const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst);
+ const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip));
const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());
@memset(comptime_args, .none);
@@ -9467,7 +9469,7 @@ fn funcCommon(
.is_generic = final_is_generic,
.is_noinline = is_noinline,
- .zir_body_inst = func_inst,
+ .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst),
.lbrace_line = src_locs.lbrace_line,
.rbrace_line = src_locs.rbrace_line,
.lbrace_column = @as(u16, @truncate(src_locs.columns)),
@@ -9545,7 +9547,7 @@ fn funcCommon(
.ty = func_ty,
.cc = cc,
.is_noinline = is_noinline,
- .zir_body_inst = func_inst,
+ .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst),
.lbrace_line = src_locs.lbrace_line,
.rbrace_line = src_locs.rbrace_line,
.lbrace_column = @as(u16, @truncate(src_locs.columns)),
@@ -21553,7 +21555,7 @@ fn zirReify(
.namespace = new_namespace_index,
.enum_tag_ty = enum_tag_ty,
.fields_len = fields_len,
- .zir_index = inst,
+ .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently?
.flags = .{
.layout = layout,
.status = .have_field_types,
@@ -21721,7 +21723,7 @@ fn reifyStruct(
const ty = try ip.getStructType(gpa, .{
.decl = new_decl_index,
.namespace = .none,
- .zir_index = inst,
+ .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently?
.layout = layout,
.known_non_opv = false,
.fields_len = fields_len,
@@ -35593,7 +35595,8 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
break :blk accumulator;
};
- const extended = zir.instructions.items(.data)[@intFromEnum(struct_type.zir_index)].extended;
+ const zir_index = struct_type.zir_index.resolve(ip);
+ const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
assert(extended.opcode == .struct_decl);
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
@@ -35613,7 +35616,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref);
} else {
const body = zir.bodySlice(extra_index, backing_int_body_len);
- const ty_ref = try sema.resolveBody(&block, body, struct_type.zir_index);
+ const ty_ref = try sema.resolveBody(&block, body, zir_index);
break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref);
}
};
@@ -36357,7 +36360,7 @@ fn semaStructFields(
const decl = mod.declPtr(decl_index);
const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
const zir = mod.namespacePtr(namespace_index).file_scope.zir;
- const zir_index = struct_type.zir_index;
+ const zir_index = struct_type.zir_index.resolve(ip);
const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
@@ -36628,7 +36631,7 @@ fn semaStructFieldInits(
const decl = mod.declPtr(decl_index);
const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
const zir = mod.namespacePtr(namespace_index).file_scope.zir;
- const zir_index = struct_type.zir_index;
+ const zir_index = struct_type.zir_index.resolve(ip);
const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa);
@@ -36777,7 +36780,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
const ip = &mod.intern_pool;
const decl_index = union_type.decl;
const zir = mod.namespacePtr(union_type.namespace).file_scope.zir;
- const extended = zir.instructions.items(.data)[@intFromEnum(union_type.zir_index)].extended;
+ const zir_index = union_type.zir_index.resolve(ip);
+ const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
assert(extended.opcode == .union_decl);
const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
var extra_index: usize = extended.operand;