Commit 928914e25a

antlilja <liljaanton2001@gmail.com>
2024-02-25 01:27:21
Builder: Improve debug location system
Debug locations are no longer emitted twice every time
1 parent 119b203
Changed files (2)
src
codegen
src/codegen/llvm/Builder.zig
@@ -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);
@@ -14866,20 +14890,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{});
src/codegen/llvm.zig
@@ -4759,7 +4759,7 @@ pub const FuncGen = struct {
 
     inlined: std.ArrayListUnmanaged(struct {
         base_line: u32,
-        location: Builder.Metadata,
+        location: Builder.DebugLocation,
         scope: Builder.Metadata,
     }) = .{},
 
@@ -6579,17 +6579,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;
     }
@@ -6610,7 +6613,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,
         });
@@ -6649,13 +6652,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;
     }
 
@@ -6672,7 +6677,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;
     }
 
@@ -8833,13 +8838,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)) {
@@ -8886,7 +8893,7 @@ pub const FuncGen = struct {
             );
         }
 
-        self.wip.current_debug_location = old_location;
+        self.wip.debug_location = old_location;
         return arg_val;
     }
 
@@ -11732,15 +11739,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, "");
     };