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 {...@@ -4754,7 +4754,7 @@ pub const FuncGen = struct {
47544754
4755 inlined: std.ArrayListUnmanaged(struct {4755 inlined: std.ArrayListUnmanaged(struct {
4756 base_line: u32,4756 base_line: u32,
4757 location: Builder.Metadata,4757 location: Builder.DebugLocation,
4758 scope: Builder.Metadata,4758 scope: Builder.Metadata,
4759 }) = .{},4759 }) = .{},
47604760
...@@ -6574,17 +6574,20 @@ pub const FuncGen = struct {...@@ -6574,17 +6574,20 @@ pub const FuncGen = struct {
6574 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;6574 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
6575 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);6575 self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
6576 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);6576 self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
6577 const inlined_at = if (self.inlined.items.len > 0)6577
6578 self.inlined.items[self.inlined.items.len - 1].location6578 const inlined_at_location = if (self.inlined.getLastOrNull()) |inlined|
6579 try inlined.location.toMetadata(self.wip.builder)
6579 else6580 else
6580 .none;6581 .none;
65816582
6582 self.wip.current_debug_location = try self.wip.builder.debugLocation(6583 self.wip.debug_location = .{
6583 self.prev_dbg_line,6584 .location = .{
6584 self.prev_dbg_column,6585 .line = self.prev_dbg_line,
6585 self.scope,6586 .column = self.prev_dbg_column,
6586 inlined_at,6587 .scope = self.scope,
6587 );6588 .inlined_at = inlined_at_location,
6589 },
6590 };
65886591
6589 return .none;6592 return .none;
6590 }6593 }
...@@ -6605,7 +6608,7 @@ pub const FuncGen = struct {...@@ -6605,7 +6608,7 @@ pub const FuncGen = struct {
66056608
6606 const line_number = decl.src_line + 1;6609 const line_number = decl.src_line + 1;
6607 try self.inlined.append(self.gpa, .{6610 try self.inlined.append(self.gpa, .{
6608 .location = self.wip.current_debug_location,6611 .location = self.wip.debug_location,
6609 .scope = self.scope,6612 .scope = self.scope,
6610 .base_line = self.base_line,6613 .base_line = self.base_line,
6611 });6614 });
...@@ -6644,13 +6647,15 @@ pub const FuncGen = struct {...@@ -6644,13 +6647,15 @@ pub const FuncGen = struct {
6644 );6647 );
6645 self.scope = lexical_block;6648 self.scope = lexical_block;
6646 self.base_line = decl.src_line;6649 self.base_line = decl.src_line;
6647 const inlined_at = self.wip.current_debug_location;6650 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
6648 self.wip.current_debug_location = try o.builder.debugLocation(6651 self.wip.debug_location = .{
6649 line_number,6652 .location = .{
6650 0,6653 .line = line_number,
6651 self.scope,6654 .column = 0,
6652 inlined_at,6655 .scope = self.scope,
6653 );6656 .inlined_at = inlined_at_location,
6657 },
6658 };
6654 return .none;6659 return .none;
6655 }6660 }
66566661
...@@ -6667,7 +6672,7 @@ pub const FuncGen = struct {...@@ -6667,7 +6672,7 @@ pub const FuncGen = struct {
6667 const old = self.inlined.pop();6672 const old = self.inlined.pop();
6668 self.scope = old.scope;6673 self.scope = old.scope;
6669 self.base_line = old.base_line;6674 self.base_line = old.base_line;
6670 self.wip.current_debug_location = old.location;6675 self.wip.debug_location = old.location;
6671 return .none;6676 return .none;
6672 }6677 }
66736678
...@@ -8828,13 +8833,15 @@ pub const FuncGen = struct {...@@ -8828,13 +8833,15 @@ pub const FuncGen = struct {
8828 @intCast(self.arg_index),8833 @intCast(self.arg_index),
8829 );8834 );
88308835
8831 const old_location = self.wip.current_debug_location;8836 const old_location = self.wip.debug_location;
8832 self.wip.current_debug_location = try o.builder.debugLocation(8837 self.wip.debug_location = .{
8833 lbrace_line,8838 .location = .{
8834 lbrace_col,8839 .line = lbrace_line,
8835 self.scope,8840 .column = lbrace_col,
8836 .none,8841 .scope = self.scope,
8837 );8842 .inlined_at = .none,
8843 },
8844 };
88388845
8839 const owner_mod = self.dg.ownerModule();8846 const owner_mod = self.dg.ownerModule();
8840 if (isByRef(inst_ty, mod)) {8847 if (isByRef(inst_ty, mod)) {
...@@ -8881,7 +8888,7 @@ pub const FuncGen = struct {...@@ -8881,7 +8888,7 @@ pub const FuncGen = struct {
8881 );8888 );
8882 }8889 }
88838890
8884 self.wip.current_debug_location = old_location;8891 self.wip.debug_location = old_location;
8885 return arg_val;8892 return arg_val;
8886 }8893 }
88878894
...@@ -11727,15 +11734,15 @@ fn buildAllocaInner(...@@ -11727,15 +11734,15 @@ fn buildAllocaInner(
1172711734
11728 const alloca = blk: {11735 const alloca = blk: {
11729 const prev_cursor = wip.cursor;11736 const prev_cursor = wip.cursor;
11730 const prev_debug_location = wip.current_debug_location;11737 const prev_debug_location = wip.debug_location;
11731 defer {11738 defer {
11732 wip.cursor = prev_cursor;11739 wip.cursor = prev_cursor;
11733 if (wip.cursor.block == .entry) wip.cursor.instruction += 1;11740 if (wip.cursor.block == .entry) wip.cursor.instruction += 1;
11734 wip.current_debug_location = prev_debug_location;11741 wip.debug_location = prev_debug_location;
11735 }11742 }
1173611743
11737 wip.cursor = .{ .block = .entry };11744 wip.cursor = .{ .block = .entry };
11738 wip.current_debug_location = .none;11745 wip.debug_location = .no_location;
11739 break :blk try wip.alloca(.normal, llvm_ty, .none, alignment, address_space, "");11746 break :blk try wip.alloca(.normal, llvm_ty, .none, alignment, address_space, "");
11740 };11747 };
1174111748
src/codegen/llvm/Builder.zig+81-34
...@@ -3797,7 +3797,7 @@ pub const Function = struct {...@@ -3797,7 +3797,7 @@ pub const Function = struct {
3797 instructions: std.MultiArrayList(Instruction) = .{},3797 instructions: std.MultiArrayList(Instruction) = .{},
3798 names: [*]const String = &[0]String{},3798 names: [*]const String = &[0]String{},
3799 value_indices: [*]const u32 = &[0]u32{},3799 value_indices: [*]const u32 = &[0]u32{},
3800 debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{},3800 debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{},
3801 debug_values: []const Instruction.Index = &.{},3801 debug_values: []const Instruction.Index = &.{},
3802 extra: []const u32 = &.{},3802 extra: []const u32 = &.{},
38033803
...@@ -4857,16 +4857,40 @@ pub const Function = struct {...@@ -4857,16 +4857,40 @@ pub const Function = struct {
4857 }4857 }
4858};4858};
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
4860pub const WipFunction = struct {4884pub const WipFunction = struct {
4861 builder: *Builder,4885 builder: *Builder,
4862 function: Function.Index,4886 function: Function.Index,
4863 last_debug_location: Metadata,4887 prev_debug_location: DebugLocation,
4864 current_debug_location: Metadata,4888 debug_location: DebugLocation,
4865 cursor: Cursor,4889 cursor: Cursor,
4866 blocks: std.ArrayListUnmanaged(Block),4890 blocks: std.ArrayListUnmanaged(Block),
4867 instructions: std.MultiArrayList(Instruction),4891 instructions: std.MultiArrayList(Instruction),
4868 names: std.ArrayListUnmanaged(String),4892 names: std.ArrayListUnmanaged(String),
4869 debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, Metadata),4893 debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, DebugLocation),
4870 debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void),4894 debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void),
4871 extra: std.ArrayListUnmanaged(u32),4895 extra: std.ArrayListUnmanaged(u32),
48724896
...@@ -4902,8 +4926,8 @@ pub const WipFunction = struct {...@@ -4902,8 +4926,8 @@ pub const WipFunction = struct {
4902 var self: WipFunction = .{4926 var self: WipFunction = .{
4903 .builder = builder,4927 .builder = builder,
4904 .function = function,4928 .function = function,
4905 .last_debug_location = .none,4929 .prev_debug_location = .no_location,
4906 .current_debug_location = .none,4930 .debug_location = .no_location,
4907 .cursor = undefined,4931 .cursor = undefined,
4908 .blocks = .{},4932 .blocks = .{},
4909 .instructions = .{},4933 .instructions = .{},
...@@ -5850,7 +5874,7 @@ pub const WipFunction = struct {...@@ -5850,7 +5874,7 @@ pub const WipFunction = struct {
5850 const value_indices = try gpa.alloc(u32, final_instructions_len);5874 const value_indices = try gpa.alloc(u32, final_instructions_len);
5851 errdefer gpa.free(value_indices);5875 errdefer gpa.free(value_indices);
58525876
5853 var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{};5877 var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{};
5854 errdefer debug_locations.deinit(gpa);5878 errdefer debug_locations.deinit(gpa);
5855 try debug_locations.ensureUnusedCapacity(gpa, @intCast(self.debug_locations.count()));5879 try debug_locations.ensureUnusedCapacity(gpa, @intCast(self.debug_locations.count()));
58565880
...@@ -6494,10 +6518,10 @@ pub const WipFunction = struct {...@@ -6494,10 +6518,10 @@ pub const WipFunction = struct {
6494 if (!self.builder.strip) {6518 if (!self.builder.strip) {
6495 self.names.appendAssumeCapacity(final_name);6519 self.names.appendAssumeCapacity(final_name);
6496 if (block_instructions.items.len == 0 or6520 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))
6498 {6522 {
6499 self.debug_locations.putAssumeCapacity(index, self.current_debug_location);6523 self.debug_locations.putAssumeCapacity(index, self.debug_location);
6500 self.last_debug_location = self.current_debug_location;6524 self.prev_debug_location = self.debug_location;
6501 }6525 }
6502 }6526 }
6503 block_instructions.insertAssumeCapacity(self.cursor.instruction, index);6527 block_instructions.insertAssumeCapacity(self.cursor.instruction, index);
...@@ -8002,7 +8026,10 @@ pub const Metadata = enum(u32) {...@@ -8002,7 +8026,10 @@ pub const Metadata = enum(u32) {
8002 const Formatter = struct {8026 const Formatter = struct {
8003 builder: *Builder,8027 builder: *Builder,
8004 need_comma: bool,8028 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
8007 const FormatData = struct {8034 const FormatData = struct {
8008 formatter: *Formatter,8035 formatter: *Formatter,
...@@ -8190,7 +8217,7 @@ pub const Metadata = enum(u32) {...@@ -8190,7 +8217,7 @@ pub const Metadata = enum(u32) {
8190 .expression, .constant => return .{ .@"inline" = unwrapped_metadata },8217 .expression, .constant => return .{ .@"inline" = unwrapped_metadata },
8191 else => {8218 else => {
8192 assert(!tag.isInline());8219 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 });
8194 return .{ .index = @intCast(gop.index) };8221 return .{ .index = @intCast(gop.index) };
8195 },8222 },
8196 }8223 }
...@@ -9409,12 +9436,19 @@ pub fn printUnbuffered(...@@ -9409,12 +9436,19 @@ pub fn printUnbuffered(
9409 if (function.instructions.len > 0) {9436 if (function.instructions.len > 0) {
9410 var block_incoming_len: u32 = undefined;9437 var block_incoming_len: u32 = undefined;
9411 try writer.writeAll(" {\n");9438 try writer.writeAll(" {\n");
9412 var dbg: Metadata = .none;9439 var maybe_dbg_index: ?u32 = null;
9413 for (params_len..function.instructions.len) |instruction_i| {9440 for (params_len..function.instructions.len) |instruction_i| {
9414 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);9441 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
9415 const instruction = function.instructions.get(@intFromEnum(instruction_index));9442 const instruction = function.instructions.get(@intFromEnum(instruction_index));
9416 if (function.debug_locations.get(instruction_index)) |debug_location|9443 if (function.debug_locations.get(instruction_index)) |debug_location| switch (debug_location) {
9417 dbg = 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 };
9418 switch (instruction.tag) {9452 switch (instruction.tag) {
9419 .add,9453 .add,
9420 .@"add nsw",9454 .@"add nsw",
...@@ -9846,9 +9880,10 @@ pub fn printUnbuffered(...@@ -9846,9 +9880,10 @@ pub fn printUnbuffered(
9846 });9880 });
9847 },9881 },
9848 }9882 }
9849 metadata_formatter.need_comma = true;9883
9850 defer metadata_formatter.need_comma = undefined;9884 if (maybe_dbg_index) |dbg_index| {
9851 try writer.print("{}\n", .{try metadata_formatter.fmt("!dbg ", dbg)});9885 try writer.print(", !dbg !{}\n", .{dbg_index});
9886 } else try writer.writeByte('\n');
9852 }9887 }
9853 try writer.writeByte('}');9888 try writer.writeByte('}');
9854 }9889 }
...@@ -9884,11 +9919,25 @@ pub fn printUnbuffered(...@@ -9884,11 +9919,25 @@ pub fn printUnbuffered(
9884 var metadata_index: usize = 0;9919 var metadata_index: usize = 0;
9885 while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) {9920 while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) {
9886 @setEvalBranchQuota(10_000);9921 @setEvalBranchQuota(10_000);
9887 const metadata_item =
9888 self.metadata_items.get(@intFromEnum(metadata_formatter.map.keys()[metadata_index]));
9889 try writer.print("!{} = ", .{metadata_index});9922 try writer.print("!{} = ", .{metadata_index});
9890 metadata_formatter.need_comma = false;9923 metadata_formatter.need_comma = false;
9891 defer metadata_formatter.need_comma = undefined;9924 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
9892 switch (metadata_item.tag) {9941 switch (metadata_item.tag) {
9893 .none, .expression, .constant => unreachable,9942 .none, .expression, .constant => unreachable,
9894 .file => {9943 .file => {
...@@ -14866,20 +14915,18 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co...@@ -14866,20 +14915,18 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
1486614915
14867 if (!self.strip) {14916 if (!self.strip) {
14868 if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| {14917 if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| {
14869 if (debug_location != .none) {14918 switch (debug_location) {
14870 const location = self.metadata_items.get(@intFromEnum(debug_location));14919 .no_location => has_location = false,
14871 assert(location.tag == .location);14920 .location => |location| {
14872 const extra = self.metadataExtraData(Metadata.Location, location.data);14921 try function_block.writeAbbrev(FunctionBlock.DebugLoc{
14873 try function_block.writeAbbrev(FunctionBlock.DebugLoc{14922 .line = location.line,
14874 .line = extra.line,14923 .column = location.column,
14875 .column = extra.column,14924 .scope = @enumFromInt(metadata_adapter.getMetadataIndex(location.scope)),
14876 .scope = @enumFromInt(metadata_adapter.getMetadataIndex(extra.scope)),14925 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(location.inlined_at)),
14877 .inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)),14926 .is_implicit = false,
14878 .is_implicit = false,14927 });
14879 });14928 has_location = true;
14880 has_location = true;14929 },
14881 } else {
14882 has_location = false;
14883 }14930 }
14884 } else if (has_location) {14931 } else if (has_location) {
14885 try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{});14932 try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{});