Skip to content

Commit 41786fa

Browse files
authored
Merge pull request #22412 from mlugg/line-number-incremental
incremental: debug line number updates
2 parents b039a8b + dde3116 commit 41786fa

20 files changed

+917
-513
lines changed

ci/x86_64-linux-debug.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
6464

6565
stage3-debug/bin/zig build test docs \
6666
--maxrss 21000000000 \
67-
-Dlldb=$HOME/deps/lldb-zig/Debug-bfeada333/bin/lldb \
67+
-Dlldb=$HOME/deps/lldb-zig/Debug-e0a42bb34/bin/lldb \
6868
-fqemu \
6969
-fwasmtime \
7070
-Dstatic-llvm \

ci/x86_64-linux-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
6464

6565
stage3-release/bin/zig build test docs \
6666
--maxrss 21000000000 \
67-
-Dlldb=$HOME/deps/lldb-zig/Release-bfeada333/bin/lldb \
67+
-Dlldb=$HOME/deps/lldb-zig/Release-e0a42bb34/bin/lldb \
6868
-fqemu \
6969
-fwasmtime \
7070
-Dstatic-llvm \

src/Compilation.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ const Job = union(enum) {
348348
/// Corresponds to the task in `link.Task`.
349349
/// Only needed for backends that haven't yet been updated to not race against Sema.
350350
codegen_type: InternPool.Index,
351+
update_line_number: InternPool.TrackedInst.Index,
351352
/// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed.
352353
/// This may be its first time being analyzed, or it may be outdated.
353354
/// If the unit is a function, a `codegen_func` job will then be queued.
@@ -3718,6 +3719,9 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
37183719
.codegen_type => |ty| {
37193720
comp.dispatchCodegenTask(tid, .{ .codegen_type = ty });
37203721
},
3722+
.update_line_number => |ti| {
3723+
comp.dispatchCodegenTask(tid, .{ .update_line_number = ti });
3724+
},
37213725
.analyze_func => |func| {
37223726
const named_frame = tracy.namedFrame("analyze_func");
37233727
defer named_frame.end();

src/InternPool.zig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ pub const TrackedInst = extern struct {
168168
_ => @enumFromInt(@intFromEnum(opt)),
169169
};
170170
}
171+
172+
const debug_state = InternPool.debug_state;
171173
};
172174

173175
pub const Unwrapped = struct {
@@ -187,6 +189,8 @@ pub const TrackedInst = extern struct {
187189
.index = @intFromEnum(tracked_inst_index) & ip.getIndexMask(u32),
188190
};
189191
}
192+
193+
const debug_state = InternPool.debug_state;
190194
};
191195
};
192196

@@ -508,7 +512,7 @@ pub const Nav = struct {
508512
/// The fully-qualified name of this `Nav`.
509513
fqn: NullTerminatedString,
510514
/// This field is populated iff this `Nav` is resolved by semantic analysis.
511-
/// If this is `null`, then `status == .resolved` always.
515+
/// If this is `null`, then `status == .fully_resolved` always.
512516
analysis: ?struct {
513517
namespace: NamespaceIndex,
514518
zir_index: TrackedInst.Index,
@@ -6631,6 +6635,8 @@ pub fn activate(ip: *const InternPool) void {
66316635
_ = OptionalString.debug_state;
66326636
_ = NullTerminatedString.debug_state;
66336637
_ = OptionalNullTerminatedString.debug_state;
6638+
_ = TrackedInst.Index.debug_state;
6639+
_ = TrackedInst.Index.Optional.debug_state;
66346640
_ = Nav.Index.debug_state;
66356641
_ = Nav.Index.Optional.debug_state;
66366642
std.debug.assert(debug_state.intern_pool == null);

src/Zcu/PerThread.zig

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ fn cleanupUpdatedFiles(gpa: Allocator, updated_files: *std.AutoArrayHashMapUnman
379379
pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
380380
assert(pt.tid == .main);
381381
const zcu = pt.zcu;
382+
const comp = zcu.comp;
382383
const ip = &zcu.intern_pool;
383384
const gpa = zcu.gpa;
384385

@@ -435,8 +436,19 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
435436

436437
const old_zir = file.prev_zir.?.*;
437438
const new_zir = file.zir;
438-
const old_tag = old_zir.instructions.items(.tag);
439-
const old_data = old_zir.instructions.items(.data);
439+
const old_tag = old_zir.instructions.items(.tag)[@intFromEnum(old_inst)];
440+
const old_data = old_zir.instructions.items(.data)[@intFromEnum(old_inst)];
441+
442+
switch (old_tag) {
443+
.declaration => {
444+
const old_line = old_zir.getDeclaration(old_inst).src_line;
445+
const new_line = new_zir.getDeclaration(new_inst).src_line;
446+
if (old_line != new_line) {
447+
try comp.queueJob(.{ .update_line_number = tracked_inst_index });
448+
}
449+
},
450+
else => {},
451+
}
440452

441453
if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
442454
if (new_zir.getAssociatedSrcHash(new_inst)) |new_hash| {
@@ -455,8 +467,8 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
455467
}
456468

457469
// If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
458-
const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
459-
.extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
470+
const has_namespace = switch (old_tag) {
471+
.extended => switch (old_data.extended.opcode) {
460472
.struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
461473
else => false,
462474
},
@@ -2517,8 +2529,6 @@ const ScanDeclIter = struct {
25172529
);
25182530
try comp.queueJob(.{ .analyze_comptime_unit = unit });
25192531
}
2520-
2521-
// TODO: we used to do line number updates here, but this is an inappropriate place for this logic to live.
25222532
}
25232533
};
25242534

@@ -3152,6 +3162,15 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void
31523162
}
31533163
}
31543164

3165+
pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Index) !void {
3166+
if (pt.zcu.comp.bin_file) |lf| {
3167+
lf.updateLineNumber(pt, ti) catch |err| switch (err) {
3168+
error.OutOfMemory => return error.OutOfMemory,
3169+
else => |e| log.err("update line number failed: {s}", .{@errorName(e)}),
3170+
};
3171+
}
3172+
}
3173+
31553174
pub fn reportRetryableAstGenError(
31563175
pt: Zcu.PerThread,
31573176
src: Zcu.AstGenSrc,

src/link.zig

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -727,16 +727,22 @@ pub const File = struct {
727727
}
728728
}
729729

730-
pub fn updateNavLineNumber(
731-
base: *File,
732-
pt: Zcu.PerThread,
733-
nav_index: InternPool.Nav.Index,
734-
) UpdateNavError!void {
730+
/// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because
731+
/// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.
732+
pub fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateNavError!void {
733+
{
734+
const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;
735+
const file = pt.zcu.fileByIndex(ti.file);
736+
assert(file.zir_loaded);
737+
const inst = file.zir.instructions.get(@intFromEnum(ti.inst));
738+
assert(inst.tag == .declaration);
739+
}
740+
735741
switch (base.tag) {
736742
.spirv, .nvptx => {},
737743
inline else => |tag| {
738744
dev.check(tag.devFeature());
739-
return @as(*tag.Type(), @fieldParentPtr("base", base)).updateNavineNumber(pt, nav_index);
745+
return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id);
740746
},
741747
}
742748
}
@@ -1407,6 +1413,8 @@ pub const Task = union(enum) {
14071413
codegen_func: CodegenFunc,
14081414
codegen_type: InternPool.Index,
14091415

1416+
update_line_number: InternPool.TrackedInst.Index,
1417+
14101418
pub const CodegenFunc = struct {
14111419
/// This will either be a non-generic `func_decl` or a `func_instance`.
14121420
func: InternPool.Index,
@@ -1558,6 +1566,13 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
15581566
error.OutOfMemory => diags.setAllocFailure(),
15591567
};
15601568
},
1569+
.update_line_number => |ti| {
1570+
const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
1571+
defer pt.deactivate();
1572+
pt.linkerUpdateLineNumber(ti) catch |err| switch (err) {
1573+
error.OutOfMemory => diags.setAllocFailure(),
1574+
};
1575+
},
15611576
}
15621577
}
15631578

src/link/C.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,12 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !
379379
gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
380380
}
381381

382-
pub fn updateNavLineNumber(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
382+
pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
383383
// The C backend does not have the ability to fix line numbers without re-generating
384384
// the entire Decl.
385385
_ = self;
386386
_ = pt;
387-
_ = nav_index;
387+
_ = ti_id;
388388
}
389389

390390
pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {

src/link/Coff.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,11 +2484,11 @@ pub fn getGlobalSymbol(coff: *Coff, name: []const u8, lib_name_name: ?[]const u8
24842484
return global_index;
24852485
}
24862486

2487-
pub fn updateDeclLineNumber(coff: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
2487+
pub fn updateLineNumber(coff: *Coff, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
24882488
_ = coff;
24892489
_ = pt;
2490-
_ = decl_index;
2491-
log.debug("TODO implement updateDeclLineNumber", .{});
2490+
_ = ti_id;
2491+
log.debug("TODO implement updateLineNumber", .{});
24922492
}
24932493

24942494
/// TODO: note if we need to rewrite base relocations by dirtying any of the entries in the global table

0 commit comments

Comments
 (0)