| author | |
| committer | |
| log | 06d8bb32e3edfb4a26c6d3ecdf198574f4bd3f87 |
| tree | c71cc2ab5af1f24f224031f947c9ac0396df2562 |
| parent | ae845a33c04fb287ae5a7445743c2b570e40ca1f |
| signature |
It is problematic for the cached `InternPool` state to directly
reference ZIR instruction indices, as these are not stable across
incremental updates. The existing ZIR mapping logic attempts to handle
this by iterating the existing Decl graph for a file after `AstGen` and
update ZIR indices on `Decl`s, struct types, etc. However, this is
unreliable due to generic instantiations, and relies on specialized
logic for everything which may refer to a ZIR instruction (e.g. a
struct's owner decl). I therefore determined that a prerequisite change
for incremental compilation would be to rework how we store these
indices.
This commit introduces a `TrackedInst` type which provides a stable
index (`TrackedInst.Index`) for a single ZIR instruction in the
compilation. The `InternPool` now stores these values in place of ZIR
instruction indices. This makes the ZIR mapping logic relatively
trivial: after `AstGen` completes, we simply iterate all `TrackedInst`
values and update those indices which have changed. In future, if the
corresponding ZIR instruction has been removed, we must also invalidate
any dependencies on this instruction to trigger any required
re-analysis, however the dependency system does not yet exist.4 files changed, 110 insertions(+), 123 deletions(-)
src/Compilation.zig+4-1| ... | @@ -2795,6 +2795,7 @@ const Header = extern struct { | ... | @@ -2795,6 +2795,7 @@ const Header = extern struct { |
| 2795 | extra_len: u32, | 2795 | extra_len: u32, |
| 2796 | limbs_len: u32, | 2796 | limbs_len: u32, |
| 2797 | string_bytes_len: u32, | 2797 | string_bytes_len: u32, |
| 2798 | tracked_insts_len: u32, | ||
| 2798 | }, | 2799 | }, |
| 2799 | }; | 2800 | }; |
| 2800 | 2801 | ||
| ... | @@ -2802,7 +2803,7 @@ const Header = extern struct { | ... | @@ -2802,7 +2803,7 @@ const Header = extern struct { |
| 2802 | /// saved, such as the target and most CLI flags. A cache hit will only occur | 2803 | /// saved, such as the target and most CLI flags. A cache hit will only occur |
| 2803 | /// when subsequent compiler invocations use the same set of flags. | 2804 | /// when subsequent compiler invocations use the same set of flags. |
| 2804 | pub fn saveState(comp: *Compilation) !void { | 2805 | pub fn saveState(comp: *Compilation) !void { |
| 2805 | var bufs_list: [6]std.os.iovec_const = undefined; | 2806 | var bufs_list: [7]std.os.iovec_const = undefined; |
| 2806 | var bufs_len: usize = 0; | 2807 | var bufs_len: usize = 0; |
| 2807 | 2808 | ||
| 2808 | const lf = comp.bin_file orelse return; | 2809 | const lf = comp.bin_file orelse return; |
| ... | @@ -2815,6 +2816,7 @@ pub fn saveState(comp: *Compilation) !void { | ... | @@ -2815,6 +2816,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 2815 | .extra_len = @intCast(ip.extra.items.len), | 2816 | .extra_len = @intCast(ip.extra.items.len), |
| 2816 | .limbs_len = @intCast(ip.limbs.items.len), | 2817 | .limbs_len = @intCast(ip.limbs.items.len), |
| 2817 | .string_bytes_len = @intCast(ip.string_bytes.items.len), | 2818 | .string_bytes_len = @intCast(ip.string_bytes.items.len), |
| 2819 | .tracked_insts_len = @intCast(ip.tracked_insts.count()), | ||
| 2818 | }, | 2820 | }, |
| 2819 | }; | 2821 | }; |
| 2820 | addBuf(&bufs_list, &bufs_len, mem.asBytes(&header)); | 2822 | addBuf(&bufs_list, &bufs_len, mem.asBytes(&header)); |
| ... | @@ -2823,6 +2825,7 @@ pub fn saveState(comp: *Compilation) !void { | ... | @@ -2823,6 +2825,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 2823 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data))); | 2825 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data))); |
| 2824 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag))); | 2826 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag))); |
| 2825 | addBuf(&bufs_list, &bufs_len, ip.string_bytes.items); | 2827 | addBuf(&bufs_list, &bufs_len, ip.string_bytes.items); |
| 2828 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys())); | ||
| 2826 | 2829 | ||
| 2827 | // TODO: compilation errors | 2830 | // TODO: compilation errors |
| 2828 | // TODO: files | 2831 | // TODO: files |
src/InternPool.zig+51-19| ... | @@ -54,6 +54,34 @@ string_table: std.HashMapUnmanaged( | ... | @@ -54,6 +54,34 @@ string_table: std.HashMapUnmanaged( |
| 54 | std.hash_map.default_max_load_percentage, | 54 | std.hash_map.default_max_load_percentage, |
| 55 | ) = .{}, | 55 | ) = .{}, |
| 56 | 56 | ||
| 57 | /// An index into `tracked_insts` gives a reference to a single ZIR instruction which | ||
| 58 | /// persists across incremental updates. | ||
| 59 | tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{}, | ||
| 60 | |||
| 61 | pub const TrackedInst = extern struct { | ||
| 62 | path_digest: Cache.BinDigest, | ||
| 63 | inst: Zir.Inst.Index, | ||
| 64 | comptime { | ||
| 65 | // The fields should be tightly packed. See also serialiation logic in `Compilation.saveState`. | ||
| 66 | assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Zir.Inst.Index)); | ||
| 67 | } | ||
| 68 | pub const Index = enum(u32) { | ||
| 69 | _, | ||
| 70 | pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index { | ||
| 71 | return ip.tracked_insts.keys()[@intFromEnum(i)].inst; | ||
| 72 | } | ||
| 73 | }; | ||
| 74 | }; | ||
| 75 | |||
| 76 | pub fn trackZir(ip: *InternPool, gpa: Allocator, file: *Module.File, inst: Zir.Inst.Index) Allocator.Error!TrackedInst.Index { | ||
| 77 | const key: TrackedInst = .{ | ||
| 78 | .path_digest = file.path_digest, | ||
| 79 | .inst = inst, | ||
| 80 | }; | ||
| 81 | const gop = try ip.tracked_insts.getOrPut(gpa, key); | ||
| 82 | return @enumFromInt(gop.index); | ||
| 83 | } | ||
| 84 | |||
| 57 | const FieldMap = std.ArrayHashMapUnmanaged(void, void, std.array_hash_map.AutoContext(void), false); | 85 | const FieldMap = std.ArrayHashMapUnmanaged(void, void, std.array_hash_map.AutoContext(void), false); |
| 58 | 86 | ||
| 59 | const builtin = @import("builtin"); | 87 | const builtin = @import("builtin"); |
| ... | @@ -62,11 +90,13 @@ const Allocator = std.mem.Allocator; | ... | @@ -62,11 +90,13 @@ const Allocator = std.mem.Allocator; |
| 62 | const assert = std.debug.assert; | 90 | const assert = std.debug.assert; |
| 63 | const BigIntConst = std.math.big.int.Const; | 91 | const BigIntConst = std.math.big.int.Const; |
| 64 | const BigIntMutable = std.math.big.int.Mutable; | 92 | const BigIntMutable = std.math.big.int.Mutable; |
| 93 | const Cache = std.Build.Cache; | ||
| 65 | const Limb = std.math.big.Limb; | 94 | const Limb = std.math.big.Limb; |
| 66 | const Hash = std.hash.Wyhash; | 95 | const Hash = std.hash.Wyhash; |
| 67 | 96 | ||
| 68 | const InternPool = @This(); | 97 | const InternPool = @This(); |
| 69 | const Module = @import("Module.zig"); | 98 | const Module = @import("Module.zig"); |
| 99 | const Zcu = Module; | ||
| 70 | const Zir = @import("Zir.zig"); | 100 | const Zir = @import("Zir.zig"); |
| 71 | 101 | ||
| 72 | const KeyAdapter = struct { | 102 | const KeyAdapter = struct { |
| ... | @@ -409,7 +439,7 @@ pub const Key = union(enum) { | ... | @@ -409,7 +439,7 @@ pub const Key = union(enum) { |
| 409 | /// `none` when the struct has no declarations. | 439 | /// `none` when the struct has no declarations. |
| 410 | namespace: OptionalNamespaceIndex, | 440 | namespace: OptionalNamespaceIndex, |
| 411 | /// Index of the struct_decl ZIR instruction. | 441 | /// Index of the struct_decl ZIR instruction. |
| 412 | zir_index: Zir.Inst.Index, | 442 | zir_index: TrackedInst.Index, |
| 413 | layout: std.builtin.Type.ContainerLayout, | 443 | layout: std.builtin.Type.ContainerLayout, |
| 414 | field_names: NullTerminatedString.Slice, | 444 | field_names: NullTerminatedString.Slice, |
| 415 | field_types: Index.Slice, | 445 | field_types: Index.Slice, |
| ... | @@ -653,7 +683,7 @@ pub const Key = union(enum) { | ... | @@ -653,7 +683,7 @@ pub const Key = union(enum) { |
| 653 | } | 683 | } |
| 654 | 684 | ||
| 655 | /// Asserts the struct is not packed. | 685 | /// Asserts the struct is not packed. |
| 656 | pub fn setZirIndex(s: @This(), ip: *InternPool, new_zir_index: Zir.Inst.Index) void { | 686 | pub fn setZirIndex(s: @This(), ip: *InternPool, new_zir_index: TrackedInst.Index) void { |
| 657 | assert(s.layout != .Packed); | 687 | assert(s.layout != .Packed); |
| 658 | const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?; | 688 | const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?; |
| 659 | ip.extra.items[s.extra_index + field_index] = @intFromEnum(new_zir_index); | 689 | ip.extra.items[s.extra_index + field_index] = @intFromEnum(new_zir_index); |
| ... | @@ -769,7 +799,7 @@ pub const Key = union(enum) { | ... | @@ -769,7 +799,7 @@ pub const Key = union(enum) { |
| 769 | flags: Tag.TypeUnion.Flags, | 799 | flags: Tag.TypeUnion.Flags, |
| 770 | /// The enum that provides the list of field names and values. | 800 | /// The enum that provides the list of field names and values. |
| 771 | enum_tag_ty: Index, | 801 | enum_tag_ty: Index, |
| 772 | zir_index: Zir.Inst.Index, | 802 | zir_index: TrackedInst.Index, |
| 773 | 803 | ||
| 774 | /// The returned pointer expires with any addition to the `InternPool`. | 804 | /// The returned pointer expires with any addition to the `InternPool`. |
| 775 | pub fn flagsPtr(self: @This(), ip: *const InternPool) *Tag.TypeUnion.Flags { | 805 | pub fn flagsPtr(self: @This(), ip: *const InternPool) *Tag.TypeUnion.Flags { |
| ... | @@ -1056,7 +1086,7 @@ pub const Key = union(enum) { | ... | @@ -1056,7 +1086,7 @@ pub const Key = union(enum) { |
| 1056 | /// the body. We store this rather than the body directly so that when ZIR | 1086 | /// the body. We store this rather than the body directly so that when ZIR |
| 1057 | /// is regenerated on update(), we can map this to the new corresponding | 1087 | /// is regenerated on update(), we can map this to the new corresponding |
| 1058 | /// ZIR instruction. | 1088 | /// ZIR instruction. |
| 1059 | zir_body_inst: Zir.Inst.Index, | 1089 | zir_body_inst: TrackedInst.Index, |
| 1060 | /// Relative to owner Decl. | 1090 | /// Relative to owner Decl. |
| 1061 | lbrace_line: u32, | 1091 | lbrace_line: u32, |
| 1062 | /// Relative to owner Decl. | 1092 | /// Relative to owner Decl. |
| ... | @@ -1082,7 +1112,7 @@ pub const Key = union(enum) { | ... | @@ -1082,7 +1112,7 @@ pub const Key = union(enum) { |
| 1082 | } | 1112 | } |
| 1083 | 1113 | ||
| 1084 | /// Returns a pointer that becomes invalid after any additions to the `InternPool`. | 1114 | /// Returns a pointer that becomes invalid after any additions to the `InternPool`. |
| 1085 | pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *Zir.Inst.Index { | 1115 | pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index { |
| 1086 | return @ptrCast(&ip.extra.items[func.zir_body_inst_extra_index]); | 1116 | return @ptrCast(&ip.extra.items[func.zir_body_inst_extra_index]); |
| 1087 | } | 1117 | } |
| 1088 | 1118 | ||
| ... | @@ -1860,7 +1890,7 @@ pub const UnionType = struct { | ... | @@ -1860,7 +1890,7 @@ pub const UnionType = struct { |
| 1860 | /// If this slice has length 0 it means all elements are `none`. | 1890 | /// If this slice has length 0 it means all elements are `none`. |
| 1861 | field_aligns: Alignment.Slice, | 1891 | field_aligns: Alignment.Slice, |
| 1862 | /// Index of the union_decl ZIR instruction. | 1892 | /// Index of the union_decl ZIR instruction. |
| 1863 | zir_index: Zir.Inst.Index, | 1893 | zir_index: TrackedInst.Index, |
| 1864 | /// Index into extra array of the `flags` field. | 1894 | /// Index into extra array of the `flags` field. |
| 1865 | flags_index: u32, | 1895 | flags_index: u32, |
| 1866 | /// Copied from `enum_tag_ty`. | 1896 | /// Copied from `enum_tag_ty`. |
| ... | @@ -1954,10 +1984,10 @@ pub const UnionType = struct { | ... | @@ -1954,10 +1984,10 @@ pub const UnionType = struct { |
| 1954 | } | 1984 | } |
| 1955 | 1985 | ||
| 1956 | /// This does not mutate the field of UnionType. | 1986 | /// This does not mutate the field of UnionType. |
| 1957 | pub fn setZirIndex(self: @This(), ip: *InternPool, new_zir_index: Zir.Inst.Index) void { | 1987 | pub fn setZirIndex(self: @This(), ip: *InternPool, new_zir_index: TrackedInst.Index) void { |
| 1958 | const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?; | 1988 | const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?; |
| 1959 | const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?; | 1989 | const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?; |
| 1960 | const ptr: *Zir.Inst.Index = | 1990 | const ptr: *TrackedInst.Index = |
| 1961 | @ptrCast(&ip.extra.items[self.flags_index - flags_field_index + zir_index_field_index]); | 1991 | @ptrCast(&ip.extra.items[self.flags_index - flags_field_index + zir_index_field_index]); |
| 1962 | ptr.* = new_zir_index; | 1992 | ptr.* = new_zir_index; |
| 1963 | } | 1993 | } |
| ... | @@ -2976,7 +3006,7 @@ pub const Tag = enum(u8) { | ... | @@ -2976,7 +3006,7 @@ pub const Tag = enum(u8) { |
| 2976 | analysis: FuncAnalysis, | 3006 | analysis: FuncAnalysis, |
| 2977 | owner_decl: DeclIndex, | 3007 | owner_decl: DeclIndex, |
| 2978 | ty: Index, | 3008 | ty: Index, |
| 2979 | zir_body_inst: Zir.Inst.Index, | 3009 | zir_body_inst: TrackedInst.Index, |
| 2980 | lbrace_line: u32, | 3010 | lbrace_line: u32, |
| 2981 | rbrace_line: u32, | 3011 | rbrace_line: u32, |
| 2982 | lbrace_column: u32, | 3012 | lbrace_column: u32, |
| ... | @@ -3050,7 +3080,7 @@ pub const Tag = enum(u8) { | ... | @@ -3050,7 +3080,7 @@ pub const Tag = enum(u8) { |
| 3050 | namespace: NamespaceIndex, | 3080 | namespace: NamespaceIndex, |
| 3051 | /// The enum that provides the list of field names and values. | 3081 | /// The enum that provides the list of field names and values. |
| 3052 | tag_ty: Index, | 3082 | tag_ty: Index, |
| 3053 | zir_index: Zir.Inst.Index, | 3083 | zir_index: TrackedInst.Index, |
| 3054 | 3084 | ||
| 3055 | pub const Flags = packed struct(u32) { | 3085 | pub const Flags = packed struct(u32) { |
| 3056 | runtime_tag: UnionType.RuntimeTag, | 3086 | runtime_tag: UnionType.RuntimeTag, |
| ... | @@ -3072,7 +3102,7 @@ pub const Tag = enum(u8) { | ... | @@ -3072,7 +3102,7 @@ pub const Tag = enum(u8) { |
| 3072 | /// 2. init: Index for each fields_len // if tag is type_struct_packed_inits | 3102 | /// 2. init: Index for each fields_len // if tag is type_struct_packed_inits |
| 3073 | pub const TypeStructPacked = struct { | 3103 | pub const TypeStructPacked = struct { |
| 3074 | decl: DeclIndex, | 3104 | decl: DeclIndex, |
| 3075 | zir_index: Zir.Inst.Index, | 3105 | zir_index: TrackedInst.Index, |
| 3076 | fields_len: u32, | 3106 | fields_len: u32, |
| 3077 | namespace: OptionalNamespaceIndex, | 3107 | namespace: OptionalNamespaceIndex, |
| 3078 | backing_int_ty: Index, | 3108 | backing_int_ty: Index, |
| ... | @@ -3119,7 +3149,7 @@ pub const Tag = enum(u8) { | ... | @@ -3119,7 +3149,7 @@ pub const Tag = enum(u8) { |
| 3119 | /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved | 3149 | /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved |
| 3120 | pub const TypeStruct = struct { | 3150 | pub const TypeStruct = struct { |
| 3121 | decl: DeclIndex, | 3151 | decl: DeclIndex, |
| 3122 | zir_index: Zir.Inst.Index, | 3152 | zir_index: TrackedInst.Index, |
| 3123 | fields_len: u32, | 3153 | fields_len: u32, |
| 3124 | flags: Flags, | 3154 | flags: Flags, |
| 3125 | size: u32, | 3155 | size: u32, |
| ... | @@ -3708,6 +3738,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { | ... | @@ -3708,6 +3738,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 3708 | 3738 | ||
| 3709 | ip.string_table.deinit(gpa); | 3739 | ip.string_table.deinit(gpa); |
| 3710 | 3740 | ||
| 3741 | ip.tracked_insts.deinit(gpa); | ||
| 3742 | |||
| 3711 | ip.* = undefined; | 3743 | ip.* = undefined; |
| 3712 | } | 3744 | } |
| 3713 | 3745 | ||
| ... | @@ -5358,7 +5390,7 @@ pub const UnionTypeInit = struct { | ... | @@ -5358,7 +5390,7 @@ pub const UnionTypeInit = struct { |
| 5358 | flags: Tag.TypeUnion.Flags, | 5390 | flags: Tag.TypeUnion.Flags, |
| 5359 | decl: DeclIndex, | 5391 | decl: DeclIndex, |
| 5360 | namespace: NamespaceIndex, | 5392 | namespace: NamespaceIndex, |
| 5361 | zir_index: Zir.Inst.Index, | 5393 | zir_index: TrackedInst.Index, |
| 5362 | fields_len: u32, | 5394 | fields_len: u32, |
| 5363 | enum_tag_ty: Index, | 5395 | enum_tag_ty: Index, |
| 5364 | /// May have length 0 which leaves the values unset until later. | 5396 | /// May have length 0 which leaves the values unset until later. |
| ... | @@ -5430,7 +5462,7 @@ pub const StructTypeInit = struct { | ... | @@ -5430,7 +5462,7 @@ pub const StructTypeInit = struct { |
| 5430 | decl: DeclIndex, | 5462 | decl: DeclIndex, |
| 5431 | namespace: OptionalNamespaceIndex, | 5463 | namespace: OptionalNamespaceIndex, |
| 5432 | layout: std.builtin.Type.ContainerLayout, | 5464 | layout: std.builtin.Type.ContainerLayout, |
| 5433 | zir_index: Zir.Inst.Index, | 5465 | zir_index: TrackedInst.Index, |
| 5434 | fields_len: u32, | 5466 | fields_len: u32, |
| 5435 | known_non_opv: bool, | 5467 | known_non_opv: bool, |
| 5436 | requires_comptime: RequiresComptime, | 5468 | requires_comptime: RequiresComptime, |
| ... | @@ -5704,7 +5736,7 @@ pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Alloc | ... | @@ -5704,7 +5736,7 @@ pub fn getExternFunc(ip: *InternPool, gpa: Allocator, key: Key.ExternFunc) Alloc |
| 5704 | pub const GetFuncDeclKey = struct { | 5736 | pub const GetFuncDeclKey = struct { |
| 5705 | owner_decl: DeclIndex, | 5737 | owner_decl: DeclIndex, |
| 5706 | ty: Index, | 5738 | ty: Index, |
| 5707 | zir_body_inst: Zir.Inst.Index, | 5739 | zir_body_inst: TrackedInst.Index, |
| 5708 | lbrace_line: u32, | 5740 | lbrace_line: u32, |
| 5709 | rbrace_line: u32, | 5741 | rbrace_line: u32, |
| 5710 | lbrace_column: u32, | 5742 | lbrace_column: u32, |
| ... | @@ -5773,7 +5805,7 @@ pub const GetFuncDeclIesKey = struct { | ... | @@ -5773,7 +5805,7 @@ pub const GetFuncDeclIesKey = struct { |
| 5773 | is_var_args: bool, | 5805 | is_var_args: bool, |
| 5774 | is_generic: bool, | 5806 | is_generic: bool, |
| 5775 | is_noinline: bool, | 5807 | is_noinline: bool, |
| 5776 | zir_body_inst: Zir.Inst.Index, | 5808 | zir_body_inst: TrackedInst.Index, |
| 5777 | lbrace_line: u32, | 5809 | lbrace_line: u32, |
| 5778 | rbrace_line: u32, | 5810 | rbrace_line: u32, |
| 5779 | lbrace_column: u32, | 5811 | lbrace_column: u32, |
| ... | @@ -6535,7 +6567,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { | ... | @@ -6535,7 +6567,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { |
| 6535 | NullTerminatedString, | 6567 | NullTerminatedString, |
| 6536 | OptionalNullTerminatedString, | 6568 | OptionalNullTerminatedString, |
| 6537 | Tag.TypePointer.VectorIndex, | 6569 | Tag.TypePointer.VectorIndex, |
| 6538 | Zir.Inst.Index, | 6570 | TrackedInst.Index, |
| 6539 | => @intFromEnum(@field(extra, field.name)), | 6571 | => @intFromEnum(@field(extra, field.name)), |
| 6540 | 6572 | ||
| 6541 | u32, | 6573 | u32, |
| ... | @@ -6611,7 +6643,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct | ... | @@ -6611,7 +6643,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct |
| 6611 | NullTerminatedString, | 6643 | NullTerminatedString, |
| 6612 | OptionalNullTerminatedString, | 6644 | OptionalNullTerminatedString, |
| 6613 | Tag.TypePointer.VectorIndex, | 6645 | Tag.TypePointer.VectorIndex, |
| 6614 | Zir.Inst.Index, | 6646 | TrackedInst.Index, |
| 6615 | => @enumFromInt(int32), | 6647 | => @enumFromInt(int32), |
| 6616 | 6648 | ||
| 6617 | u32, | 6649 | u32, |
| ... | @@ -8317,7 +8349,7 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool { | ... | @@ -8317,7 +8349,7 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool { |
| 8317 | return funcAnalysis(ip, i).inferred_error_set; | 8349 | return funcAnalysis(ip, i).inferred_error_set; |
| 8318 | } | 8350 | } |
| 8319 | 8351 | ||
| 8320 | pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index { | 8352 | pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index { |
| 8321 | assert(i != .none); | 8353 | assert(i != .none); |
| 8322 | const item = ip.items.get(@intFromEnum(i)); | 8354 | const item = ip.items.get(@intFromEnum(i)); |
| 8323 | const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?; | 8355 | const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?; |
src/Module.zig+34-86| ... | @@ -834,6 +834,9 @@ pub const File = struct { | ... | @@ -834,6 +834,9 @@ pub const File = struct { |
| 834 | multi_pkg: bool = false, | 834 | multi_pkg: bool = false, |
| 835 | /// List of references to this file, used for multi-package errors. | 835 | /// List of references to this file, used for multi-package errors. |
| 836 | references: std.ArrayListUnmanaged(Reference) = .{}, | 836 | references: std.ArrayListUnmanaged(Reference) = .{}, |
| 837 | /// The hash of the path to this file, used to store `InternPool.TrackedInst`. | ||
| 838 | /// undefined until `zir_loaded == true`. | ||
| 839 | path_digest: Cache.BinDigest = undefined, | ||
| 837 | 840 | ||
| 838 | /// Used by change detection algorithm, after astgen, contains the | 841 | /// Used by change detection algorithm, after astgen, contains the |
| 839 | /// set of decls that existed in the previous ZIR but not in the new one. | 842 | /// 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 { | ... | @@ -2594,7 +2597,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2594 | const stat = try source_file.stat(); | 2597 | const stat = try source_file.stat(); |
| 2595 | 2598 | ||
| 2596 | const want_local_cache = file.mod == mod.main_mod; | 2599 | const want_local_cache = file.mod == mod.main_mod; |
| 2597 | const digest = hash: { | 2600 | const bin_digest = hash: { |
| 2598 | var path_hash: Cache.HashHelper = .{}; | 2601 | var path_hash: Cache.HashHelper = .{}; |
| 2599 | path_hash.addBytes(build_options.version); | 2602 | path_hash.addBytes(build_options.version); |
| 2600 | path_hash.add(builtin.zig_backend); | 2603 | path_hash.add(builtin.zig_backend); |
| ... | @@ -2603,7 +2606,19 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -2603,7 +2606,19 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2603 | path_hash.addBytes(file.mod.root.sub_path); | 2606 | path_hash.addBytes(file.mod.root.sub_path); |
| 2604 | } | 2607 | } |
| 2605 | path_hash.addBytes(file.sub_file_path); | 2608 | path_hash.addBytes(file.sub_file_path); |
| 2606 | break :hash path_hash.final(); | 2609 | var bin: Cache.BinDigest = undefined; |
| 2610 | path_hash.hasher.final(&bin); | ||
| 2611 | break :hash bin; | ||
| 2612 | }; | ||
| 2613 | file.path_digest = bin_digest; | ||
| 2614 | const hex_digest = hex: { | ||
| 2615 | var hex: Cache.HexDigest = undefined; | ||
| 2616 | _ = std.fmt.bufPrint( | ||
| 2617 | &hex, | ||
| 2618 | "{s}", | ||
| 2619 | .{std.fmt.fmtSliceHexLower(&bin_digest)}, | ||
| 2620 | ) catch unreachable; | ||
| 2621 | break :hex hex; | ||
| 2607 | }; | 2622 | }; |
| 2608 | const cache_directory = if (want_local_cache) mod.local_zir_cache else mod.global_zir_cache; | 2623 | const cache_directory = if (want_local_cache) mod.local_zir_cache else mod.global_zir_cache; |
| 2609 | const zir_dir = cache_directory.handle; | 2624 | const zir_dir = cache_directory.handle; |
| ... | @@ -2613,7 +2628,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -2613,7 +2628,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2613 | .never_loaded, .retryable_failure => lock: { | 2628 | .never_loaded, .retryable_failure => lock: { |
| 2614 | // First, load the cached ZIR code, if any. | 2629 | // First, load the cached ZIR code, if any. |
| 2615 | log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{ | 2630 | log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{ |
| 2616 | file.sub_file_path, want_local_cache, &digest, | 2631 | file.sub_file_path, want_local_cache, &hex_digest, |
| 2617 | }); | 2632 | }); |
| 2618 | 2633 | ||
| 2619 | break :lock .shared; | 2634 | break :lock .shared; |
| ... | @@ -2640,7 +2655,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -2640,7 +2655,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2640 | // version. Likewise if we're working on AstGen and another process asks for | 2655 | // version. Likewise if we're working on AstGen and another process asks for |
| 2641 | // the cached file, they'll get it. | 2656 | // the cached file, they'll get it. |
| 2642 | const cache_file = while (true) { | 2657 | const cache_file = while (true) { |
| 2643 | break zir_dir.createFile(&digest, .{ | 2658 | break zir_dir.createFile(&hex_digest, .{ |
| 2644 | .read = true, | 2659 | .read = true, |
| 2645 | .truncate = false, | 2660 | .truncate = false, |
| 2646 | .lock = lock, | 2661 | .lock = lock, |
| ... | @@ -2826,7 +2841,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { | ... | @@ -2826,7 +2841,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2826 | }; | 2841 | }; |
| 2827 | cache_file.writevAll(&iovecs) catch |err| { | 2842 | cache_file.writevAll(&iovecs) catch |err| { |
| 2828 | log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{ | 2843 | log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{ |
| 2829 | file.mod.root, file.sub_file_path, cache_directory, &digest, @errorName(err), | 2844 | file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err), |
| 2830 | }); | 2845 | }); |
| 2831 | }; | 2846 | }; |
| 2832 | 2847 | ||
| ... | @@ -2935,89 +2950,22 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) | ... | @@ -2935,89 +2950,22 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) |
| 2935 | return zir; | 2950 | return zir; |
| 2936 | } | 2951 | } |
| 2937 | 2952 | ||
| 2938 | /// Patch ups: | 2953 | fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir) !void { |
| 2939 | /// * Struct.zir_index | 2954 | const gpa = zcu.gpa; |
| 2940 | /// * Decl.zir_index | ||
| 2941 | /// * Fn.zir_body_inst | ||
| 2942 | /// * Decl.zir_decl_index | ||
| 2943 | fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void { | ||
| 2944 | const gpa = mod.gpa; | ||
| 2945 | const new_zir = file.zir; | ||
| 2946 | |||
| 2947 | // The root decl will be null if the previous ZIR had AST errors. | ||
| 2948 | const root_decl = file.root_decl.unwrap() orelse return; | ||
| 2949 | 2955 | ||
| 2950 | // Maps from old ZIR to new ZIR, declaration, struct_decl, enum_decl, etc. Any instruction which | ||
| 2951 | // creates a namespace, and any `declaration` instruction, gets mapped from old to new here. | ||
| 2952 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{}; | 2956 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{}; |
| 2953 | defer inst_map.deinit(gpa); | 2957 | defer inst_map.deinit(gpa); |
| 2954 | 2958 | ||
| 2955 | try mapOldZirToNew(gpa, old_zir, new_zir, &inst_map); | 2959 | try mapOldZirToNew(gpa, old_zir, file.zir, &inst_map); |
| 2956 | |||
| 2957 | // Walk the Decl graph, updating ZIR indexes, strings, and populating | ||
| 2958 | // the deleted and outdated lists. | ||
| 2959 | |||
| 2960 | var decl_stack: ArrayListUnmanaged(Decl.Index) = .{}; | ||
| 2961 | defer decl_stack.deinit(gpa); | ||
| 2962 | |||
| 2963 | try decl_stack.append(gpa, root_decl); | ||
| 2964 | |||
| 2965 | file.deleted_decls.clearRetainingCapacity(); | ||
| 2966 | file.outdated_decls.clearRetainingCapacity(); | ||
| 2967 | |||
| 2968 | // The root decl is always outdated; otherwise we would not have had | ||
| 2969 | // to re-generate ZIR for the File. | ||
| 2970 | try file.outdated_decls.append(gpa, root_decl); | ||
| 2971 | |||
| 2972 | const ip = &mod.intern_pool; | ||
| 2973 | |||
| 2974 | while (decl_stack.popOrNull()) |decl_index| { | ||
| 2975 | const decl = mod.declPtr(decl_index); | ||
| 2976 | // Anonymous decls and the root decl have this set to 0. We still need | ||
| 2977 | // to walk them but we do not need to modify this value. | ||
| 2978 | // Anonymous decls should not be marked outdated. They will be re-generated | ||
| 2979 | // if their owner decl is marked outdated. | ||
| 2980 | if (decl.zir_decl_index.unwrap()) |old_zir_decl_index| { | ||
| 2981 | const new_zir_decl_index = inst_map.get(old_zir_decl_index) orelse { | ||
| 2982 | try file.deleted_decls.append(gpa, decl_index); | ||
| 2983 | continue; | ||
| 2984 | }; | ||
| 2985 | const old_hash = decl.contentsHashZir(old_zir); | ||
| 2986 | decl.zir_decl_index = new_zir_decl_index.toOptional(); | ||
| 2987 | const new_hash = decl.contentsHashZir(new_zir); | ||
| 2988 | if (!std.zig.srcHashEql(old_hash, new_hash)) { | ||
| 2989 | try file.outdated_decls.append(gpa, decl_index); | ||
| 2990 | } | ||
| 2991 | } | ||
| 2992 | 2960 | ||
| 2993 | if (!decl.owns_tv) continue; | 2961 | // TODO: this should be done after all AstGen workers complete, to avoid |
| 2994 | 2962 | // iterating over this full set for every updated file. | |
| 2995 | if (decl.getOwnedStruct(mod)) |struct_type| { | 2963 | for (zcu.intern_pool.tracked_insts.keys()) |*ti| { |
| 2996 | struct_type.setZirIndex(ip, inst_map.get(struct_type.zir_index) orelse { | 2964 | if (!std.mem.eql(u8, &ti.path_digest, &file.path_digest)) continue; |
| 2997 | try file.deleted_decls.append(gpa, decl_index); | 2965 | ti.inst = inst_map.get(ti.inst) orelse { |
| 2998 | continue; | 2966 | // TODO: invalidate this `TrackedInst` via the dependency mechanism |
| 2999 | }); | 2967 | continue; |
| 3000 | } | 2968 | }; |
| 3001 | |||
| 3002 | if (decl.getOwnedUnion(mod)) |union_type| { | ||
| 3003 | union_type.setZirIndex(ip, inst_map.get(union_type.zir_index) orelse { | ||
| 3004 | try file.deleted_decls.append(gpa, decl_index); | ||
| 3005 | continue; | ||
| 3006 | }); | ||
| 3007 | } | ||
| 3008 | |||
| 3009 | if (decl.getOwnedFunction(mod)) |func| { | ||
| 3010 | func.zirBodyInst(ip).* = inst_map.get(func.zir_body_inst) orelse { | ||
| 3011 | try file.deleted_decls.append(gpa, decl_index); | ||
| 3012 | continue; | ||
| 3013 | }; | ||
| 3014 | } | ||
| 3015 | |||
| 3016 | if (decl.getOwnedInnerNamespace(mod)) |namespace| { | ||
| 3017 | for (namespace.decls.keys()) |sub_decl| { | ||
| 3018 | try decl_stack.append(gpa, sub_decl); | ||
| 3019 | } | ||
| 3020 | } | ||
| 3021 | } | 2969 | } |
| 3022 | } | 2970 | } |
| 3023 | 2971 | ||
| ... | @@ -3494,7 +3442,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { | ... | @@ -3494,7 +3442,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { |
| 3494 | const struct_ty = sema.getStructType( | 3442 | const struct_ty = sema.getStructType( |
| 3495 | new_decl_index, | 3443 | new_decl_index, |
| 3496 | new_namespace_index, | 3444 | new_namespace_index, |
| 3497 | .main_struct_inst, | 3445 | try mod.intern_pool.trackZir(gpa, file, .main_struct_inst), |
| 3498 | ) catch |err| switch (err) { | 3446 | ) catch |err| switch (err) { |
| 3499 | error.OutOfMemory => return error.OutOfMemory, | 3447 | error.OutOfMemory => return error.OutOfMemory, |
| 3500 | }; | 3448 | }; |
| ... | @@ -4472,7 +4420,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato | ... | @@ -4472,7 +4420,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato |
| 4472 | }; | 4420 | }; |
| 4473 | defer inner_block.instructions.deinit(gpa); | 4421 | defer inner_block.instructions.deinit(gpa); |
| 4474 | 4422 | ||
| 4475 | const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).*); | 4423 | const fn_info = sema.code.getFnInfo(func.zirBodyInst(ip).resolve(ip)); |
| 4476 | 4424 | ||
| 4477 | // Here we are performing "runtime semantic analysis" for a function body, which means | 4425 | // Here we are performing "runtime semantic analysis" for a function body, which means |
| 4478 | // we must map the parameter ZIR instructions to `arg` AIR instructions. | 4426 | // 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] | ... | @@ -6125,7 +6073,7 @@ pub fn getParamName(mod: *Module, func_index: InternPool.Index, index: u32) [:0] |
| 6125 | const tags = file.zir.instructions.items(.tag); | 6073 | const tags = file.zir.instructions.items(.tag); |
| 6126 | const data = file.zir.instructions.items(.data); | 6074 | const data = file.zir.instructions.items(.data); |
| 6127 | 6075 | ||
| 6128 | const param_body = file.zir.getParamBody(func.zir_body_inst); | 6076 | const param_body = file.zir.getParamBody(func.zir_body_inst.resolve(&mod.intern_pool)); |
| 6129 | const param = param_body[index]; | 6077 | const param = param_body[index]; |
| 6130 | 6078 | ||
| 6131 | return switch (tags[@intFromEnum(param)]) { | 6079 | return switch (tags[@intFromEnum(param)]) { |
src/Sema.zig+21-17| ... | @@ -2708,11 +2708,12 @@ pub fn getStructType( | ... | @@ -2708,11 +2708,12 @@ pub fn getStructType( |
| 2708 | sema: *Sema, | 2708 | sema: *Sema, |
| 2709 | decl: InternPool.DeclIndex, | 2709 | decl: InternPool.DeclIndex, |
| 2710 | namespace: InternPool.NamespaceIndex, | 2710 | namespace: InternPool.NamespaceIndex, |
| 2711 | zir_index: Zir.Inst.Index, | 2711 | tracked_inst: InternPool.TrackedInst.Index, |
| 2712 | ) !InternPool.Index { | 2712 | ) !InternPool.Index { |
| 2713 | const mod = sema.mod; | 2713 | const mod = sema.mod; |
| 2714 | const gpa = sema.gpa; | 2714 | const gpa = sema.gpa; |
| 2715 | const ip = &mod.intern_pool; | 2715 | const ip = &mod.intern_pool; |
| 2716 | const zir_index = tracked_inst.resolve(ip); | ||
| 2716 | const extended = sema.code.instructions.items(.data)[@intFromEnum(zir_index)].extended; | 2717 | const extended = sema.code.instructions.items(.data)[@intFromEnum(zir_index)].extended; |
| 2717 | assert(extended.opcode == .struct_decl); | 2718 | assert(extended.opcode == .struct_decl); |
| 2718 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | 2719 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); |
| ... | @@ -2747,7 +2748,7 @@ pub fn getStructType( | ... | @@ -2747,7 +2748,7 @@ pub fn getStructType( |
| 2747 | const ty = try ip.getStructType(gpa, .{ | 2748 | const ty = try ip.getStructType(gpa, .{ |
| 2748 | .decl = decl, | 2749 | .decl = decl, |
| 2749 | .namespace = namespace.toOptional(), | 2750 | .namespace = namespace.toOptional(), |
| 2750 | .zir_index = zir_index, | 2751 | .zir_index = tracked_inst, |
| 2751 | .layout = small.layout, | 2752 | .layout = small.layout, |
| 2752 | .known_non_opv = small.known_non_opv, | 2753 | .known_non_opv = small.known_non_opv, |
| 2753 | .is_tuple = small.is_tuple, | 2754 | .is_tuple = small.is_tuple, |
| ... | @@ -2797,7 +2798,8 @@ fn zirStructDecl( | ... | @@ -2797,7 +2798,8 @@ fn zirStructDecl( |
| 2797 | errdefer mod.destroyNamespace(new_namespace_index); | 2798 | errdefer mod.destroyNamespace(new_namespace_index); |
| 2798 | 2799 | ||
| 2799 | const struct_ty = ty: { | 2800 | const struct_ty = ty: { |
| 2800 | const ty = try sema.getStructType(new_decl_index, new_namespace_index, inst); | 2801 | const tracked_inst = try ip.trackZir(mod.gpa, block.getFileScope(mod), inst); |
| 2802 | const ty = try sema.getStructType(new_decl_index, new_namespace_index, tracked_inst); | ||
| 2801 | if (sema.builtin_type_target_index != .none) { | 2803 | if (sema.builtin_type_target_index != .none) { |
| 2802 | ip.resolveBuiltinType(sema.builtin_type_target_index, ty); | 2804 | ip.resolveBuiltinType(sema.builtin_type_target_index, ty); |
| 2803 | break :ty sema.builtin_type_target_index; | 2805 | break :ty sema.builtin_type_target_index; |
| ... | @@ -2856,7 +2858,7 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2856,7 +2858,7 @@ fn createAnonymousDeclTypeNamed( |
| 2856 | return new_decl_index; | 2858 | return new_decl_index; |
| 2857 | }, | 2859 | }, |
| 2858 | .func => { | 2860 | .func => { |
| 2859 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index)); | 2861 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip)); |
| 2860 | const zir_tags = sema.code.instructions.items(.tag); | 2862 | const zir_tags = sema.code.instructions.items(.tag); |
| 2861 | 2863 | ||
| 2862 | var buf = std.ArrayList(u8).init(gpa); | 2864 | var buf = std.ArrayList(u8).init(gpa); |
| ... | @@ -3252,7 +3254,7 @@ fn zirUnionDecl( | ... | @@ -3252,7 +3254,7 @@ fn zirUnionDecl( |
| 3252 | }, | 3254 | }, |
| 3253 | .decl = new_decl_index, | 3255 | .decl = new_decl_index, |
| 3254 | .namespace = new_namespace_index, | 3256 | .namespace = new_namespace_index, |
| 3255 | .zir_index = inst, | 3257 | .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst), |
| 3256 | .fields_len = fields_len, | 3258 | .fields_len = fields_len, |
| 3257 | .enum_tag_ty = .none, | 3259 | .enum_tag_ty = .none, |
| 3258 | .field_types = &.{}, | 3260 | .field_types = &.{}, |
| ... | @@ -7446,7 +7448,7 @@ fn analyzeCall( | ... | @@ -7446,7 +7448,7 @@ fn analyzeCall( |
| 7446 | // the AIR instructions of the callsite. The callee could be a generic function | 7448 | // the AIR instructions of the callsite. The callee could be a generic function |
| 7447 | // which means its parameter type expressions must be resolved in order and used | 7449 | // which means its parameter type expressions must be resolved in order and used |
| 7448 | // to successively coerce the arguments. | 7450 | // to successively coerce the arguments. |
| 7449 | const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst); | 7451 | const fn_info = ics.callee().code.getFnInfo(module_fn.zir_body_inst.resolve(ip)); |
| 7450 | try ics.callee().inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body); | 7452 | try ics.callee().inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body); |
| 7451 | 7453 | ||
| 7452 | var arg_i: u32 = 0; | 7454 | var arg_i: u32 = 0; |
| ... | @@ -7494,7 +7496,7 @@ fn analyzeCall( | ... | @@ -7494,7 +7496,7 @@ fn analyzeCall( |
| 7494 | // each of the parameters, resolving the return type and providing it to the child | 7496 | // each of the parameters, resolving the return type and providing it to the child |
| 7495 | // `Sema` so that it can be used for the `ret_ptr` instruction. | 7497 | // `Sema` so that it can be used for the `ret_ptr` instruction. |
| 7496 | const ret_ty_inst = if (fn_info.ret_ty_body.len != 0) | 7498 | const ret_ty_inst = if (fn_info.ret_ty_body.len != 0) |
| 7497 | try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst) | 7499 | try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip)) |
| 7498 | else | 7500 | else |
| 7499 | try sema.resolveInst(fn_info.ret_ty_ref); | 7501 | try sema.resolveInst(fn_info.ret_ty_ref); |
| 7500 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; | 7502 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| ... | @@ -7885,7 +7887,7 @@ fn instantiateGenericCall( | ... | @@ -7885,7 +7887,7 @@ fn instantiateGenericCall( |
| 7885 | const namespace_index = fn_owner_decl.src_namespace; | 7887 | const namespace_index = fn_owner_decl.src_namespace; |
| 7886 | const namespace = mod.namespacePtr(namespace_index); | 7888 | const namespace = mod.namespacePtr(namespace_index); |
| 7887 | const fn_zir = namespace.file_scope.zir; | 7889 | const fn_zir = namespace.file_scope.zir; |
| 7888 | const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst); | 7890 | const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip)); |
| 7889 | 7891 | ||
| 7890 | const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count()); | 7892 | const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count()); |
| 7891 | @memset(comptime_args, .none); | 7893 | @memset(comptime_args, .none); |
| ... | @@ -9467,7 +9469,7 @@ fn funcCommon( | ... | @@ -9467,7 +9469,7 @@ fn funcCommon( |
| 9467 | .is_generic = final_is_generic, | 9469 | .is_generic = final_is_generic, |
| 9468 | .is_noinline = is_noinline, | 9470 | .is_noinline = is_noinline, |
| 9469 | 9471 | ||
| 9470 | .zir_body_inst = func_inst, | 9472 | .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst), |
| 9471 | .lbrace_line = src_locs.lbrace_line, | 9473 | .lbrace_line = src_locs.lbrace_line, |
| 9472 | .rbrace_line = src_locs.rbrace_line, | 9474 | .rbrace_line = src_locs.rbrace_line, |
| 9473 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), | 9475 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| ... | @@ -9545,7 +9547,7 @@ fn funcCommon( | ... | @@ -9545,7 +9547,7 @@ fn funcCommon( |
| 9545 | .ty = func_ty, | 9547 | .ty = func_ty, |
| 9546 | .cc = cc, | 9548 | .cc = cc, |
| 9547 | .is_noinline = is_noinline, | 9549 | .is_noinline = is_noinline, |
| 9548 | .zir_body_inst = func_inst, | 9550 | .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst), |
| 9549 | .lbrace_line = src_locs.lbrace_line, | 9551 | .lbrace_line = src_locs.lbrace_line, |
| 9550 | .rbrace_line = src_locs.rbrace_line, | 9552 | .rbrace_line = src_locs.rbrace_line, |
| 9551 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), | 9553 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| ... | @@ -21553,7 +21555,7 @@ fn zirReify( | ... | @@ -21553,7 +21555,7 @@ fn zirReify( |
| 21553 | .namespace = new_namespace_index, | 21555 | .namespace = new_namespace_index, |
| 21554 | .enum_tag_ty = enum_tag_ty, | 21556 | .enum_tag_ty = enum_tag_ty, |
| 21555 | .fields_len = fields_len, | 21557 | .fields_len = fields_len, |
| 21556 | .zir_index = inst, | 21558 | .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently? |
| 21557 | .flags = .{ | 21559 | .flags = .{ |
| 21558 | .layout = layout, | 21560 | .layout = layout, |
| 21559 | .status = .have_field_types, | 21561 | .status = .have_field_types, |
| ... | @@ -21721,7 +21723,7 @@ fn reifyStruct( | ... | @@ -21721,7 +21723,7 @@ fn reifyStruct( |
| 21721 | const ty = try ip.getStructType(gpa, .{ | 21723 | const ty = try ip.getStructType(gpa, .{ |
| 21722 | .decl = new_decl_index, | 21724 | .decl = new_decl_index, |
| 21723 | .namespace = .none, | 21725 | .namespace = .none, |
| 21724 | .zir_index = inst, | 21726 | .zir_index = try mod.intern_pool.trackZir(gpa, block.getFileScope(mod), inst), // TODO: should reified types be handled differently? |
| 21725 | .layout = layout, | 21727 | .layout = layout, |
| 21726 | .known_non_opv = false, | 21728 | .known_non_opv = false, |
| 21727 | .fields_len = fields_len, | 21729 | .fields_len = fields_len, |
| ... | @@ -35593,7 +35595,8 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp | ... | @@ -35593,7 +35595,8 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp |
| 35593 | break :blk accumulator; | 35595 | break :blk accumulator; |
| 35594 | }; | 35596 | }; |
| 35595 | 35597 | ||
| 35596 | const extended = zir.instructions.items(.data)[@intFromEnum(struct_type.zir_index)].extended; | 35598 | const zir_index = struct_type.zir_index.resolve(ip); |
| 35599 | const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; | ||
| 35597 | assert(extended.opcode == .struct_decl); | 35600 | assert(extended.opcode == .struct_decl); |
| 35598 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); | 35601 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); |
| 35599 | 35602 | ||
| ... | @@ -35613,7 +35616,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp | ... | @@ -35613,7 +35616,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp |
| 35613 | break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref); | 35616 | break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref); |
| 35614 | } else { | 35617 | } else { |
| 35615 | const body = zir.bodySlice(extra_index, backing_int_body_len); | 35618 | const body = zir.bodySlice(extra_index, backing_int_body_len); |
| 35616 | const ty_ref = try sema.resolveBody(&block, body, struct_type.zir_index); | 35619 | const ty_ref = try sema.resolveBody(&block, body, zir_index); |
| 35617 | break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref); | 35620 | break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref); |
| 35618 | } | 35621 | } |
| 35619 | }; | 35622 | }; |
| ... | @@ -36357,7 +36360,7 @@ fn semaStructFields( | ... | @@ -36357,7 +36360,7 @@ fn semaStructFields( |
| 36357 | const decl = mod.declPtr(decl_index); | 36360 | const decl = mod.declPtr(decl_index); |
| 36358 | const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; | 36361 | const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; |
| 36359 | const zir = mod.namespacePtr(namespace_index).file_scope.zir; | 36362 | const zir = mod.namespacePtr(namespace_index).file_scope.zir; |
| 36360 | const zir_index = struct_type.zir_index; | 36363 | const zir_index = struct_type.zir_index.resolve(ip); |
| 36361 | 36364 | ||
| 36362 | const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); | 36365 | const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); |
| 36363 | 36366 | ||
| ... | @@ -36628,7 +36631,7 @@ fn semaStructFieldInits( | ... | @@ -36628,7 +36631,7 @@ fn semaStructFieldInits( |
| 36628 | const decl = mod.declPtr(decl_index); | 36631 | const decl = mod.declPtr(decl_index); |
| 36629 | const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; | 36632 | const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; |
| 36630 | const zir = mod.namespacePtr(namespace_index).file_scope.zir; | 36633 | const zir = mod.namespacePtr(namespace_index).file_scope.zir; |
| 36631 | const zir_index = struct_type.zir_index; | 36634 | const zir_index = struct_type.zir_index.resolve(ip); |
| 36632 | const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); | 36635 | const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); |
| 36633 | 36636 | ||
| 36634 | var comptime_mutable_decls = std.ArrayList(InternPool.DeclIndex).init(gpa); | 36637 | 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 | ... | @@ -36777,7 +36780,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un |
| 36777 | const ip = &mod.intern_pool; | 36780 | const ip = &mod.intern_pool; |
| 36778 | const decl_index = union_type.decl; | 36781 | const decl_index = union_type.decl; |
| 36779 | const zir = mod.namespacePtr(union_type.namespace).file_scope.zir; | 36782 | const zir = mod.namespacePtr(union_type.namespace).file_scope.zir; |
| 36780 | const extended = zir.instructions.items(.data)[@intFromEnum(union_type.zir_index)].extended; | 36783 | const zir_index = union_type.zir_index.resolve(ip); |
| 36784 | const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; | ||
| 36781 | assert(extended.opcode == .union_decl); | 36785 | assert(extended.opcode == .union_decl); |
| 36782 | const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); | 36786 | const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); |
| 36783 | var extra_index: usize = extended.operand; | 36787 | var extra_index: usize = extended.operand; |