authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-11 05:41:28-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 11:00:55-04:00
loge761d5200a0888e4c56e04a725979c70de457e71
tree23713636a7a766d1a5a0c4624f21c90e350cce67
parent0bf3e08c705ec460c71d3b2261acb0b87aacd066

link: fix `@tagName` incremental bug


22 files changed, 299 insertions(+), 246 deletions(-)

src/Compilation.zig+4-4
...@@ -2829,6 +2829,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -2829,6 +2829,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
2829 }2829 }
28302830
2831 const is_hit = man.hit(main_progress_node) catch |err| switch (err) {2831 const is_hit = man.hit(main_progress_node) catch |err| switch (err) {
2832 error.Canceled, error.OutOfMemory => |e| return e,
2832 error.CacheCheckFailed => switch (man.diagnostic) {2833 error.CacheCheckFailed => switch (man.diagnostic) {
2833 .none => unreachable,2834 .none => unreachable,
2834 .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure(2835 .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure(
...@@ -2844,7 +2845,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -2844,7 +2845,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
2844 });2845 });
2845 },2846 },
2846 },2847 },
2847 error.OutOfMemory, error.Canceled => |e| return e,
2848 error.InvalidFormat => return comp.setMiscFailure(2848 error.InvalidFormat => return comp.setMiscFailure(
2849 .check_whole_cache,2849 .check_whole_cache,
2850 "failed to check cache: invalid manifest file format",2850 "failed to check cache: invalid manifest file format",
...@@ -3283,8 +3283,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error...@@ -3283,8 +3283,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error
3283 .fuzz = comp.config.any_fuzz,3283 .fuzz = comp.config.any_fuzz,
3284 .lto = comp.config.lto,3284 .lto = comp.config.lto,
3285 }) catch |err| switch (err) {3285 }) catch |err| switch (err) {
3286 error.Canceled, error.OutOfMemory => |e| return e,
3286 error.AlreadyReported => {},3287 error.AlreadyReported => {},
3287 error.OutOfMemory => |e| return e,
3288 };3288 };
32893289
3290 if (zcu_obj_path) |path| {3290 if (zcu_obj_path) |path| {
...@@ -3293,8 +3293,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error...@@ -3293,8 +3293,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error
3293 // `link.Queue` has not called `prelink` because it knew we would want to send that3293 // `link.Queue` has not called `prelink` because it knew we would want to send that
3294 // final link input. It is *our* responsibility to call `prelink` now we're done.3294 // final link input. It is *our* responsibility to call `prelink` now we're done.
3295 comp.bin_file.?.prelink() catch |err| switch (err) {3295 comp.bin_file.?.prelink() catch |err| switch (err) {
3296 error.Canceled, error.OutOfMemory => |e| return e,
3296 error.AlreadyReported => return,3297 error.AlreadyReported => return,
3297 else => |e| return e,
3298 };3298 };
3299 }3299 }
3300 }3300 }
...@@ -3308,8 +3308,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error...@@ -3308,8 +3308,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error
3308 };3308 };
3309 // This is needed before reading the error flags.3309 // This is needed before reading the error flags.
3310 lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) {3310 lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) {
3311 error.Canceled, error.OutOfMemory => |e| return e,
3311 error.AlreadyReported => return,3312 error.AlreadyReported => return,
3312 error.OutOfMemory, error.Canceled => |e| return e,
3313 };3313 };
3314 }3314 }
3315}3315}
src/Zcu.zig+1-1
...@@ -4707,7 +4707,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)...@@ -4707,7 +4707,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
4707 return .ok;4707 return .ok;
4708}4708}
47094709
4710pub const CodegenFailError = error{4710pub const CodegenFailError = Io.Cancelable || error{
4711 /// Indicates the error message has been already stored at `Zcu.failed_codegen`.4711 /// Indicates the error message has been already stored at `Zcu.failed_codegen`.
4712 AlreadyReported,4712 AlreadyReported,
4713 OutOfMemory,4713 OutOfMemory,
src/codegen/aarch64/Select.zig+5-5
...@@ -896,7 +896,7 @@ pub fn finishAnalysis(isel: *Select) !void {...@@ -896,7 +896,7 @@ pub fn finishAnalysis(isel: *Select) !void {
896 }896 }
897}897}
898898
899pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, AlreadyReported }!void {899pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void {
900 const zcu = isel.pt.zcu;900 const zcu = isel.pt.zcu;
901 const ip = &zcu.intern_pool;901 const ip = &zcu.intern_pool;
902 const gpa = zcu.gpa;902 const gpa = zcu.gpa;
...@@ -8024,7 +8024,7 @@ fn emitLiteral(isel: *Select, bytes: []const u8) !void {...@@ -8024,7 +8024,7 @@ fn emitLiteral(isel: *Select, bytes: []const u8) !void {
8024 }8024 }
8025}8025}
80268026
8027fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {8027fn fail(isel: *Select, comptime format: []const u8, args: anytype) codegen.Error {
8028 @branchHint(.cold);8028 @branchHint(.cold);
8029 return isel.pt.zcu.codegenFail(isel.nav_index, format, args);8029 return isel.pt.zcu.codegenFail(isel.nav_index, format, args);
8030}8030}
...@@ -10618,7 +10618,7 @@ pub const Value = struct {...@@ -10618,7 +10618,7 @@ pub const Value = struct {
10618 vi: Value.Index,10618 vi: Value.Index,
10619 ra: Register.Alias,10619 ra: Register.Alias,
1062010620
10621 fn finish(mat: Value.Materialize, isel: *Select) error{ OutOfMemory, AlreadyReported }!void {10621 fn finish(mat: Value.Materialize, isel: *Select) codegen.Error!void {
10622 const live_vi = isel.live_registers.getPtr(mat.ra);10622 const live_vi = isel.live_registers.getPtr(mat.ra);
10623 assert(live_vi.* == .allocating);10623 assert(live_vi.* == .allocating);
10624 var vi = mat.vi;10624 var vi = mat.vi;
...@@ -11659,7 +11659,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index {...@@ -11659,7 +11659,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index {
11659 return vi;11659 return vi;
11660}11660}
1166111661
11662fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool {11662fn fill(isel: *Select, dst_ra: Register.Alias) codegen.Error!bool {
11663 switch (dst_ra) {11663 switch (dst_ra) {
11664 else => {},11664 else => {},
11665 Register.Alias.fp, .zr, .sp, .pc, .fpcr, .fpsr, .ffr => return false,11665 Register.Alias.fp, .zr, .sp, .pc, .fpcr, .fpsr, .ffr => return false,
...@@ -11692,7 +11692,7 @@ fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReport...@@ -11692,7 +11692,7 @@ fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReport
11692 return true;11692 return true;
11693}11693}
1169411694
11695fn fillMemory(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool {11695fn fillMemory(isel: *Select, dst_ra: Register.Alias) codegen.Error!bool {
11696 const dst_live_vi = isel.live_registers.getPtr(dst_ra);11696 const dst_live_vi = isel.live_registers.getPtr(dst_ra);
11697 const dst_vi = switch (dst_live_vi.*) {11697 const dst_vi = switch (dst_live_vi.*) {
11698 _ => |dst_vi| dst_vi,11698 _ => |dst_vi| dst_vi,
src/codegen/c.zig+3-2
...@@ -6,6 +6,7 @@ const log = std.log.scoped(.c);...@@ -6,6 +6,7 @@ const log = std.log.scoped(.c);
6const Allocator = mem.Allocator;6const Allocator = mem.Allocator;
7const Writer = std.Io.Writer;7const Writer = std.Io.Writer;
88
9const codegen = @import("../codegen.zig");
9const dev = @import("../dev.zig");10const dev = @import("../dev.zig");
10const link = @import("../link.zig");11const link = @import("../link.zig");
11const Zcu = @import("../Zcu.zig");12const Zcu = @import("../Zcu.zig");
...@@ -86,7 +87,7 @@ pub const Mir = struct {...@@ -86,7 +87,7 @@ pub const Mir = struct {
86 }87 }
87};88};
8889
89pub const Error = Writer.Error || Allocator.Error || error{AlreadyReported};90pub const Error = codegen.Error || Writer.Error;
9091
91pub const CType = @import("c/type.zig").CType;92pub const CType = @import("c/type.zig").CType;
9293
...@@ -2251,7 +2252,7 @@ pub fn generate(...@@ -2251,7 +2252,7 @@ pub fn generate(
2251 func_index: InternPool.Index,2252 func_index: InternPool.Index,
2252 air: *const Air,2253 air: *const Air,
2253 liveness: *const ?Air.Liveness,2254 liveness: *const ?Air.Liveness,
2254) @import("../codegen.zig").Error!Mir {2255) codegen.Error!Mir {
2255 const zcu = pt.zcu;2256 const zcu = pt.zcu;
2256 const gpa = zcu.gpa;2257 const gpa = zcu.gpa;
22572258
src/codegen/llvm.zig+3-3
...@@ -348,7 +348,7 @@ pub const Object = struct {...@@ -348,7 +348,7 @@ pub const Object = struct {
348 lto: std.zig.LtoMode,348 lto: std.zig.LtoMode,
349 };349 };
350350
351 pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ AlreadyReported, OutOfMemory }!void {351 pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) link.Error!void {
352 const zcu = o.zcu;352 const zcu = o.zcu;
353 const comp = zcu.comp;353 const comp = zcu.comp;
354 const io = comp.io;354 const io = comp.io;
...@@ -1141,7 +1141,7 @@ pub const Object = struct {...@@ -1141,7 +1141,7 @@ pub const Object = struct {
1141 }1141 }
1142 }1142 }
11431143
1144 fn flushTypePool(o: *Object, pt: Zcu.PerThread) Allocator.Error!void {1144 fn flushTypePool(o: *Object, pt: Zcu.PerThread) link.Error!void {
1145 try o.type_pool.flushPending(pt, .{ .llvm = o });1145 try o.type_pool.flushPending(pt, .{ .llvm = o });
1146 }1146 }
11471147
...@@ -1304,7 +1304,7 @@ pub const Object = struct {...@@ -1304,7 +1304,7 @@ pub const Object = struct {
1304 }, &o.builder);1304 }, &o.builder);
1305 }1305 }
13061306
1307 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void {1307 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) link.Error!void {
1308 _ = o.type_map.remove(ty);1308 _ = o.type_map.remove(ty);
1309 try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success);1309 try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success);
1310 if (o.named_enum_map.get(ty)) |llvm_function| {1310 if (o.named_enum_map.get(ty)) |llvm_function| {
src/codegen/loongarch/Mir.zig+1-1
...@@ -115,7 +115,7 @@ pub fn emit(...@@ -115,7 +115,7 @@ pub fn emit(
115 @fromBackingInt(ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|115 @fromBackingInt(ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
116 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)}))116 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)}))
117 else if (lf.cast(.elf2)) |elf|117 else if (lf.cast(.elf2)) |elf|
118 elf.lazySymbol(lazy_reloc.symbol) catch |err|118 elf.lazySymbol(pt, lazy_reloc.symbol) catch |err|
119 return zcu.codegenFail(func.owner_nav, "emit lazy symbol: {t}", .{err})119 return zcu.codegenFail(func.owner_nav, "emit lazy symbol: {t}", .{err})
120 else120 else
121 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),121 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
src/codegen/riscv64/CodeGen.zig+2-2
...@@ -8349,7 +8349,7 @@ fn wantSafety(func: *Func) bool {...@@ -8349,7 +8349,7 @@ fn wantSafety(func: *Func) bool {
8349 };8349 };
8350}8350}
83518351
8352fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {8352fn fail(func: *const Func, comptime format: []const u8, args: anytype) codegen.Error {
8353 @branchHint(.cold);8353 @branchHint(.cold);
8354 const zcu = func.pt.zcu;8354 const zcu = func.pt.zcu;
8355 switch (func.owner) {8355 switch (func.owner) {
...@@ -8359,7 +8359,7 @@ fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ Ou...@@ -8359,7 +8359,7 @@ fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ Ou
8359 return error.AlreadyReported;8359 return error.AlreadyReported;
8360}8360}
83618361
8362fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } {8362fn failMsg(func: *const Func, msg: *ErrorMsg) codegen.Error {
8363 @branchHint(.cold);8363 @branchHint(.cold);
8364 const zcu = func.pt.zcu;8364 const zcu = func.pt.zcu;
8365 switch (func.owner) {8365 switch (func.owner) {
src/codegen/sparc64/CodeGen.zig+2-2
...@@ -3450,7 +3450,7 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)...@@ -3450,7 +3450,7 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
3450 }3450 }
3451}3451}
34523452
3453fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {3453fn fail(self: *Self, comptime format: []const u8, args: anytype) codegen.Error {
3454 @branchHint(.cold);3454 @branchHint(.cold);
3455 const zcu = self.pt.zcu;3455 const zcu = self.pt.zcu;
3456 const func = zcu.funcInfo(self.func_index);3456 const func = zcu.funcInfo(self.func_index);
...@@ -3458,7 +3458,7 @@ fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMem...@@ -3458,7 +3458,7 @@ fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMem
3458 return zcu.codegenFailMsg(func.owner_nav, msg);3458 return zcu.codegenFailMsg(func.owner_nav, msg);
3459}3459}
34603460
3461fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } {3461fn failMsg(self: *Self, msg: *ErrorMsg) codegen.Error {
3462 @branchHint(.cold);3462 @branchHint(.cold);
3463 const zcu = self.pt.zcu;3463 const zcu = self.pt.zcu;
3464 const func = zcu.funcInfo(self.func_index);3464 const func = zcu.funcInfo(self.func_index);
src/codegen/spirv/CodeGen.zig+3-9
...@@ -240,10 +240,7 @@ pub fn generate(...@@ -240,10 +240,7 @@ pub fn generate(
240 };240 };
241 defer cg.deinit();241 defer cg.deinit();
242242
243 cg.genNav(true) catch |err| switch (err) {243 try cg.genNav(true);
244 error.AlreadyReported => return error.AlreadyReported,
245 error.OutOfMemory => return error.OutOfMemory,
246 };
247244
248 return cg.serializeToMir(gpa);245 return cg.serializeToMir(gpa);
249}246}
...@@ -270,10 +267,7 @@ pub fn generateNav(...@@ -270,10 +267,7 @@ pub fn generateNav(
270 };267 };
271 defer cg.deinit();268 defer cg.deinit();
272269
273 cg.genNav(false) catch |err| switch (err) {270 try cg.genNav(false);
274 error.AlreadyReported => return error.AlreadyReported,
275 error.OutOfMemory => return error.OutOfMemory,
276 };
277271
278 return cg.serializeToMir(gpa);272 return cg.serializeToMir(gpa);
279}273}
...@@ -854,7 +848,7 @@ pub fn storageClass(cg: *const CodeGen, as: std.lang.AddressSpace) spec.StorageC...@@ -854,7 +848,7 @@ pub fn storageClass(cg: *const CodeGen, as: std.lang.AddressSpace) spec.StorageC
854 };848 };
855}849}
856850
857const Error = error{ AlreadyReported, OutOfMemory };851const Error = codegen.Error;
858852
859pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {853pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
860 const gpa = cg.gpa;854 const gpa = cg.gpa;
src/codegen/spork8/CodeGen.zig+15-27
...@@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;...@@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
4const assert = std.debug.assert;4const assert = std.debug.assert;
55
6const CodeGen = @This();6const CodeGen = @This();
7const codegen = @import("../../codegen.zig");
7const link = @import("../../link.zig");8const link = @import("../../link.zig");
8const Spork8 = link.File.Spork8;9const Spork8 = link.File.Spork8;
9const Zcu = @import("../../Zcu.zig");10const Zcu = @import("../../Zcu.zig");
...@@ -133,37 +134,20 @@ pub fn generate(...@@ -133,37 +134,20 @@ pub fn generate(
133 _ = bin_file;134 _ = bin_file;
134 const zcu = pt.zcu;135 const zcu = pt.zcu;
135 const gpa = zcu.gpa;136 const gpa = zcu.gpa;
136 const cg = zcu.funcInfo(func_index);137 const func = zcu.funcInfo(func_index);
137138
138 var code_gen: CodeGen = .{139 var cg: CodeGen = .{
139 .gpa = gpa,140 .gpa = gpa,
140 .pt = pt,141 .pt = pt,
141 .air = air.*,142 .air = air.*,
142 .liveness = liveness.*.?,143 .liveness = liveness.*.?,
143 .owner_nav = cg.owner_nav,144 .owner_nav = func.owner_nav,
144 .func_index = func_index,145 .func_index = func_index,
145 .mir_instructions = .empty,146 .mir_instructions = .empty,
146 .mir_extra = .empty,147 .mir_extra = .empty,
147 };148 };
148 defer code_gen.deinit();149 defer cg.deinit();
149150
150 return generateInner(&code_gen) catch |err| switch (err) {
151 error.AlreadyReported,
152 error.OutOfMemory,
153 => |e| return e,
154 };
155}
156
157pub fn deinit(cg: *CodeGen) void {
158 cg.* = undefined;
159}
160
161const InnerError = error{
162 AlreadyReported,
163 OutOfMemory,
164};
165
166fn generateInner(cg: *CodeGen) InnerError!Mir {
167 // Generate MIR for function body151 // Generate MIR for function body
168 try cg.genBody(cg.air.getMainBody());152 try cg.genBody(cg.air.getMainBody());
169153
...@@ -175,7 +159,11 @@ fn generateInner(cg: *CodeGen) InnerError!Mir {...@@ -175,7 +159,11 @@ fn generateInner(cg: *CodeGen) InnerError!Mir {
175 };159 };
176}160}
177161
178fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {162pub fn deinit(cg: *CodeGen) void {
163 cg.* = undefined;
164}
165
166fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) codegen.Error!void {
179 const zcu = cg.pt.zcu;167 const zcu = cg.pt.zcu;
180 const ip = &zcu.intern_pool;168 const ip = &zcu.intern_pool;
181169
...@@ -185,7 +173,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -185,7 +173,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
185 }173 }
186}174}
187175
188fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {176fn genInst(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
189 const air_tags = cg.air.instructions.items(.tag);177 const air_tags = cg.air.instructions.items(.tag);
190 return switch (air_tags[@backingInt(inst)]) {178 return switch (air_tags[@backingInt(inst)]) {
191 .inferred_alloc, .inferred_alloc_comptime => unreachable,179 .inferred_alloc, .inferred_alloc_comptime => unreachable,
...@@ -444,17 +432,17 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -444,17 +432,17 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
444 };432 };
445}433}
446434
447fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {435fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
448 _ = cg;436 _ = cg;
449 _ = inst;437 _ = inst;
450}438}
451439
452fn airTrap(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {440fn airTrap(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
453 _ = inst;441 _ = inst;
454 try cg.addTag(.halt);442 try cg.addTag(.halt);
455}443}
456444
457fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {445fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
458 const unwrapped_asm = cg.air.unwrapAsm(inst);446 const unwrapped_asm = cg.air.unwrapAsm(inst);
459 const outputs = unwrapped_asm.outputs;447 const outputs = unwrapped_asm.outputs;
460 // const inputs = unwrapped_asm.inputs;448 // const inputs = unwrapped_asm.inputs;
...@@ -538,7 +526,7 @@ pub fn addTagImm8(cg: *CodeGen, tag: Mir.Inst.Tag, imm8: u8) error{OutOfMemory}!...@@ -538,7 +526,7 @@ pub fn addTagImm8(cg: *CodeGen, tag: Mir.Inst.Tag, imm8: u8) error{OutOfMemory}!
538 try cg.addInst(.{ .tag = tag, .data = .{ .imm8 = imm8 } });526 try cg.addInst(.{ .tag = tag, .data = .{ .imm8 = imm8 } });
539}527}
540528
541fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {529fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) codegen.Error {
542 const zcu = cg.pt.zcu;530 const zcu = cg.pt.zcu;
543 const func = zcu.funcInfo(cg.func_index);531 const func = zcu.funcInfo(cg.func_index);
544 return zcu.codegenFail(func.owner_nav, fmt, args);532 return zcu.codegenFail(func.owner_nav, fmt, args);
src/codegen/wasm/CodeGen.zig+3-8
...@@ -332,8 +332,7 @@ const ValueTable = std.array_hash_map.Auto(Air.Inst.Ref, WValue);...@@ -332,8 +332,7 @@ const ValueTable = std.array_hash_map.Auto(Air.Inst.Ref, WValue);
332332
333const bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {};333const bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {};
334334
335const InnerError = error{335const InnerError = Error || error{
336 OutOfMemory,
337 /// An error occurred when trying to lower AIR to MIR.336 /// An error occurred when trying to lower AIR to MIR.
338 AlreadyReported,337 AlreadyReported,
339 /// Compiler implementation could not handle a large integer.338 /// Compiler implementation could not handle a large integer.
...@@ -361,7 +360,7 @@ pub fn deinit(cg: *CodeGen) void {...@@ -361,7 +360,7 @@ pub fn deinit(cg: *CodeGen) void {
361 cg.* = undefined;360 cg.* = undefined;
362}361}
363362
364pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {363pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) Error {
365 const zcu = cg.pt.zcu;364 const zcu = cg.pt.zcu;
366 const func = zcu.funcInfo(cg.func_index);365 const func = zcu.funcInfo(cg.func_index);
367 return zcu.codegenFail(func.owner_nav, fmt, args);366 return zcu.codegenFail(func.owner_nav, fmt, args);
...@@ -760,11 +759,7 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {...@@ -760,11 +759,7 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {
760 return .{ .local = .{ .value = initial_index, .references = 1 } };759 return .{ .local = .{ .value = initial_index, .references = 1 } };
761}760}
762761
763pub const Error = error{762pub const Error = codegen.Error;
764 OutOfMemory,
765 /// Indicates the error is already stored in Zcu `failed_codegen`.
766 AlreadyReported,
767};
768763
769pub fn generate(764pub fn generate(
770 bin_file: *link.File,765 bin_file: *link.File,
src/codegen/x86_64/CodeGen.zig+1-1
...@@ -182172,7 +182172,7 @@ fn resolveCallingConventionValues(...@@ -182172,7 +182172,7 @@ fn resolveCallingConventionValues(
182172 return result;182172 return result;
182173}182173}
182174182174
182175fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {182175fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) codegen.Error {
182176 @branchHint(.cold);182176 @branchHint(.cold);
182177 const zcu = cg.pt.zcu;182177 const zcu = cg.pt.zcu;
182178 return switch (cg.owner) {182178 return switch (cg.owner) {
src/codegen/x86_64/Emit.zig+1-1
...@@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void {
138 return emit.fail("{s} creating lazy symbol", .{@errorName(err)}),138 return emit.fail("{s} creating lazy symbol", .{@errorName(err)}),
139 ))139 ))
140 else if (emit.bin_file.cast(.elf2)) |elf|140 else if (emit.bin_file.cast(.elf2)) |elf|
141 try elf.lazySymbol(lazy_sym)141 try elf.lazySymbol(emit.pt, lazy_sym)
142 else if (emit.bin_file.cast(.macho)) |macho_file|142 else if (emit.bin_file.cast(.macho)) |macho_file|
143 @fromBackingInt(@intCast(macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|143 @fromBackingInt(@intCast(macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
144 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})))144 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})))
src/link.zig+9-14
...@@ -838,7 +838,7 @@ pub const File = struct {...@@ -838,7 +838,7 @@ pub const File = struct {
838 switch (base.tag) {838 switch (base.tag) {
839 .lld => unreachable,839 .lld => unreachable,
840 else => {},840 else => {},
841 inline .elf, .c => |tag| {841 inline .elf, .elf2, .c, .coff2 => |tag| {
842 dev.check(tag.devFeature());842 dev.check(tag.devFeature());
843 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateContainerType(pt, ty, success);843 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateContainerType(pt, ty, success);
844 },844 },
...@@ -1690,19 +1690,14 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void...@@ -1690,19 +1690,14 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
1690 const name = Type.fromInterned(container_update.ty).containerTypeName(ip).toSlice(ip);1690 const name = Type.fromInterned(container_update.ty).containerTypeName(ip).toSlice(ip);
1691 const ty_prog_node = comp.link_prog_node.start(name, 0);1691 const ty_prog_node = comp.link_prog_node.start(name, 0);
1692 defer ty_prog_node.end();1692 defer ty_prog_node.end();
1693 if (zcu.llvm_object) |llvm_object| {1693 (if (zcu.llvm_object) |llvm_object|
1694 llvm_object.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {1694 llvm_object.updateContainerType(pt, container_update.ty, container_update.success)
1695 error.OutOfMemory => diags.setAllocFailure(),1695 else if (comp.bin_file) |lf|
1696 };1696 lf.updateContainerType(pt, container_update.ty, container_update.success)) catch |err| switch (err) {
1697 } else {1697 error.OutOfMemory => diags.setAllocFailure(),
1698 if (comp.bin_file) |lf| {1698 error.Canceled => io.recancel(),
1699 lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {1699 error.AlreadyReported => {},
1700 error.OutOfMemory => diags.setAllocFailure(),1700 };
1701 error.Canceled => io.recancel(),
1702 error.AlreadyReported => {},
1703 };
1704 }
1705 }
1706 break :nav null;1701 break :nav null;
1707 },1702 },
1708 .debug_update_line_number => |ti| nav: {1703 .debug_update_line_number => |ti| nav: {
src/link/C.zig+14-14
...@@ -498,7 +498,7 @@ pub fn updateFunc(...@@ -498,7 +498,7 @@ pub fn updateFunc(
498 pt: Zcu.PerThread,498 pt: Zcu.PerThread,
499 func_index: InternPool.Index,499 func_index: InternPool.Index,
500 mir: *AnyMir,500 mir: *AnyMir,
501) Allocator.Error!void {501) link.Error!void {
502 const zcu = pt.zcu;502 const zcu = pt.zcu;
503 const gpa = zcu.gpa;503 const gpa = zcu.gpa;
504 const nav = zcu.funcInfo(func_index).owner_nav;504 const nav = zcu.funcInfo(func_index).owner_nav;
...@@ -536,11 +536,7 @@ pub fn updateFunc(...@@ -536,11 +536,7 @@ pub fn updateFunc(
536 try c.type_pool.flushPending(pt, .{ .c = c });536 try c.type_pool.flushPending(pt, .{ .c = c });
537}537}
538538
539pub fn updateNav(539pub fn updateNav(c: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {
540 c: *C,
541 pt: Zcu.PerThread,
542 nav_index: InternPool.Nav.Index,
543) Allocator.Error!void {
544 const tracy = trace(@src());540 const tracy = trace(@src());
545 defer tracy.end();541 defer tracy.end();
546542
...@@ -603,7 +599,8 @@ pub fn updateNav(...@@ -603,7 +599,8 @@ pub fn updateNav(
603 const start = aw.written().len;599 const start = aw.written().len;
604 codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) {600 codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) {
605 error.AlreadyReported => return,601 error.AlreadyReported => return,
606 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,602 error.WriteFailed => return error.OutOfMemory,
603 error.Canceled, error.OutOfMemory => |e| return e,
607 };604 };
608 break :fwd_decl .{605 break :fwd_decl .{
609 .start = @intCast(start),606 .start = @intCast(start),
...@@ -617,7 +614,8 @@ pub fn updateNav(...@@ -617,7 +614,8 @@ pub fn updateNav(
617 const start = aw.written().len;614 const start = aw.written().len;
618 codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) {615 codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) {
619 error.AlreadyReported => return,616 error.AlreadyReported => return,
620 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,617 error.WriteFailed => return error.OutOfMemory,
618 error.Canceled, error.OutOfMemory => |e| return e,
621 };619 };
622 break :code .{620 break :code .{
623 .start = @intCast(start),621 .start = @intCast(start),
...@@ -655,7 +653,7 @@ fn updateUav(...@@ -655,7 +653,7 @@ fn updateUav(
655 pt: Zcu.PerThread,653 pt: Zcu.PerThread,
656 val: Value,654 val: Value,
657 rendered_decl: *RenderedDecl,655 rendered_decl: *RenderedDecl,
658) Allocator.Error!void {656) link.Error!void {
659 const tracy = trace(@src());657 const tracy = trace(@src());
660 defer tracy.end();658 defer tracy.end();
661659
...@@ -691,7 +689,8 @@ fn updateUav(...@@ -691,7 +689,8 @@ fn updateUav(
691 .init_val = val,689 .init_val = val,
692 }) catch |err| switch (err) {690 }) catch |err| switch (err) {
693 error.AlreadyReported => return,691 error.AlreadyReported => return,
694 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,692 error.WriteFailed => return error.OutOfMemory,
693 error.Canceled, error.OutOfMemory => |e| return e,
695 };694 };
696 break :fwd_decl .{695 break :fwd_decl .{
697 .start = @intCast(start),696 .start = @intCast(start),
...@@ -710,7 +709,8 @@ fn updateUav(...@@ -710,7 +709,8 @@ fn updateUav(
710 .init_val = val,709 .init_val = val,
711 }) catch |err| switch (err) {710 }) catch |err| switch (err) {
712 error.AlreadyReported => return,711 error.AlreadyReported => return,
713 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,712 error.WriteFailed => return error.OutOfMemory,
713 error.Canceled, error.OutOfMemory => |e| return e,
714 };714 };
715 break :code .{715 break :code .{
716 .start = @intCast(start),716 .start = @intCast(start),
...@@ -1144,14 +1144,14 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -1144,14 +1144,14 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
1144 for (need_never_tail_funcs.keys()) |fn_nav| {1144 for (need_never_tail_funcs.keys()) |fn_nav| {
1145 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) {1145 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) {
1146 error.WriteFailed => return error.OutOfMemory,1146 error.WriteFailed => return error.OutOfMemory,
1147 error.OutOfMemory => |e| return e,1147 error.Canceled, error.OutOfMemory => |e| return e,
1148 error.AlreadyReported => unreachable,1148 error.AlreadyReported => unreachable,
1149 };1149 };
1150 }1150 }
1151 for (need_never_inline_funcs.keys()) |fn_nav| {1151 for (need_never_inline_funcs.keys()) |fn_nav| {
1152 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) {1152 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) {
1153 error.WriteFailed => return error.OutOfMemory,1153 error.WriteFailed => return error.OutOfMemory,
1154 error.OutOfMemory => |e| return e,1154 error.Canceled, error.OutOfMemory => |e| return e,
1155 error.AlreadyReported => unreachable,1155 error.AlreadyReported => unreachable,
1156 };1156 };
1157 }1157 }
...@@ -1399,7 +1399,7 @@ fn addCTypeDependencies(...@@ -1399,7 +1399,7 @@ fn addCTypeDependencies(
1399 };1399 };
1400}1400}
14011401
1402fn updateNewUavs(c: *C, pt: Zcu.PerThread, old_uavs_len: usize) Allocator.Error!void {1402fn updateNewUavs(c: *C, pt: Zcu.PerThread, old_uavs_len: usize) link.Error!void {
1403 const gpa = pt.zcu.comp.gpa;1403 const gpa = pt.zcu.comp.gpa;
1404 var index = old_uavs_len;1404 var index = old_uavs_len;
1405 while (index < c.uavs.count()) : (index += 1) {1405 while (index < c.uavs.count()) : (index += 1) {
src/link/Coff.zig+87-51
...@@ -1666,7 +1666,7 @@ fn create(...@@ -1666,7 +1666,7 @@ fn create(
1666 .global_pending_index = 0,1666 .global_pending_index = 0,
1667 .navs = .empty,1667 .navs = .empty,
1668 .uavs = .empty,1668 .uavs = .empty,
1669 .lazy = .initFill(.{1669 .lazy = comptime .initFill(.{
1670 .map = .empty,1670 .map = .empty,
1671 .pending_index = 0,1671 .pending_index = 0,
1672 }),1672 }),
...@@ -3158,7 +3158,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32, pt: Zcu.PerThread) !void {...@@ -3158,7 +3158,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32, pt: Zcu.PerThread) !void {
3158 },3158 },
3159 inline .lazy_code, .lazy_const_data => |mi, tag| {3159 inline .lazy_code, .lazy_const_data => |mi, tag| {
3160 const lazy_sym = mi.lazySymbol(coff);3160 const lazy_sym = mi.lazySymbol(coff);
3161 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{3161 const name = try gpa.print("__lazy_{s}_{f}", .{
3162 @tagName(lazy_sym.kind),3162 @tagName(lazy_sym.kind),
3163 Type.fromInterned(lazy_sym.ty).fmt(pt),3163 Type.fromInterned(lazy_sym.ty).fmt(pt),
3164 });3164 });
...@@ -5488,6 +5488,44 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde...@@ -5488,6 +5488,44 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
5488 if (nav.resolved.?.@"linksection".unwrap()) |_| {5488 if (nav.resolved.?.@"linksection".unwrap()) |_| {
5489 try ni.resizeLeaf(&coff.mf, gpa, si.get(coff).extra.size);5489 try ni.resizeLeaf(&coff.mf, gpa, si.get(coff).extra.size);
5490 }5490 }
5491
5492 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
5493 try coff.genPending(pt);
5494}
5495
5496pub fn updateContainerType(
5497 coff: *Coff,
5498 pt: Zcu.PerThread,
5499 ty: InternPool.Index,
5500 success: bool,
5501) link.Error!void {
5502 if (!success) return;
5503 var lazy_it = coff.lazy.iterator();
5504 while (lazy_it.next()) |lazy| if (lazy.value.map.getIndex(ty)) |lmi| {
5505 if (lazy.value.pending_index <= lmi) continue;
5506 // This type has changed on this incremental update, so update the lazy code/data.
5507 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = @intCast(lmi) };
5508 const kind = switch (lmr.kind) {
5509 .code => "code",
5510 .const_data => "data",
5511 };
5512 var name: [std.Progress.Node.max_name_len]u8 = undefined;
5513 const sub_prog_node = coff.synth_prog_node.start(
5514 std.mem.print(&name, "lazy {s} for {f}", .{
5515 kind,
5516 Type.fromInterned(ty).fmt(pt),
5517 }) catch &name,
5518 0,
5519 );
5520 defer sub_prog_node.end();
5521 coff.genLazy(pt, lmr) catch |err| switch (err) {
5522 else => |e| return e,
5523 error.MappedFileIo => return coff.base.comp.link_diags.fail(
5524 "linker failed to lower lazy {s}: {t}",
5525 .{ kind, coff.mf.io_err.? },
5526 ),
5527 };
5528 };
5491}5529}
54925530
5493pub fn lowerUav(5531pub fn lowerUav(
...@@ -5603,10 +5641,13 @@ fn updateFuncInner(...@@ -5603,10 +5641,13 @@ fn updateFuncInner(
5603 };5641 };
5604 si.get(coff).extra.size = @intCast(nw.interface.end);5642 si.get(coff).extra.size = @intCast(nw.interface.end);
5605 try si.applyLocationRelocs(coff);5643 try si.applyLocationRelocs(coff);
5644
5645 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
5646 try coff.genPending(pt);
5606}5647}
56075648
5608pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {5649pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {
5609 coff.flushLazy(pt, .{5650 coff.genLazy(pt, .{
5610 .kind = .const_data,5651 .kind = .const_data,
5611 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),5652 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
5612 }) catch |err| switch (err) {5653 }) catch |err| switch (err) {
...@@ -5919,22 +5960,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {...@@ -5919,22 +5960,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
5919 };5960 };
5920 break :task;5961 break :task;
5921 }5962 }
5922 while (coff.pending_uavs.pop()) |pending_uav| {
5923 const sub_prog_node = coff.idleProgNode(tid, coff.const_prog_node, .{ .uav = pending_uav.key });
5924 defer sub_prog_node.end();
5925 coff.flushUav(
5926 .{ .zcu = comp.zcu.?, .tid = tid },
5927 pending_uav.key,
5928 pending_uav.value.alignment,
5929 ) catch |err| switch (err) {
5930 else => |e| return e,
5931 error.MappedFileIo => return comp.link_diags.fail(
5932 "linker failed to lower constant: {t}",
5933 .{coff.mf.io_err.?},
5934 ),
5935 };
5936 break :task;
5937 }
5938 if (coff.pending_input) |pending_iami| {5963 if (coff.pending_input) |pending_iami| {
5939 const name_slice = pending_iami.member(coff).name.toSlice(coff);5964 const name_slice = pending_iami.member(coff).name.toSlice(coff);
5940 const sub_prog_node = coff.input_prog_node.start(5965 const sub_prog_node = coff.input_prog_node.start(
...@@ -5983,33 +6008,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {...@@ -5983,33 +6008,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
5983 };6008 };
5984 break :task;6009 break :task;
5985 }6010 }
5986 var lazy_it = coff.lazy.iterator();
5987 while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) {
5988 const pt: Zcu.PerThread = .{ .zcu = comp.zcu.?, .tid = tid };
5989 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
5990 lazy.value.pending_index += 1;
5991 const kind = switch (lmr.kind) {
5992 .code => "code",
5993 .const_data => "data",
5994 };
5995 var name: [std.Progress.Node.max_name_len]u8 = undefined;
5996 const sub_prog_node = coff.synth_prog_node.start(
5997 std.mem.print(&name, "lazy {s} for {f}", .{
5998 kind,
5999 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),
6000 }) catch &name,
6001 0,
6002 );
6003 defer sub_prog_node.end();
6004 coff.flushLazy(pt, lmr) catch |err| switch (err) {
6005 else => |e| return e,
6006 error.MappedFileIo => return comp.link_diags.fail(
6007 "linker failed to lower lazy {s}: {t}",
6008 .{ kind, coff.mf.io_err.? },
6009 ),
6010 };
6011 break :task;
6012 };
6013 if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) {6011 if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) {
6014 defer coff.symbol_table.pending_symbol_index += 1;6012 defer coff.symbol_table.pending_symbol_index += 1;
6015 const si = coff.symbol_table.symbols.keys()[coff.symbol_table.pending_symbol_index];6013 const si = coff.symbol_table.symbols.keys()[coff.symbol_table.pending_symbol_index];
...@@ -6038,12 +6036,10 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {...@@ -6038,12 +6036,10 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
6038 }6036 }
60396037
6040 if (coff.section_merge_pending_index < coff.section_merges.count()) return true;6038 if (coff.section_merge_pending_index < coff.section_merges.count()) return true;
6041 if (coff.pending_uavs.count() > 0) return true;
6042 if (coff.pending_input != null) return true;6039 if (coff.pending_input != null) return true;
6043 if (coff.exports_complete and coff.globals.count() > coff.global_pending_index) return true;6040 if (coff.exports_complete and coff.globals.count() > coff.global_pending_index) return true;
6044 assert(!coff.exports_complete or coff.inputs_complete);6041 assert(!coff.exports_complete or coff.inputs_complete);
6045 if (coff.exports_complete and coff.pending_special_symbol != .none) return true;6042 if (coff.exports_complete and coff.pending_special_symbol != .none) return true;
6046 for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true;
6047 if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) return true;6043 if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) return true;
6048 return false;6044 return false;
6049}6045}
...@@ -6153,7 +6149,47 @@ fn idleProgNode(...@@ -6153,7 +6149,47 @@ fn idleProgNode(
6153 }, 0);6149 }, 0);
6154}6150}
61556151
6156fn flushUav(6152fn genPending(coff: *Coff, pt: Zcu.PerThread) Error!void {
6153 const comp = pt.zcu.comp;
6154 while (coff.pending_uavs.pop()) |pending_uav| {
6155 const sub_prog_node = coff.idleProgNode(pt.tid, coff.const_prog_node, .{ .uav = pending_uav.key });
6156 defer sub_prog_node.end();
6157 coff.genUav(pt, pending_uav.key, pending_uav.value.alignment) catch |err| switch (err) {
6158 else => |e| return e,
6159 error.MappedFileIo => return comp.link_diags.fail(
6160 "linker failed to lower constant: {t}",
6161 .{coff.mf.io_err.?},
6162 ),
6163 };
6164 }
6165 var lazy_it = coff.lazy.iterator();
6166 while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) {
6167 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
6168 lazy.value.pending_index += 1;
6169 const kind = switch (lmr.kind) {
6170 .code => "code",
6171 .const_data => "data",
6172 };
6173 var name: [std.Progress.Node.max_name_len]u8 = undefined;
6174 const sub_prog_node = coff.synth_prog_node.start(
6175 std.mem.print(&name, "lazy {s} for {f}", .{
6176 kind,
6177 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),
6178 }) catch &name,
6179 0,
6180 );
6181 defer sub_prog_node.end();
6182 coff.genLazy(pt, lmr) catch |err| switch (err) {
6183 else => |e| return e,
6184 error.MappedFileIo => return comp.link_diags.fail(
6185 "linker failed to lower lazy {s}: {t}",
6186 .{ kind, coff.mf.io_err.? },
6187 ),
6188 };
6189 };
6190}
6191
6192fn genUav(
6157 coff: *Coff,6193 coff: *Coff,
6158 pt: Zcu.PerThread,6194 pt: Zcu.PerThread,
6159 umi: Node.UavMapIndex,6195 umi: Node.UavMapIndex,
...@@ -6311,7 +6347,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {...@@ -6311,7 +6347,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
6311 .{ name, imp_match }6347 .{ name, imp_match }
6312 else name: {6348 else name: {
6313 try coff.ensureUnusedStringCapacity(imp_prefix.len + name_slice.len);6349 try coff.ensureUnusedStringCapacity(imp_prefix.len + name_slice.len);
6314 const imp_name = try std.fmt.allocPrint(gpa, imp_prefix ++ "{s}", .{name_slice});6350 const imp_name = try gpa.print(imp_prefix ++ "{s}", .{name_slice});
6315 defer gpa.free(imp_name);6351 defer gpa.free(imp_name);
6316 break :name .{ coff.getOrPutStringAssumeCapacity(imp_name), true };6352 break :name .{ coff.getOrPutStringAssumeCapacity(imp_name), true };
6317 };6353 };
...@@ -6773,7 +6809,7 @@ fn flushSpecialSymbol(coff: *Coff, pending: SpecialSymbol) !SpecialSymbol {...@@ -6773,7 +6809,7 @@ fn flushSpecialSymbol(coff: *Coff, pending: SpecialSymbol) !SpecialSymbol {
6773 };6809 };
6774}6810}
67756811
6776fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {6812fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
6777 const zcu = pt.zcu;6813 const zcu = pt.zcu;
6778 const gpa = zcu.gpa;6814 const gpa = zcu.gpa;
67796815
src/link/ConstPool.zig+10-5
...@@ -46,6 +46,7 @@ pub const Index = enum(u32) {...@@ -46,6 +46,7 @@ pub const Index = enum(u32) {
4646
47pub const User = union(enum) {47pub const User = union(enum) {
48 dwarf: *@import("Dwarf.zig"),48 dwarf: *@import("Dwarf.zig"),
49 elf2: *@import("Elf2.zig"),
49 c: *@import("C.zig"),50 c: *@import("C.zig"),
50 llvm: @import("../codegen/llvm.zig").Object.Ptr,51 llvm: @import("../codegen/llvm.zig").Object.Ptr,
5152
...@@ -73,7 +74,7 @@ pub const User = union(enum) {...@@ -73,7 +74,7 @@ pub const User = union(enum) {
73 pt: Zcu.PerThread,74 pt: Zcu.PerThread,
74 index: Index,75 index: Index,
75 val: InternPool.Index,76 val: InternPool.Index,
76 ) Allocator.Error!void {77 ) link.Error!void {
77 switch (user) {78 switch (user) {
78 inline else => |impl| return impl.updateConst(pt, index, val),79 inline else => |impl| return impl.updateConst(pt, index, val),
79 }80 }
...@@ -89,7 +90,7 @@ pub const User = union(enum) {...@@ -89,7 +90,7 @@ pub const User = union(enum) {
89 pt: Zcu.PerThread,90 pt: Zcu.PerThread,
90 index: Index,91 index: Index,
91 val: InternPool.Index,92 val: InternPool.Index,
92 ) Allocator.Error!void {93 ) link.Error!void {
93 switch (user) {94 switch (user) {
94 inline else => |impl| return impl.updateConstIncomplete(pt, index, val),95 inline else => |impl| return impl.updateConstIncomplete(pt, index, val),
95 }96 }
...@@ -128,7 +129,7 @@ pub fn updateContainerType(...@@ -128,7 +129,7 @@ pub fn updateContainerType(
128 user: User,129 user: User,
129 container_ty: InternPool.Index,130 container_ty: InternPool.Index,
130 success: bool,131 success: bool,
131) Allocator.Error!void {132) link.Error!void {
132 if (success) {133 if (success) {
133 const gpa = pt.zcu.comp.gpa;134 const gpa = pt.zcu.comp.gpa;
134 try pool.complete_containers.put(gpa, container_ty, {});135 try pool.complete_containers.put(gpa, container_ty, {});
...@@ -160,13 +161,16 @@ pub fn get(pool: *ConstPool, pt: Zcu.PerThread, user: User, val: InternPool.Inde...@@ -160,13 +161,16 @@ pub fn get(pool: *ConstPool, pt: Zcu.PerThread, user: User, val: InternPool.Inde
160 }161 }
161 return index;162 return index;
162}163}
163pub fn flushPending(pool: *ConstPool, pt: Zcu.PerThread, user: User) Allocator.Error!void {164pub fn getIfExists(pool: *ConstPool, val: InternPool.Index) ?ConstPool.Index {
165 return @fromBackingInt(@intCast(pool.values.getIndex(val) orelse return null));
166}
167pub fn flushPending(pool: *ConstPool, pt: Zcu.PerThread, user: User) link.Error!void {
164 while (pool.pending.pop()) |pending_ty| {168 while (pool.pending.pop()) |pending_ty| {
165 try pool.update(pt, user, pending_ty);169 try pool.update(pt, user, pending_ty);
166 }170 }
167}171}
168172
169fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Index) Allocator.Error!void {173fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Index) link.Error!void {
170 const zcu = pt.zcu;174 const zcu = pt.zcu;
171 const ip = &zcu.intern_pool;175 const ip = &zcu.intern_pool;
172 const val = index.val(pool);176 const val = index.val(pool);
...@@ -286,5 +290,6 @@ const std = @import("std");...@@ -286,5 +290,6 @@ const std = @import("std");
286const Allocator = std.mem.Allocator;290const Allocator = std.mem.Allocator;
287291
288const InternPool = @import("../InternPool.zig");292const InternPool = @import("../InternPool.zig");
293const link = @import("../link.zig");
289const Type = @import("../Type.zig");294const Type = @import("../Type.zig");
290const Zcu = @import("../Zcu.zig");295const Zcu = @import("../Zcu.zig");
src/link/Dwarf.zig+2-2
...@@ -2585,7 +2585,7 @@ pub fn initWipNav(...@@ -2585,7 +2585,7 @@ pub fn initWipNav(
2585 pt: Zcu.PerThread,2585 pt: Zcu.PerThread,
2586 nav_index: InternPool.Nav.Index,2586 nav_index: InternPool.Nav.Index,
2587 sym_index: link.File.SymbolId,2587 sym_index: link.File.SymbolId,
2588) error{ OutOfMemory, AlreadyReported }!WipNav {2588) link.Error!WipNav {
2589 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {2589 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
2590 error.OutOfMemory => error.OutOfMemory,2590 error.OutOfMemory => error.OutOfMemory,
2591 else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),2591 else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
...@@ -3008,7 +3008,7 @@ fn finishWipNavWriterError(...@@ -3008,7 +3008,7 @@ fn finishWipNavWriterError(
3008 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });3008 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3009}3009}
30103010
3011pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, AlreadyReported }!void {3011pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {
3012 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {3012 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
3013 error.OutOfMemory => error.OutOfMemory,3013 error.OutOfMemory => error.OutOfMemory,
3014 else => |e| pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),3014 else => |e| pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
src/link/Elf.zig+1-3
...@@ -1677,9 +1677,7 @@ pub fn updateContainerType(...@@ -1677,9 +1677,7 @@ pub fn updateContainerType(
1677 ty: InternPool.Index,1677 ty: InternPool.Index,
1678 success: bool,1678 success: bool,
1679) link.Error!void {1679) link.Error!void {
1680 return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) {1680 try self.zigObjectPtr().?.updateContainerType(pt, ty, success);
1681 error.OutOfMemory => |e| return e,
1682 };
1683}1681}
16841682
1685pub fn updateExports(1683pub fn updateExports(
src/link/Elf2.zig+105-73
...@@ -174,16 +174,13 @@ uavs: std.array_hash_map.Auto(InternPool.Index, struct {...@@ -174,16 +174,13 @@ uavs: std.array_hash_map.Auto(InternPool.Index, struct {
174 first_symbol_reloc: SymbolReloc.Index,174 first_symbol_reloc: SymbolReloc.Index,
175 // No `first_got_reloc` field because a UAV never contains GOT relocations.175 // No `first_got_reloc` field because a UAV never contains GOT relocations.
176}),176}),
177lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {177lazy: std.EnumArray(link.File.LazySymbol.Kind, std.array_hash_map.Auto(link.ConstPool.Index, struct {
178 map: std.array_hash_map.Auto(InternPool.Index, struct {178 lsi: Symbol.LocalIndex,
179 lsi: Symbol.LocalIndex,179 /// The start index of the contiguous sequence of symbol relocations in this lazy code/data.
180 /// The start index of the contiguous sequence of symbol relocations in this lazy code/data.180 first_symbol_reloc: SymbolReloc.Index,
181 first_symbol_reloc: SymbolReloc.Index,181 /// The start index of the contiguous sequence of GOT relocations in this lazy code/data.
182 /// The start index of the contiguous sequence of GOT relocations in this lazy code/data.182 first_got_reloc: GotReloc.Index,
183 first_got_reloc: GotReloc.Index,183})),
184 }),
185 pending_index: u32,
186}),
187pending_uavs: std.ArrayList(Node.UavMapIndex),184pending_uavs: std.ArrayList(Node.UavMapIndex),
188symbol_relocs: std.ArrayList(SymbolReloc),185symbol_relocs: std.ArrayList(SymbolReloc),
189node_relocs: std.ArrayList(NodeReloc),186node_relocs: std.ArrayList(NodeReloc),
...@@ -240,7 +237,6 @@ overflowed_reloc_count: u32,...@@ -240,7 +237,6 @@ overflowed_reloc_count: u32,
240misaligned_reloc_count: u32,237misaligned_reloc_count: u32,
241238
242const_prog_node: std.Progress.Node,239const_prog_node: std.Progress.Node,
243synth_prog_node: std.Progress.Node,
244input_prog_node: std.Progress.Node,240input_prog_node: std.Progress.Node,
245241
246const Error = link.Error || error{MappedFileIo};242const Error = link.Error || error{MappedFileIo};
...@@ -408,20 +404,23 @@ const Node = union(enum) {...@@ -408,20 +404,23 @@ const Node = union(enum) {
408 }404 }
409405
410 fn firstSymbolReloc(lmi: @This(), elf: *const Elf) SymbolReloc.Index {406 fn firstSymbolReloc(lmi: @This(), elf: *const Elf) SymbolReloc.Index {
411 return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_symbol_reloc;407 return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_symbol_reloc;
412 }408 }
413 fn firstGotReloc(lmi: @This(), elf: *const Elf) GotReloc.Index {409 fn firstGotReloc(lmi: @This(), elf: *const Elf) GotReloc.Index {
414 return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_got_reloc;410 return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_got_reloc;
415 }411 }
416 };412 };
417 }413 }
418414
419 pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol {415 pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol {
420 return .{ .kind = lmr.kind, .ty = elf.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };416 return .{
417 .kind = lmr.kind,
418 .ty = elf.lazy.getPtrConst(lmr.kind).keys()[lmr.index].val(&elf.dwarf.const_pool),
419 };
421 }420 }
422421
423 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.LocalIndex {422 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.LocalIndex {
424 return elf.lazy.getPtrConst(lmr.kind).map.values()[lmr.index].lsi;423 return elf.lazy.getPtrConst(lmr.kind).values()[lmr.index].lsi;
425 }424 }
426 };425 };
427426
...@@ -3283,21 +3282,26 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {...@@ -3283,21 +3282,26 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
3283 const s: Symbol.Id = .local(lsi);3282 const s: Symbol.Id = .local(lsi);
3284 return s.toTypeErased();3283 return s.toTypeErased();
3285}3284}
3286pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId {3285pub fn lazySymbol(
3286 elf: *Elf,
3287 pt: Zcu.PerThread,
3288 lazy: link.File.LazySymbol,
3289) link.Error!link.File.SymbolId {
3287 const diags = &elf.base.comp.link_diags;3290 const diags = &elf.base.comp.link_diags;
3288 return elf.lazySymbolInner(lazy) catch |err| switch (err) {3291 return elf.lazySymbolInner(pt, lazy) catch |err| switch (err) {
3289 else => |e| return e,3292 else => |e| return e,
3290 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),3293 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
3291 };3294 };
3292}3295}
3293fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId {3296fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
3294 const gpa = elf.base.comp.gpa;3297 const gpa = elf.base.comp.gpa;
32953298
3296 try elf.ensureUnusedSymbolCapacity(1, .all_local);3299 try elf.ensureUnusedSymbolCapacity(1, .all_local);
3297 try elf.nodes.ensureUnusedCapacity(gpa, 1);3300 try elf.nodes.ensureUnusedCapacity(gpa, 1);
3298 try elf.lazy.getPtr(lazy.kind).map.ensureUnusedCapacity(gpa, 1);3301 try elf.lazy.getPtr(lazy.kind).ensureUnusedCapacity(gpa, 1);
32993302
3300 const gop = elf.lazy.getPtr(lazy.kind).map.getOrPutAssumeCapacity(lazy.ty);3303 const cpi = try elf.dwarf.const_pool.get(pt, .{ .elf2 = elf }, lazy.ty);
3304 const gop = elf.lazy.getPtr(lazy.kind).getOrPutAssumeCapacity(cpi);
3301 if (!gop.found_existing) {3305 if (!gop.found_existing) {
3302 const shndx: Section.Index, const sym_type: std.elf.STT = switch (lazy.kind) {3306 const shndx: Section.Index, const sym_type: std.elf.STT = switch (lazy.kind) {
3303 .code => .{ .text, .FUNC },3307 .code => .{ .text, .FUNC },
...@@ -3326,7 +3330,7 @@ fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.Symbol...@@ -3326,7 +3330,7 @@ fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.Symbol
3326 .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) },3330 .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) },
3327 .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) },3331 .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) },
3328 });3332 });
3329 elf.synth_prog_node.increaseEstimatedTotalItems(1);3333 elf.base.comp.link_prog_node.increaseEstimatedTotalItems(1);
3330 }3334 }
3331 const s: Symbol.Id = .local(gop.value_ptr.lsi);3335 const s: Symbol.Id = .local(gop.value_ptr.lsi);
3332 return s.toTypeErased();3336 return s.toTypeErased();
...@@ -3754,10 +3758,7 @@ fn create(...@@ -3754,10 +3758,7 @@ fn create(
3754 .one_shot_fixups = .empty,3758 .one_shot_fixups = .empty,
3755 .navs = .empty,3759 .navs = .empty,
3756 .uavs = .empty,3760 .uavs = .empty,
3757 .lazy = comptime .initFill(.{3761 .lazy = comptime .initFill(.empty),
3758 .map = .empty,
3759 .pending_index = 0,
3760 }),
3761 .pending_uavs = .empty,3762 .pending_uavs = .empty,
3762 .symbol_relocs = .empty,3763 .symbol_relocs = .empty,
3763 .node_relocs = .empty,3764 .node_relocs = .empty,
...@@ -3772,7 +3773,7 @@ fn create(...@@ -3772,7 +3773,7 @@ fn create(
3772 .dwarf => |v| v,3773 .dwarf => |v| v,
3773 .code_view => unreachable,3774 .code_view => unreachable,
3774 }),3775 }),
3775 .dwarf_shared = .initFill(.{3776 .dwarf_shared = comptime .initFill(.{
3776 .first_target_reloc = .none,3777 .first_target_reloc = .none,
3777 }),3778 }),
3778 .dwarf_units = .empty,3779 .dwarf_units = .empty,
...@@ -3784,7 +3785,6 @@ fn create(...@@ -3784,7 +3785,6 @@ fn create(
3784 .misaligned_reloc_count = 0,3785 .misaligned_reloc_count = 0,
37853786
3786 .const_prog_node = .none,3787 .const_prog_node = .none,
3787 .synth_prog_node = .none,
3788 .input_prog_node = .none,3788 .input_prog_node = .none,
3789 };3789 };
3790 errdefer elf.deinit();3790 errdefer elf.deinit();
...@@ -3820,7 +3820,7 @@ pub fn deinit(elf: *Elf) void {...@@ -3820,7 +3820,7 @@ pub fn deinit(elf: *Elf) void {
3820 elf.one_shot_fixups.deinit(gpa);3820 elf.one_shot_fixups.deinit(gpa);
3821 elf.navs.deinit(gpa);3821 elf.navs.deinit(gpa);
3822 elf.uavs.deinit(gpa);3822 elf.uavs.deinit(gpa);
3823 for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa);3823 for (&elf.lazy.values) |*lazy| lazy.deinit(gpa);
3824 elf.pending_uavs.deinit(gpa);3824 elf.pending_uavs.deinit(gpa);
3825 elf.symbol_relocs.deinit(gpa);3825 elf.symbol_relocs.deinit(gpa);
3826 elf.node_relocs.deinit(gpa);3826 elf.node_relocs.deinit(gpa);
...@@ -5087,11 +5087,6 @@ fn initHeaders(...@@ -5087,11 +5087,6 @@ fn initHeaders(
5087pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void {5087pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void {
5088 prog_node.increaseEstimatedTotalItems(4);5088 prog_node.increaseEstimatedTotalItems(4);
5089 elf.const_prog_node = prog_node.start("Constants", elf.pending_uavs.items.len);5089 elf.const_prog_node = prog_node.start("Constants", elf.pending_uavs.items.len);
5090 elf.synth_prog_node = prog_node.start("Synthetics", count: {
5091 var count: usize = 0;
5092 for (&elf.lazy.values) |*lazy| count += lazy.map.count() - lazy.pending_index;
5093 break :count count;
5094 });
5095 elf.mf.update_prog_node = prog_node.start("Relocations", elf.mf.updates.items.len);5090 elf.mf.update_prog_node = prog_node.start("Relocations", elf.mf.updates.items.len);
5096 elf.input_prog_node = prog_node.start("Inputs", (elf.inputs.items.len - elf.input_pending_index) +5091 elf.input_prog_node = prog_node.start("Inputs", (elf.inputs.items.len - elf.input_pending_index) +
5097 (elf.input_sections.items.len - elf.input_section_pending_index));5092 (elf.input_sections.items.len - elf.input_section_pending_index));
...@@ -5102,8 +5097,6 @@ pub fn endProgress(elf: *Elf) void {...@@ -5102,8 +5097,6 @@ pub fn endProgress(elf: *Elf) void {
5102 elf.input_prog_node = .none;5097 elf.input_prog_node = .none;
5103 elf.mf.update_prog_node.end();5098 elf.mf.update_prog_node.end();
5104 elf.mf.update_prog_node = .none;5099 elf.mf.update_prog_node = .none;
5105 elf.synth_prog_node.end();
5106 elf.synth_prog_node = .none;
5107 elf.const_prog_node.end();5100 elf.const_prog_node.end();
5108 elf.const_prog_node = .none;5101 elf.const_prog_node = .none;
5109}5102}
...@@ -5267,8 +5260,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5267,8 +5260,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5267 .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc,5260 .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc,
5268 },5261 },
5269 inline .lazy_code, .lazy_const_data => |lmi| .{5262 inline .lazy_code, .lazy_const_data => |lmi| .{
5270 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc,5263 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_symbol_reloc,
5271 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc,5264 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc,
5272 },5265 },
5273 .unit_debug_info_header => |ui| .{5266 .unit_debug_info_header => |ui| .{
5274 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc,5267 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc,
...@@ -8452,6 +8445,73 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)...@@ -8452,6 +8445,73 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
8452 try elf.genPending(pt);8445 try elf.genPending(pt);
8453}8446}
84548447
8448pub fn updateContainerType(
8449 elf: *Elf,
8450 pt: Zcu.PerThread,
8451 ty: InternPool.Index,
8452 success: bool,
8453) link.Error!void {
8454 try elf.dwarf.const_pool.updateContainerType(pt, .{ .elf2 = elf }, ty, success);
8455}
8456
8457pub fn addConst(
8458 elf: *Elf,
8459 pt: Zcu.PerThread,
8460 index: link.ConstPool.Index,
8461 val: InternPool.Index,
8462) std.mem.Allocator.Error!void {
8463 if (false) try elf.dwarf.addConst(pt, index, val);
8464}
8465
8466pub fn updateConst(
8467 elf: *Elf,
8468 pt: Zcu.PerThread,
8469 cpi: link.ConstPool.Index,
8470 val: InternPool.Index,
8471) link.Error!void {
8472 if (val == .anyerror_type) return;
8473 try elf.updateConstInner(pt, cpi, val);
8474}
8475fn updateConstInner(
8476 elf: *Elf,
8477 pt: Zcu.PerThread,
8478 cpi: link.ConstPool.Index,
8479 val: InternPool.Index,
8480) link.Error!void {
8481 var lazy_it = elf.lazy.iterator();
8482 while (lazy_it.next()) |lazy| if (lazy.value.getIndex(cpi)) |li| {
8483 const lazy_ty: Type = .fromInterned(cpi.val(&elf.dwarf.const_pool));
8484 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
8485 const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) {
8486 .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
8487 .error_set => switch (lazy.key) {
8488 .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
8489 .const_data => "@errorName(anyerror)",
8490 },
8491 else => unreachable,
8492 };
8493 const prog_node = elf.base.comp.link_prog_node.start(prog_name, 0);
8494 defer prog_node.end();
8495 elf.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(li) }) catch |err| switch (err) {
8496 else => |e| return e,
8497 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8498 "failed to write output file: {t}",
8499 .{elf.mf.io_err.?},
8500 ),
8501 };
8502 };
8503 if (false) try elf.dwarf.updateConst(pt, cpi, val);
8504}
8505
8506pub fn updateConstIncomplete(
8507 elf: *Elf,
8508 pt: Zcu.PerThread,
8509 cpi: link.ConstPool.Index,
8510 val: InternPool.Index,
8511) link.Error!void {
8512 if (false) try elf.dwarf.updateConstIncomplete(pt, cpi, val);
8513}
8514
8455pub fn updateFunc(8515pub fn updateFunc(
8456 elf: *Elf,8516 elf: *Elf,
8457 pt: Zcu.PerThread,8517 pt: Zcu.PerThread,
...@@ -8726,16 +8786,11 @@ fn updateFuncInner(...@@ -8726,16 +8786,11 @@ fn updateFuncInner(
8726}8786}
87278787
8728pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {8788pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
8729 elf.genLazy(pt, .{8789 try elf.updateConstInner(
8730 .kind = .const_data,8790 pt,
8731 .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),8791 elf.dwarf.const_pool.getIfExists(.anyerror_type) orelse return,
8732 }) catch |err| switch (err) {8792 .anyerror_type,
8733 else => |e| return e,8793 );
8734 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8735 "failed to write output file: {t}",
8736 .{elf.mf.io_err.?},
8737 ),
8738 };
8739}8794}
87408795
8741pub fn flush(8796pub fn flush(
...@@ -8782,8 +8837,7 @@ fn flushInner(...@@ -8782,8 +8837,7 @@ fn flushInner(
8782 while (try elf.idle(tid)) {}8837 while (try elf.idle(tid)) {}
87838838
8784 assert(elf.pending_uavs.items.len == 0);8839 assert(elf.pending_uavs.items.len == 0);
8785 var lazy_it = elf.lazy.iterator();8840 assert(elf.dwarf.const_pool.pending.items.len == 0);
8786 while (lazy_it.next()) |lazy| assert(lazy.value.pending_index == lazy.value.map.count());
87878841
8788 // We've done the final `idle` loop, so everything is at its final place in the file. We have a8842 // We've done the final `idle` loop, so everything is at its final place in the file. We have a
8789 // few more things to check and write now that addresses and offsets are finalized.8843 // few more things to check and write now that addresses and offsets are finalized.
...@@ -8844,9 +8898,7 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {...@@ -8844,9 +8898,7 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
8844 const diags = &comp.link_diags;8898 const diags = &comp.link_diags;
88458899
8846 assert(elf.pending_uavs.items.len == 0);8900 assert(elf.pending_uavs.items.len == 0);
8847 for (&elf.lazy.values) |*lazy| {8901 assert(elf.dwarf.const_pool.pending.items.len == 0);
8848 assert(lazy.pending_index == lazy.map.count());
8849 }
88508902
8851 task: {8903 task: {
8852 if (elf.input_pending_index < elf.inputs.items.len) {8904 if (elf.input_pending_index < elf.inputs.items.len) {
...@@ -9061,8 +9113,6 @@ fn idleProgNode(...@@ -9061,8 +9113,6 @@ fn idleProgNode(
9061}9113}
90629114
9063fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {9115fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {
9064 const zcu = elf.base.comp.zcu.?;
9065
9066 while (elf.pending_uavs.pop()) |umi| {9116 while (elf.pending_uavs.pop()) |umi| {
9067 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;9117 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
9068 const prog_name = std.mem.print(&prog_name_buf, "{f}", .{9118 const prog_name = std.mem.print(&prog_name_buf, "{f}", .{
...@@ -9072,25 +9122,7 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {...@@ -9072,25 +9122,7 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {
9072 defer prog_node.end();9122 defer prog_node.end();
9073 try elf.genUav(pt, umi);9123 try elf.genUav(pt, umi);
9074 }9124 }
90759125 try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf });
9076 var lazy_it = elf.lazy.iterator();
9077 while (lazy_it.next()) |lazy| while (lazy.value.pending_index < lazy.value.map.count()) {
9078 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
9079 lazy.value.pending_index += 1;
9080 const lazy_ty: Type = .fromInterned(lmr.lazySymbol(elf).ty);
9081 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
9082 const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(zcu)) {
9083 .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
9084 .error_set => switch (lmr.kind) {
9085 .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
9086 .const_data => "@errorName",
9087 },
9088 else => unreachable,
9089 };
9090 const prog_node = elf.synth_prog_node.start(prog_name, 0);
9091 defer prog_node.end();
9092 try elf.genLazy(pt, lmr);
9093 };
9094}9126}
90959127
9096fn genUav(9128fn genUav(
test/incremental/no_change_preserves_tag_names deleted-18
...@@ -1,18 +0,0 @@
1#update=initial version
2#file=main.zig
3const std = @import("std");
4var some_enum: enum { first, second } = .first;
5const io = std.Io.Threaded.global_single_threaded.io();
6pub fn main() !void {
7 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
8}
9#expect_stdout="first"
10#update=no change
11#file=main.zig
12const std = @import("std");
13var some_enum: enum { first, second } = .first;
14const io = std.Io.Threaded.global_single_threaded.io();
15pub fn main() !void {
16 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
17}
18#expect_stdout="first"
test/incremental/tag_name created+27
...@@ -0,0 +1,27 @@
1#update=initial version
2#file=main.zig
3const std = @import("std");
4var some_enum: enum { first, second } = .first;
5const io = std.Io.Threaded.global_single_threaded.io();
6pub fn main() !void {
7 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
8}
9#expect_stdout="first"
10#update=no change
11#file=main.zig
12const std = @import("std");
13var some_enum: enum { first, second } = .first;
14const io = std.Io.Threaded.global_single_threaded.io();
15pub fn main() !void {
16 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
17}
18#expect_stdout="first"
19#update=swap fields
20#file=main.zig
21const std = @import("std");
22var some_enum: enum { second, first } = .first;
23const io = std.Io.Threaded.global_single_threaded.io();
24pub fn main() !void {
25 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
26}
27#expect_stdout="first"