mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
Merge pull request #19074 from antlilja/llvm-debug-loc
Rework LLVM debug locations to not emit them twice
This commit is contained in:
commit
661137ac92
@ -4754,7 +4754,7 @@ pub const FuncGen = struct {
|
||||
|
||||
inlined: std.ArrayListUnmanaged(struct {
|
||||
base_line: u32,
|
||||
location: Builder.Metadata,
|
||||
location: Builder.DebugLocation,
|
||||
scope: Builder.Metadata,
|
||||
}) = .{},
|
||||
|
||||
@ -6574,17 +6574,20 @@ pub const FuncGen = struct {
|
||||
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
|
||||
self.prev_dbg_line = @intCast(self.base_line + dbg_stmt.line + 1);
|
||||
self.prev_dbg_column = @intCast(dbg_stmt.column + 1);
|
||||
const inlined_at = if (self.inlined.items.len > 0)
|
||||
self.inlined.items[self.inlined.items.len - 1].location
|
||||
|
||||
const inlined_at_location = if (self.inlined.getLastOrNull()) |inlined|
|
||||
try inlined.location.toMetadata(self.wip.builder)
|
||||
else
|
||||
.none;
|
||||
|
||||
self.wip.current_debug_location = try self.wip.builder.debugLocation(
|
||||
self.prev_dbg_line,
|
||||
self.prev_dbg_column,
|
||||
self.scope,
|
||||
inlined_at,
|
||||
);
|
||||
self.wip.debug_location = .{
|
||||
.location = .{
|
||||
.line = self.prev_dbg_line,
|
||||
.column = self.prev_dbg_column,
|
||||
.scope = self.scope,
|
||||
.inlined_at = inlined_at_location,
|
||||
},
|
||||
};
|
||||
|
||||
return .none;
|
||||
}
|
||||
@ -6605,7 +6608,7 @@ pub const FuncGen = struct {
|
||||
|
||||
const line_number = decl.src_line + 1;
|
||||
try self.inlined.append(self.gpa, .{
|
||||
.location = self.wip.current_debug_location,
|
||||
.location = self.wip.debug_location,
|
||||
.scope = self.scope,
|
||||
.base_line = self.base_line,
|
||||
});
|
||||
@ -6644,13 +6647,15 @@ pub const FuncGen = struct {
|
||||
);
|
||||
self.scope = lexical_block;
|
||||
self.base_line = decl.src_line;
|
||||
const inlined_at = self.wip.current_debug_location;
|
||||
self.wip.current_debug_location = try o.builder.debugLocation(
|
||||
line_number,
|
||||
0,
|
||||
self.scope,
|
||||
inlined_at,
|
||||
);
|
||||
const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
|
||||
self.wip.debug_location = .{
|
||||
.location = .{
|
||||
.line = line_number,
|
||||
.column = 0,
|
||||
.scope = self.scope,
|
||||
.inlined_at = inlined_at_location,
|
||||
},
|
||||
};
|
||||
return .none;
|
||||
}
|
||||
|
||||
@ -6667,7 +6672,7 @@ pub const FuncGen = struct {
|
||||
const old = self.inlined.pop();
|
||||
self.scope = old.scope;
|
||||
self.base_line = old.base_line;
|
||||
self.wip.current_debug_location = old.location;
|
||||
self.wip.debug_location = old.location;
|
||||
return .none;
|
||||
}
|
||||
|
||||
@ -8828,13 +8833,15 @@ pub const FuncGen = struct {
|
||||
@intCast(self.arg_index),
|
||||
);
|
||||
|
||||
const old_location = self.wip.current_debug_location;
|
||||
self.wip.current_debug_location = try o.builder.debugLocation(
|
||||
lbrace_line,
|
||||
lbrace_col,
|
||||
self.scope,
|
||||
.none,
|
||||
);
|
||||
const old_location = self.wip.debug_location;
|
||||
self.wip.debug_location = .{
|
||||
.location = .{
|
||||
.line = lbrace_line,
|
||||
.column = lbrace_col,
|
||||
.scope = self.scope,
|
||||
.inlined_at = .none,
|
||||
},
|
||||
};
|
||||
|
||||
const owner_mod = self.dg.ownerModule();
|
||||
if (isByRef(inst_ty, mod)) {
|
||||
@ -8881,7 +8888,7 @@ pub const FuncGen = struct {
|
||||
);
|
||||
}
|
||||
|
||||
self.wip.current_debug_location = old_location;
|
||||
self.wip.debug_location = old_location;
|
||||
return arg_val;
|
||||
}
|
||||
|
||||
@ -11727,15 +11734,15 @@ fn buildAllocaInner(
|
||||
|
||||
const alloca = blk: {
|
||||
const prev_cursor = wip.cursor;
|
||||
const prev_debug_location = wip.current_debug_location;
|
||||
const prev_debug_location = wip.debug_location;
|
||||
defer {
|
||||
wip.cursor = prev_cursor;
|
||||
if (wip.cursor.block == .entry) wip.cursor.instruction += 1;
|
||||
wip.current_debug_location = prev_debug_location;
|
||||
wip.debug_location = prev_debug_location;
|
||||
}
|
||||
|
||||
wip.cursor = .{ .block = .entry };
|
||||
wip.current_debug_location = .none;
|
||||
wip.debug_location = .no_location;
|
||||
break :blk try wip.alloca(.normal, llvm_ty, .none, alignment, address_space, "");
|
||||
};
|
||||
|
||||
|
||||
@ -3797,7 +3797,7 @@ pub const Function = struct {
|
||||
instructions: std.MultiArrayList(Instruction) = .{},
|
||||
names: [*]const String = &[0]String{},
|
||||
value_indices: [*]const u32 = &[0]u32{},
|
||||
debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{},
|
||||
debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{},
|
||||
debug_values: []const Instruction.Index = &.{},
|
||||
extra: []const u32 = &.{},
|
||||
|
||||
@ -4857,16 +4857,40 @@ pub const Function = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const DebugLocation = union(enum) {
|
||||
no_location: void,
|
||||
location: Location,
|
||||
|
||||
pub const Location = struct {
|
||||
line: u32,
|
||||
column: u32,
|
||||
scope: Builder.Metadata,
|
||||
inlined_at: Builder.Metadata,
|
||||
};
|
||||
|
||||
pub fn toMetadata(self: DebugLocation, builder: *Builder) Allocator.Error!Metadata {
|
||||
return switch (self) {
|
||||
.no_location => .none,
|
||||
.location => |location| try builder.debugLocation(
|
||||
location.line,
|
||||
location.column,
|
||||
location.scope,
|
||||
location.inlined_at,
|
||||
),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const WipFunction = struct {
|
||||
builder: *Builder,
|
||||
function: Function.Index,
|
||||
last_debug_location: Metadata,
|
||||
current_debug_location: Metadata,
|
||||
prev_debug_location: DebugLocation,
|
||||
debug_location: DebugLocation,
|
||||
cursor: Cursor,
|
||||
blocks: std.ArrayListUnmanaged(Block),
|
||||
instructions: std.MultiArrayList(Instruction),
|
||||
names: std.ArrayListUnmanaged(String),
|
||||
debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, Metadata),
|
||||
debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, DebugLocation),
|
||||
debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void),
|
||||
extra: std.ArrayListUnmanaged(u32),
|
||||
|
||||
@ -4902,8 +4926,8 @@ pub const WipFunction = struct {
|
||||
var self: WipFunction = .{
|
||||
.builder = builder,
|
||||
.function = function,
|
||||
.last_debug_location = .none,
|
||||
.current_debug_location = .none,
|
||||
.prev_debug_location = .no_location,
|
||||
.debug_location = .no_location,
|
||||
.cursor = undefined,
|
||||
.blocks = .{},
|
||||
.instructions = .{},
|
||||
@ -5850,7 +5874,7 @@ pub const WipFunction = struct {
|
||||
const value_indices = try gpa.alloc(u32, final_instructions_len);
|
||||
errdefer gpa.free(value_indices);
|
||||
|
||||
var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, Metadata) = .{};
|
||||
var debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, DebugLocation) = .{};
|
||||
errdefer debug_locations.deinit(gpa);
|
||||
try debug_locations.ensureUnusedCapacity(gpa, @intCast(self.debug_locations.count()));
|
||||
|
||||
@ -6494,10 +6518,10 @@ pub const WipFunction = struct {
|
||||
if (!self.builder.strip) {
|
||||
self.names.appendAssumeCapacity(final_name);
|
||||
if (block_instructions.items.len == 0 or
|
||||
self.current_debug_location != self.last_debug_location)
|
||||
!std.meta.eql(self.debug_location, self.prev_debug_location))
|
||||
{
|
||||
self.debug_locations.putAssumeCapacity(index, self.current_debug_location);
|
||||
self.last_debug_location = self.current_debug_location;
|
||||
self.debug_locations.putAssumeCapacity(index, self.debug_location);
|
||||
self.prev_debug_location = self.debug_location;
|
||||
}
|
||||
}
|
||||
block_instructions.insertAssumeCapacity(self.cursor.instruction, index);
|
||||
@ -8002,7 +8026,10 @@ pub const Metadata = enum(u32) {
|
||||
const Formatter = struct {
|
||||
builder: *Builder,
|
||||
need_comma: bool,
|
||||
map: std.AutoArrayHashMapUnmanaged(Metadata, void) = .{},
|
||||
map: std.AutoArrayHashMapUnmanaged(union(enum) {
|
||||
metadata: Metadata,
|
||||
debug_location: DebugLocation.Location,
|
||||
}, void) = .{},
|
||||
|
||||
const FormatData = struct {
|
||||
formatter: *Formatter,
|
||||
@ -8190,7 +8217,7 @@ pub const Metadata = enum(u32) {
|
||||
.expression, .constant => return .{ .@"inline" = unwrapped_metadata },
|
||||
else => {
|
||||
assert(!tag.isInline());
|
||||
const gop = try formatter.map.getOrPutValue(builder.gpa, unwrapped_metadata, {});
|
||||
const gop = try formatter.map.getOrPut(builder.gpa, .{ .metadata = unwrapped_metadata });
|
||||
return .{ .index = @intCast(gop.index) };
|
||||
},
|
||||
}
|
||||
@ -9409,12 +9436,19 @@ pub fn printUnbuffered(
|
||||
if (function.instructions.len > 0) {
|
||||
var block_incoming_len: u32 = undefined;
|
||||
try writer.writeAll(" {\n");
|
||||
var dbg: Metadata = .none;
|
||||
var maybe_dbg_index: ?u32 = null;
|
||||
for (params_len..function.instructions.len) |instruction_i| {
|
||||
const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
|
||||
const instruction = function.instructions.get(@intFromEnum(instruction_index));
|
||||
if (function.debug_locations.get(instruction_index)) |debug_location|
|
||||
dbg = debug_location;
|
||||
if (function.debug_locations.get(instruction_index)) |debug_location| switch (debug_location) {
|
||||
.no_location => maybe_dbg_index = null,
|
||||
.location => |location| {
|
||||
const gop = try metadata_formatter.map.getOrPut(self.gpa, .{
|
||||
.debug_location = location,
|
||||
});
|
||||
maybe_dbg_index = @intCast(gop.index);
|
||||
},
|
||||
};
|
||||
switch (instruction.tag) {
|
||||
.add,
|
||||
.@"add nsw",
|
||||
@ -9846,9 +9880,10 @@ pub fn printUnbuffered(
|
||||
});
|
||||
},
|
||||
}
|
||||
metadata_formatter.need_comma = true;
|
||||
defer metadata_formatter.need_comma = undefined;
|
||||
try writer.print("{}\n", .{try metadata_formatter.fmt("!dbg ", dbg)});
|
||||
|
||||
if (maybe_dbg_index) |dbg_index| {
|
||||
try writer.print(", !dbg !{}\n", .{dbg_index});
|
||||
} else try writer.writeByte('\n');
|
||||
}
|
||||
try writer.writeByte('}');
|
||||
}
|
||||
@ -9884,11 +9919,25 @@ pub fn printUnbuffered(
|
||||
var metadata_index: usize = 0;
|
||||
while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) {
|
||||
@setEvalBranchQuota(10_000);
|
||||
const metadata_item =
|
||||
self.metadata_items.get(@intFromEnum(metadata_formatter.map.keys()[metadata_index]));
|
||||
try writer.print("!{} = ", .{metadata_index});
|
||||
metadata_formatter.need_comma = false;
|
||||
defer metadata_formatter.need_comma = undefined;
|
||||
|
||||
const key = metadata_formatter.map.keys()[metadata_index];
|
||||
const metadata_item = switch (key) {
|
||||
.debug_location => |location| {
|
||||
try metadata_formatter.specialized(.@"!", .DILocation, .{
|
||||
.line = location.line,
|
||||
.column = location.column,
|
||||
.scope = location.scope,
|
||||
.inlinedAt = location.inlined_at,
|
||||
.isImplicitCode = false,
|
||||
}, writer);
|
||||
continue;
|
||||
},
|
||||
.metadata => |metadata| self.metadata_items.get(@intFromEnum(metadata)),
|
||||
};
|
||||
|
||||
switch (metadata_item.tag) {
|
||||
.none, .expression, .constant => unreachable,
|
||||
.file => {
|
||||
@ -14866,20 +14915,18 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
|
||||
|
||||
if (!self.strip) {
|
||||
if (func.debug_locations.get(@enumFromInt(instr_index))) |debug_location| {
|
||||
if (debug_location != .none) {
|
||||
const location = self.metadata_items.get(@intFromEnum(debug_location));
|
||||
assert(location.tag == .location);
|
||||
const extra = self.metadataExtraData(Metadata.Location, location.data);
|
||||
try function_block.writeAbbrev(FunctionBlock.DebugLoc{
|
||||
.line = extra.line,
|
||||
.column = extra.column,
|
||||
.scope = @enumFromInt(metadata_adapter.getMetadataIndex(extra.scope)),
|
||||
.inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(extra.inlined_at)),
|
||||
.is_implicit = false,
|
||||
});
|
||||
has_location = true;
|
||||
} else {
|
||||
has_location = false;
|
||||
switch (debug_location) {
|
||||
.no_location => has_location = false,
|
||||
.location => |location| {
|
||||
try function_block.writeAbbrev(FunctionBlock.DebugLoc{
|
||||
.line = location.line,
|
||||
.column = location.column,
|
||||
.scope = @enumFromInt(metadata_adapter.getMetadataIndex(location.scope)),
|
||||
.inlined_at = @enumFromInt(metadata_adapter.getMetadataIndex(location.inlined_at)),
|
||||
.is_implicit = false,
|
||||
});
|
||||
has_location = true;
|
||||
},
|
||||
}
|
||||
} else if (has_location) {
|
||||
try function_block.writeAbbrev(FunctionBlock.DebugLocAgain{});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user