authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-25 17:03:45+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-25 17:03:45+01:00
log661137ac92ef05490a22dfcfb812a81a3014f0c7
tree4d4a5069c6139694b4e7ea13a6891a1588fd8a91
parent9d7082972e8df9105b48a806e7bfabca90d4dc1b
parent71d9f3a86b61c815031e42a24c3081e868870e46
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19074 from antlilja/llvm-debug-loc

Rework LLVM debug locations to not emit them twice

2 files changed, 117 insertions(+), 63 deletions(-)

src/codegen/llvm.zig+36-29
......@@ -4754,7 +4754,7 @@ pub const FuncGen = struct {
47544754
47554755 inlined: std.ArrayListUnmanaged(struct {
47564756 base_line: u32,
4757 location: Builder.Metadata,
4757 location: Builder.DebugLocation,
47584758 scope: Builder.Metadata,
47594759 }) = .{},
47604760
......@@ -6574,17 +6574,20 @@ pub const FuncGen = struct {
65746574 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
65756575 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
65766576 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
6577 const inlined_at = if (self.inlined.items.len > 0)
6578 self.inlined.items[self.inlined.items.len - 1].location
6577
6578 const inlined_at_location = if (self.inlined.getLastOrNull()) |inlined|
6579 try inlined.location.toMetadata(self.wip.builder)
65796580 else
65806581 .none;
65816582
6582 self.wip.current_debug_location = try self.wip.builder.debugLocation(
6583 self.prev_dbg_line,
6584 self.prev_dbg_column,
6585 self.scope,
6586 inlined_at,
6587 );
6583 self.wip.debug_location = .{
6584 .location = .{
6585 .line = self.prev_dbg_line,
6586 .column = self.prev_dbg_column,
6587 .scope = self.scope,
6588 .inlined_at = inlined_at_location,
6589 },
6590 };
65886591
65896592 return .none;
65906593 }
......@@ -6605,7 +6608,7 @@ pub const FuncGen = struct {
66056608
66066609 const line_number = decl.src_line + 1;
66076610 try self.inlined.append(self.gpa, .{
6608 .location = self.wip.current_debug_location,
6611 .location = self.wip.debug_location,
66096612 .scope = self.scope,
66106613 .base_line = self.base_line,
66116614 });
......@@ -6644,13 +6647,15 @@ pub const FuncGen = struct {
66446647 );
66456648 self.scope = lexical_block;
66466649 self.base_line = decl.src_line;
6647 const inlined_at = self.wip.current_debug_location;
6648 self.wip.current_debug_location = try o.builder.debugLocation(
6649 line_number,
6650 0,
6651 self.scope,
6652 inlined_at,
6653 );
6650 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
6651 self.wip.debug_location = .{
6652 .location = .{
6653 .line = line_number,
6654 .column = 0,
6655 .scope = self.scope,
6656 .inlined_at = inlined_at_location,
6657 },
6658 };
66546659 return .none;
66556660 }
66566661
......@@ -6667,7 +6672,7 @@ pub const FuncGen = struct {
66676672 const old = self.inlined.pop();
66686673 self.scope = old.scope;
66696674 self.base_line = old.base_line;
6670 self.wip.current_debug_location = old.location;
6675 self.wip.debug_location = old.location;
66716676 return .none;
66726677 }
66736678
......@@ -8828,13 +8833,15 @@ pub const FuncGen = struct {
88288833 @intCast(self.arg_index),
88298834 );
88308835
8831 const old_location = self.wip.current_debug_location;
8832 self.wip.current_debug_location = try o.builder.debugLocation(
8833 lbrace_line,
8834 lbrace_col,
8835 self.scope,
8836 .none,
8837 );
8836 const old_location = self.wip.debug_location;
8837 self.wip.debug_location = .{
8838 .location = .{
8839 .line = lbrace_line,
8840 .column = lbrace_col,
8841 .scope = self.scope,
8842 .inlined_at = .none,
8843 },
8844 };
88388845
88398846 const owner_mod = self.dg.ownerModule();
88408847 if (isByRef(inst_ty, mod)) {
......@@ -8881,7 +8888,7 @@ pub const FuncGen = struct {
88818888 );
88828889 }
88838890
8884 self.wip.current_debug_location = old_location;
8891 self.wip.debug_location = old_location;
88858892 return arg_val;
88868893 }
88878894
......@@ -11727,15 +11734,15 @@ fn buildAllocaInner(
1172711734
1172811735 const alloca = blk: {
1172911736 const prev_cursor = wip.cursor;
11730 const prev_debug_location = wip.current_debug_location;
11737 const prev_debug_location = wip.debug_location;
1173111738 defer {
1173211739 wip.cursor = prev_cursor;
1173311740 if (wip.cursor.block == .entry) wip.cursor.instruction += 1;
11734 wip.current_debug_location = prev_debug_location;
11741 wip.debug_location = prev_debug_location;
1173511742 }
1173611743
1173711744 wip.cursor = .{ .block = .entry };
11738 wip.current_debug_location = .none;
11745 wip.debug_location = .no_location;
1173911746 break :blk try wip.alloca(.normal, llvm_ty, .none, alignment, address_space, "");
1174011747 };
1174111748
src/codegen/llvm/Builder.zig+81-34
......@@ -3797,7 +3797,7 @@ pub const Function = struct {
37973797 instructions: std.MultiArrayList(Instruction) = .{},
37983798 names: [*]const String = &[0]String{},
37993799 value_indices: [*]const u32 = &[0]u32{},
3800 debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{},
3800 debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{},
38013801 debug_values: []const Instruction.Index = &.{},
38023802 extra: []const u32 = &.{},
38033803
......@@ -4857,16 +4857,40 @@ pub const Function = struct {
48574857 }
48584858};
48594859
4860pub const DebugLocation = union(enum) {
4861 no_location: void,
4862 location: Location,
4863
4864 pub const Location = struct {
4865 line: u32,
4866 column: u32,
4867 scope: Builder.Metadata,
4868 inlined_at: Builder.Metadata,
4869 };
4870
4871 pub fn toMetadata(self: DebugLocation, builder: *Builder) Allocator.Error!Metadata {
4872 return switch (self) {
4873 .no_location => .none,
4874 .location => |location| try builder.debugLocation(
4875 location.line,
4876 location.column,
4877 location.scope,
4878 location.inlined_at,
4879 ),
4880 };
4881 }
4882};
4883
48604884pub const WipFunction = struct {
48614885 builder: *Builder,
48624886 function: Function.Index,
4863 last_debug_location: Metadata,
4864 current_debug_location: Metadata,
4887 prev_debug_location: DebugLocation,
4888 debug_location: DebugLocation,
48654889 cursor: Cursor,
48664890 blocks: std.ArrayListUnmanaged(Block),
48674891 instructions: std.MultiArrayList(Instruction),
48684892 names: std.ArrayListUnmanaged(String),
4869 debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, Metadata),
4893 debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, DebugLocation),
48704894 debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void),
48714895 extra: std.ArrayListUnmanaged(u32),
48724896
......@@ -4902,8 +4926,8 @@ pub const WipFunction = struct {
49024926 var self: WipFunction = .{
49034927 .builder = builder,
49044928 .function = function,
4905 .last_debug_location = .none,
4906 .current_debug_location = .none,
4929 .prev_debug_location = .no_location,
4930 .debug_location = .no_location,
49074931 .cursor = undefined,
49084932 .blocks = .{},
49094933 .instructions = .{},
......@@ -5850,7 +5874,7 @@ pub const WipFunction = struct {
58505874 const value_indices = try gpa.alloc(u32, final_instructions_len);
58515875 errdefer gpa.free(value_indices);
58525876
5853 var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{};
5877 var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{};
58545878 errdefer debug_locations.deinit(gpa);
58555879 try debug_locations.ensureUnusedCapacity(gpa, @intCast(self.debug_locations.count()));
58565880
......@@ -6494,10 +6518,10 @@ pub const WipFunction = struct {
64946518 if (!self.builder.strip) {
64956519 self.names.appendAssumeCapacity(final_name);
64966520 if (block_instructions.items.len == 0 or
6497 self.current_debug_location != self.last_debug_location)
6521 !std.meta.eql(self.debug_location, self.prev_debug_location))
64986522 {
6499 self.debug_locations.putAssumeCapacity(index, self.current_debug_location);
6500 self.last_debug_location = self.current_debug_location;
6523 self.debug_locations.putAssumeCapacity(index, self.debug_location);
6524 self.prev_debug_location = self.debug_location;
65016525 }
65026526 }
65036527 block_instructions.insertAssumeCapacity(self.cursor.instruction, index);
......@@ -8002,7 +8026,10 @@ pub const Metadata = enum(u32) {
80028026 const Formatter = struct {
80038027 builder: *Builder,
80048028 need_comma: bool,
8005 map: std.AutoArrayHashMapUnmanaged(Metadata, void) = .{},
8029 map: std.AutoArrayHashMapUnmanaged(union(enum) {
8030 metadata: Metadata,
8031 debug_location: DebugLocation.Location,
8032 }, void) = .{},
80068033
80078034 const FormatData = struct {
80088035 formatter: *Formatter,
......@@ -8190,7 +8217,7 @@ pub const Metadata = enum(u32) {
81908217 .expression, .constant => return .{ .@"inline" = unwrapped_metadata },
81918218 else => {
81928219 assert(!tag.isInline());
8193 const gop = try formatter.map.getOrPutValue(builder.gpa, unwrapped_metadata, {});
8220 const gop = try formatter.map.getOrPut(builder.gpa, .{ .metadata = unwrapped_metadata });
81948221 return .{ .index = @intCast(gop.index) };
81958222 },
81968223 }
......@@ -9409,12 +9436,19 @@ pub fn printUnbuffered(
94099436 if (function.instructions.len > 0) {
94109437 var block_incoming_len: u32 = undefined;
94119438 try writer.writeAll(" {\n");
9412 var dbg: Metadata = .none;
9439 var maybe_dbg_index: ?u32 = null;
94139440 for (params_len..function.instructions.len) |instruction_i| {
94149441 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
94159442 const instruction = function.instructions.get(@intFromEnum(instruction_index));
9416 if (function.debug_locations.get(instruction_index)) |debug_location|
9417 dbg = debug_location;
9443 if (function.debug_locations.get(instruction_index)) |debug_location| switch (debug_location) {
9444 .no_location => maybe_dbg_index = null,
9445 .location => |location| {
9446 const gop = try metadata_formatter.map.getOrPut(self.gpa, .{
9447 .debug_location = location,
9448 });
9449 maybe_dbg_index = @intCast(gop.index);
9450 },
9451 };
94189452 switch (instruction.tag) {
94199453 .add,
94209454 .@"add nsw",
......@@ -9846,9 +9880,10 @@ pub fn printUnbuffered(
98469880 });
98479881 },
98489882 }
9849 metadata_formatter.need_comma = true;
9850 defer metadata_formatter.need_comma = undefined;
9851 try writer.print("{}\n", .{try metadata_formatter.fmt("!dbg ", dbg)});
9883
9884 if (maybe_dbg_index) |dbg_index| {
9885 try writer.print(", !dbg !{}\n", .{dbg_index});
9886 } else try writer.writeByte('\n');
98529887 }
98539888 try writer.writeByte('}');
98549889 }
......@@ -9884,11 +9919,25 @@ pub fn printUnbuffered(
98849919 var metadata_index: usize = 0;
98859920 while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) {
98869921 @setEvalBranchQuota(10_000);
9887 const metadata_item =
9888 self.metadata_items.get(@intFromEnum(metadata_formatter.map.keys()[metadata_index]));
98899922 try writer.print("!{} = ", .{metadata_index});
98909923 metadata_formatter.need_comma = false;
98919924 defer metadata_formatter.need_comma = undefined;
9925
9926 const key = metadata_formatter.map.keys()[metadata_index];
9927 const metadata_item = switch (key) {
9928 .debug_location => |location| {
9929 try metadata_formatter.specialized(.@"!", .DILocation, .{
9930 .line = location.line,
9931 .column = location.column,
9932 .scope = location.scope,
9933 .inlinedAt = location.inlined_at,
9934 .isImplicitCode = false,
9935 }, writer);
9936 continue;
9937 },
9938 .metadata => |metadata| self.metadata_items.get(@intFromEnum(metadata)),
9939 };
9940
98929941 switch (metadata_item.tag) {
98939942 .none, .expression, .constant => unreachable,
98949943 .file => {
......@@ -14866,20 +14915,18 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1486614915
1486714916 if (!self.strip) {
1486814917 if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| {
14869 if (debug_location != .none) {
14870 const location = self.metadata_items.get(@intFromEnum(debug_location));
14871 assert(location.tag == .location);
14872 const extra = self.metadataExtraData(Metadata.Location, location.data);
14873 try function_block.writeAbbrev(FunctionBlock.DebugLoc{
14874 .line = extra.line,
14875 .column = extra.column,
14876 .scope = @enumFromInt(metadata_adapter.getMetadataIndex(extra.scope)),
14877 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)),
14878 .is_implicit = false,
14879 });
14880 has_location = true;
14881 } else {
14882 has_location = false;
14918 switch (debug_location) {
14919 .no_location => has_location = false,
14920 .location => |location| {
14921 try function_block.writeAbbrev(FunctionBlock.DebugLoc{
14922 .line = location.line,
14923 .column = location.column,
14924 .scope = @enumFromInt(metadata_adapter.getMetadataIndex(location.scope)),
14925 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(location.inlined_at)),
14926 .is_implicit = false,
14927 });
14928 has_location = true;
14929 },
1488314930 }
1488414931 } else if (has_location) {
1488514932 try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{});