authorgravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-19 23:04:13+01:00
committergravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-21 16:24:59+01:00
log049cad44113ad8851be95f691188402456551e3a
treefaea327b743ae0566cf1acb245e98e1af4036d77
parenta456631e2940ba53dc0e450bc4748cad9071f019

LLVM Builder: Add debug locations to instructions


1 files changed, 90 insertions(+), 14 deletions(-)

src/codegen/llvm/Builder.zig+90-14
......@@ -3935,6 +3935,8 @@ pub const Function = struct {
39353935 names: [*]const String = &[0]String{},
39363936 value_indices: [*]const u32 = &[0]u32{},
39373937 metadata: ?[*]const Metadata = null,
3938 debug_locations: std.AutoHashMapUnmanaged(Instruction.Index, ?DebugLocation) = .{},
3939 debug_values: []const Instruction.Index = &.{},
39383940 extra: []const u32 = &.{},
39393941
39403942 pub const Index = enum(u32) {
......@@ -5031,7 +5033,8 @@ pub const Function = struct {
50315033
50325034 pub fn deinit(self: *Function, gpa: Allocator) void {
50335035 gpa.free(self.extra);
5034 if (self.metadata) |metadata| gpa.free(metadata[0..self.instructions.len]);
5036 gpa.free(self.debug_values);
5037 self.debug_locations.deinit(gpa);
50355038 gpa.free(self.value_indices[0..self.instructions.len]);
50365039 gpa.free(self.names[0..self.instructions.len]);
50375040 self.instructions.deinit(gpa);
......@@ -5103,6 +5106,13 @@ pub const Function = struct {
51035106 }
51045107};
51055108
5109pub const DebugLocation = struct {
5110 line: u32,
5111 column: u32,
5112 scope: Metadata,
5113 inlined_at: Metadata,
5114};
5115
51065116pub const WipFunction = struct {
51075117 builder: *Builder,
51085118 function: Function.Index,
......@@ -5111,11 +5121,14 @@ pub const WipFunction = struct {
51115121 blocks: std.ArrayListUnmanaged(*llvm.BasicBlock),
51125122 instructions: std.ArrayListUnmanaged(*llvm.Value),
51135123 } else void,
5124 last_debug_location: ?DebugLocation,
5125 current_debug_location: ?DebugLocation,
51145126 cursor: Cursor,
51155127 blocks: std.ArrayListUnmanaged(Block),
51165128 instructions: std.MultiArrayList(Instruction),
51175129 names: std.ArrayListUnmanaged(String),
5118 metadata: std.ArrayListUnmanaged(Metadata),
5130 debug_locations: std.AutoArrayHashMapUnmanaged(Instruction.Index, ?DebugLocation),
5131 debug_values: std.AutoArrayHashMapUnmanaged(Instruction.Index, void),
51195132 extra: std.ArrayListUnmanaged(u32),
51205133
51215134 pub const Cursor = struct { block: Block.Index, instruction: u32 = 0 };
......@@ -5169,20 +5182,27 @@ pub const WipFunction = struct {
51695182 .blocks = .{},
51705183 .instructions = .{},
51715184 .names = .{},
5172 .metadata = .{},
5185 .debug_locations = .{},
5186 .debug_values = .{},
51735187 .extra = .{},
5188 .current_debug_location = null,
5189 .last_debug_location = null,
51745190 };
51755191 errdefer self.deinit();
51765192
51775193 const params_len = function.typeOf(self.builder).functionParameters(self.builder).len;
51785194 try self.ensureUnusedExtraCapacity(params_len, NoExtra, 0);
51795195 try self.instructions.ensureUnusedCapacity(self.builder.gpa, params_len);
5180 if (!self.builder.strip) try self.names.ensureUnusedCapacity(self.builder.gpa, params_len);
5196 if (!self.builder.strip) {
5197 try self.names.ensureUnusedCapacity(self.builder.gpa, params_len);
5198 }
51815199 if (self.builder.useLibLlvm())
51825200 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, params_len);
51835201 for (0..params_len) |param_index| {
51845202 self.instructions.appendAssumeCapacity(.{ .tag = .arg, .data = @intCast(param_index) });
5185 if (!self.builder.strip) self.names.appendAssumeCapacity(.empty); // TODO: param names
5203 if (!self.builder.strip) {
5204 self.names.appendAssumeCapacity(.empty); // TODO: param names
5205 }
51865206 if (self.builder.useLibLlvm()) self.llvm.instructions.appendAssumeCapacity(
51875207 function.toLlvm(self.builder).getParam(@intCast(param_index)),
51885208 );
......@@ -6395,6 +6415,22 @@ pub const WipFunction = struct {
63956415 return instruction.toValue();
63966416 }
63976417
6418 pub fn debugValue(self: *WipFunction, value: Value) Allocator.Error!Metadata {
6419 if (self.builder.strip) return .none;
6420 return switch (value.unwrap()) {
6421 .instruction => |instr_index| blk: {
6422 const gop = try self.debug_values.getOrPut(self.builder.gpa, instr_index);
6423
6424 const metadata: Metadata = @enumFromInt(Metadata.first_local_metadata + gop.index);
6425 if (!gop.found_existing) gop.key_ptr.* = instr_index;
6426
6427 break :blk metadata;
6428 },
6429 .constant => |constant| try self.builder.debugConstant(constant),
6430 .metadata => |metadata| metadata,
6431 };
6432 }
6433
63986434 pub fn finish(self: *WipFunction) Allocator.Error!void {
63996435 const gpa = self.builder.gpa;
64006436 const function = self.function.ptr(self.builder);
......@@ -6426,9 +6462,12 @@ pub const WipFunction = struct {
64266462 const value_indices = try gpa.alloc(u32, final_instructions_len);
64276463 errdefer gpa.free(value_indices);
64286464
6429 const metadata =
6430 if (self.builder.strip) null else try gpa.alloc(Metadata, final_instructions_len);
6431 errdefer if (metadata) |new_metadata| gpa.free(new_metadata);
6465 var debug_locations = std.AutoHashMapUnmanaged(Instruction.Index, ?DebugLocation){};
6466 errdefer debug_locations.deinit(gpa);
6467 try debug_locations.ensureUnusedCapacity(gpa, @intCast(self.debug_locations.count()));
6468
6469 const debug_values = try gpa.alloc(Instruction.Index, self.debug_values.count());
6470 errdefer gpa.free(debug_values);
64326471
64336472 var wip_extra: struct {
64346473 index: Instruction.ExtraIndex = 0,
......@@ -6482,8 +6521,10 @@ pub const WipFunction = struct {
64826521 gpa.free(function.blocks);
64836522 function.blocks = &.{};
64846523 gpa.free(function.names[0..function.instructions.len]);
6485 if (function.metadata) |old_metadata| gpa.free(old_metadata[0..function.instructions.len]);
6486 function.metadata = null;
6524 function.debug_locations.deinit(gpa);
6525 function.debug_locations = .{};
6526 gpa.free(function.debug_values);
6527 function.debug_values = &.{};
64876528 gpa.free(function.extra);
64886529 function.extra = &.{};
64896530
......@@ -6532,6 +6573,12 @@ pub const WipFunction = struct {
65326573 names[@intFromEnum(new_argument_index)] = wip_name.map(
65336574 if (self.builder.strip) .empty else self.names.items[@intFromEnum(old_argument_index)],
65346575 );
6576 if (self.debug_locations.get(old_argument_index)) |location| {
6577 debug_locations.putAssumeCapacity(new_argument_index, location);
6578 }
6579 if (self.debug_values.getIndex(old_argument_index)) |index| {
6580 debug_values[index] = new_argument_index;
6581 }
65356582 }
65366583 for (self.blocks.items) |current_block| {
65376584 const new_block_index: Instruction.Index = @enumFromInt(function.instructions.len);
......@@ -6846,6 +6893,14 @@ pub const WipFunction = struct {
68466893 else
68476894 self.names.items[@intFromEnum(old_instruction_index)]);
68486895
6896 if (self.debug_locations.get(old_instruction_index)) |location| {
6897 debug_locations.putAssumeCapacity(new_instruction_index, location);
6898 }
6899
6900 if (self.debug_values.getIndex(old_instruction_index)) |index| {
6901 debug_values[index] = new_instruction_index;
6902 }
6903
68496904 value_indices[@intFromEnum(new_instruction_index)] = value_index;
68506905 if (old_instruction_index.hasResultWip(self)) value_index += 1;
68516906 }
......@@ -6856,12 +6911,14 @@ pub const WipFunction = struct {
68566911 function.blocks = blocks;
68576912 function.names = names.ptr;
68586913 function.value_indices = value_indices.ptr;
6859 function.metadata = if (metadata) |new_metadata| new_metadata.ptr else null;
6914 function.debug_locations = debug_locations;
6915 function.debug_values = debug_values;
68606916 }
68616917
68626918 pub fn deinit(self: *WipFunction) void {
68636919 self.extra.deinit(self.builder.gpa);
6864 self.metadata.deinit(self.builder.gpa);
6920 self.debug_values.deinit(self.builder.gpa);
6921 self.debug_locations.deinit(self.builder.gpa);
68656922 self.names.deinit(self.builder.gpa);
68666923 self.instructions.deinit(self.builder.gpa);
68676924 for (self.blocks.items) |*b| b.instructions.deinit(self.builder.gpa);
......@@ -7137,7 +7194,16 @@ pub const WipFunction = struct {
71377194 ) Allocator.Error!Instruction.Index {
71387195 const block_instructions = &self.cursor.block.ptr(self).instructions;
71397196 try self.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
7140 if (!self.builder.strip) try self.names.ensureUnusedCapacity(self.builder.gpa, 1);
7197 if (!self.builder.strip) {
7198 try self.names.ensureUnusedCapacity(self.builder.gpa, 1);
7199 if (!std.mem.eql(
7200 u8,
7201 std.mem.asBytes(&self.current_debug_location),
7202 std.mem.asBytes(&self.last_debug_location),
7203 )) {
7204 try self.debug_locations.ensureUnusedCapacity(self.builder.gpa, 1);
7205 }
7206 }
71417207 try block_instructions.ensureUnusedCapacity(self.builder.gpa, 1);
71427208 if (self.builder.useLibLlvm())
71437209 try self.llvm.instructions.ensureUnusedCapacity(self.builder.gpa, 1);
......@@ -7158,7 +7224,17 @@ pub const WipFunction = struct {
71587224
71597225 const index: Instruction.Index = @enumFromInt(self.instructions.len);
71607226 self.instructions.appendAssumeCapacity(instruction);
7161 if (!self.builder.strip) self.names.appendAssumeCapacity(final_name);
7227 if (!self.builder.strip) {
7228 self.names.appendAssumeCapacity(final_name);
7229 if (!std.mem.eql(
7230 u8,
7231 std.mem.asBytes(&self.current_debug_location),
7232 std.mem.asBytes(&self.last_debug_location),
7233 )) {
7234 self.debug_locations.putAssumeCapacity(index, self.current_debug_location);
7235 self.last_debug_location = self.current_debug_location;
7236 }
7237 }
71627238 block_instructions.insertAssumeCapacity(self.cursor.instruction, index);
71637239 self.cursor.instruction += 1;
71647240 return index;