authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-19 14:56:17-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-20 08:09:33-04:00
log62f7276501bee7460cd004c17fdc1545487ad99b
tree36681df690d8baf3e090072d4c2adab9a58a3f4d
parentef90eb0d4d88e0f4ab4ba72bfb2b523dbd5001fa

Dwarf: emit info about inline call sites


21 files changed, 543 insertions(+), 255 deletions(-)

src/Air.zig+14-11
......@@ -456,6 +456,8 @@ pub const Inst = struct {
456456 /// Same as `dbg_var_ptr` except the local is a const, not a var, and the
457457 /// operand is the local's value.
458458 dbg_var_val,
459 /// Same as `dbg_var_val` except the local is an inline function argument.
460 dbg_arg_inline,
459461 /// ?T => bool
460462 /// Result type is always bool.
461463 /// Uses the `un_op` field.
......@@ -1022,10 +1024,7 @@ pub const Inst = struct {
10221024 ty: Ref,
10231025 /// Index into `extra` of a null-terminated string representing the parameter name.
10241026 /// This is `.none` if debug info is stripped.
1025 name: enum(u32) {
1026 none = std.math.maxInt(u32),
1027 _,
1028 },
1027 name: NullTerminatedString,
10291028 },
10301029 ty_op: struct {
10311030 ty: Ref,
......@@ -1440,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
14401439 .dbg_stmt,
14411440 .dbg_var_ptr,
14421441 .dbg_var_val,
1442 .dbg_arg_inline,
14431443 .store,
14441444 .store_safe,
14451445 .fence,
......@@ -1562,14 +1562,16 @@ pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value {
15621562 return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt);
15631563}
15641564
1565pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
1566 const bytes = std.mem.sliceAsBytes(air.extra[index..]);
1567 var end: usize = 0;
1568 while (bytes[end] != 0) {
1569 end += 1;
1565pub const NullTerminatedString = enum(u32) {
1566 none = std.math.maxInt(u32),
1567 _,
1568
1569 pub fn toSlice(nts: NullTerminatedString, air: Air) [:0]const u8 {
1570 if (nts == .none) return "";
1571 const bytes = std.mem.sliceAsBytes(air.extra[@intFromEnum(nts)..]);
1572 return bytes[0..std.mem.indexOfScalar(u8, bytes, 0).? :0];
15701573 }
1571 return bytes[0..end :0];
1572}
1574};
15731575
15741576/// Returns whether the given instruction must always be lowered, for instance
15751577/// because it can cause side effects. If an instruction does not need to be
......@@ -1596,6 +1598,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
15961598 .dbg_inline_block,
15971599 .dbg_var_ptr,
15981600 .dbg_var_val,
1601 .dbg_arg_inline,
15991602 .ret,
16001603 .ret_safe,
16011604 .ret_load,
src/Air/types_resolved.zig+1
......@@ -339,6 +339,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {
339339
340340 .dbg_var_ptr,
341341 .dbg_var_val,
342 .dbg_arg_inline,
342343 => {
343344 if (!checkRef(data.pl_op.operand, zcu)) return false;
344345 },
src/Liveness.zig+2
......@@ -464,6 +464,7 @@ pub fn categorizeOperand(
464464
465465 .dbg_var_ptr,
466466 .dbg_var_val,
467 .dbg_arg_inline,
467468 => {
468469 const o = air_datas[@intFromEnum(inst)].pl_op.operand;
469470 if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
......@@ -1097,6 +1098,7 @@ fn analyzeInst(
10971098
10981099 .dbg_var_ptr,
10991100 .dbg_var_val,
1101 .dbg_arg_inline,
11001102 => {
11011103 const operand = inst_datas[@intFromEnum(inst)].pl_op.operand;
11021104 return analyzeOperands(a, pass, data, inst, .{ operand, .none, .none });
src/Liveness/Verify.zig+1
......@@ -157,6 +157,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
157157 },
158158 .dbg_var_ptr,
159159 .dbg_var_val,
160 .dbg_arg_inline,
160161 .wasm_memory_grow,
161162 => {
162163 const pl_op = data[@intFromEnum(inst)].pl_op;
src/Sema.zig+11-10
......@@ -376,7 +376,7 @@ pub const Block = struct {
376376
377377 c_import_buf: ?*std.ArrayList(u8) = null,
378378
379 /// If not `null`, this boolean is set when a `dbg_var_ptr` or `dbg_var_val`
379 /// If not `null`, this boolean is set when a `dbg_var_ptr`, `dbg_var_val`, or `dbg_arg_inline`.
380380 /// instruction is emitted. It signals that the innermost lexically
381381 /// enclosing `block`/`block_inline` should be translated into a real AIR
382382 /// `block` in order for codegen to match lexical scoping for debug vars.
......@@ -6567,7 +6567,7 @@ fn addDbgVar(
65676567 const operand_ty = sema.typeOf(operand);
65686568 const val_ty = switch (air_tag) {
65696569 .dbg_var_ptr => operand_ty.childType(mod),
6570 .dbg_var_val => operand_ty,
6570 .dbg_var_val, .dbg_arg_inline => operand_ty,
65716571 else => unreachable,
65726572 };
65736573 if (try sema.typeRequiresComptime(val_ty)) return;
......@@ -6586,25 +6586,26 @@ fn addDbgVar(
65866586 if (block.need_debug_scope) |ptr| ptr.* = true;
65876587
65886588 // Add the name to the AIR.
6589 const name_extra_index = try sema.appendAirString(name);
6589 const name_nts = try sema.appendAirString(name);
65906590
65916591 _ = try block.addInst(.{
65926592 .tag = air_tag,
65936593 .data = .{ .pl_op = .{
6594 .payload = name_extra_index,
6594 .payload = @intFromEnum(name_nts),
65956595 .operand = operand,
65966596 } },
65976597 });
65986598}
65996599
6600pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 {
6601 const str_extra_index: u32 = @intCast(sema.air_extra.items.len);
6600pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!Air.NullTerminatedString {
6601 if (str.len == 0) return .none;
6602 const nts: Air.NullTerminatedString = @enumFromInt(sema.air_extra.items.len);
66026603 const elements_used = str.len / 4 + 1;
66036604 const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used);
66046605 const buffer = mem.sliceAsBytes(elements);
66056606 @memcpy(buffer[0..str.len], str);
66066607 buffer[str.len] = 0;
6607 return str_extra_index;
6608 return nts;
66086609}
66096610
66106611fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -7748,14 +7749,14 @@ fn analyzeCall(
77487749 const param_name = sema.code.nullTerminatedString(extra.data.name);
77497750 const inst = sema.inst_map.get(param).?;
77507751
7751 try sema.addDbgVar(&child_block, inst, .dbg_var_val, param_name);
7752 try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name);
77527753 },
77537754 .param_anytype, .param_anytype_comptime => {
77547755 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok;
77557756 const param_name = inst_data.get(sema.code);
77567757 const inst = sema.inst_map.get(param).?;
77577758
7758 try sema.addDbgVar(&child_block, inst, .dbg_var_val, param_name);
7759 try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name);
77597760 },
77607761 else => continue,
77617762 };
......@@ -8266,7 +8267,7 @@ fn instantiateGenericCall(
82668267 .name = if (child_block.ownerModule().strip)
82678268 .none
82688269 else
8269 @enumFromInt(try sema.appendAirString(fn_zir.nullTerminatedString(param_name))),
8270 try sema.appendAirString(fn_zir.nullTerminatedString(param_name)),
82708271 } },
82718272 }));
82728273 try child_block.params.append(sema.arena, .{
src/Zcu/PerThread.zig+5-2
......@@ -1241,7 +1241,10 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
12411241 }
12421242
12431243 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
1244 .func => |f| .{ f.owner_nav == nav_index, false },
1244 .func => |f| status: {
1245 const func_type = ip.indexToKey(f.ty).func_type;
1246 break :status .{ f.owner_nav == nav_index, func_type.is_generic or func_type.cc == .Inline };
1247 },
12451248 .variable => |v| .{ false, v.owner_nav == nav_index },
12461249 .@"extern" => .{ false, false },
12471250 else => .{ false, true },
......@@ -2158,7 +2161,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!
21582161 .name = if (inner_block.ownerModule().strip)
21592162 .none
21602163 else
2161 @enumFromInt(try sema.appendAirString(sema.code.nullTerminatedString(param_name))),
2164 try sema.appendAirString(sema.code.nullTerminatedString(param_name)),
21622165 } },
21632166 });
21642167 }
src/arch/aarch64/CodeGen.zig+15-16
......@@ -170,7 +170,9 @@ const DbgInfoReloc = struct {
170170
171171 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
172172 switch (reloc.tag) {
173 .arg => try reloc.genArgDbgInfo(function),
173 .arg,
174 .dbg_arg_inline,
175 => try reloc.genArgDbgInfo(function),
174176
175177 .dbg_var_ptr,
176178 .dbg_var_val,
......@@ -201,7 +203,7 @@ const DbgInfoReloc = struct {
201203 else => unreachable, // not a possible argument
202204
203205 };
204 try dw.genVarDebugInfo(.local_arg, reloc.name, reloc.ty, loc);
206 try dw.genLocalDebugInfo(.local_arg, reloc.name, reloc.ty, loc);
205207 },
206208 .plan9 => {},
207209 .none => {},
......@@ -237,7 +239,7 @@ const DbgInfoReloc = struct {
237239 break :blk .empty;
238240 },
239241 };
240 try dwarf.genVarDebugInfo(.local_var, reloc.name, reloc.ty, loc);
242 try dwarf.genLocalDebugInfo(.local_var, reloc.name, reloc.ty, loc);
241243 },
242244 .plan9 => {},
243245 .none => {},
......@@ -799,6 +801,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
799801 .dbg_inline_block => try self.airDbgInlineBlock(inst),
800802 .dbg_var_ptr,
801803 .dbg_var_val,
804 .dbg_arg_inline,
802805 => try self.airDbgVar(inst),
803806
804807 .call => try self.airCall(inst, .auto),
......@@ -4220,17 +4223,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
42204223
42214224 const ty = self.typeOfIndex(inst);
42224225 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4223
4224 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4225 if (name_nts != .none) {
4226 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
4227 try self.dbg_info_relocs.append(self.gpa, .{
4228 .tag = tag,
4229 .ty = ty,
4230 .name = name,
4231 .mcv = self.args[arg_index],
4232 });
4233 }
4226 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4227 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{
4228 .tag = tag,
4229 .ty = ty,
4230 .name = name.toSlice(self.air),
4231 .mcv = self.args[arg_index],
4232 });
42344233
42354234 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
42364235 return self.finishAir(inst, result, .{ .none, .none, .none });
......@@ -4644,14 +4643,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
46444643 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
46454644 const ty = self.typeOf(operand);
46464645 const mcv = try self.resolveInst(operand);
4647 const name = self.air.nullTerminatedString(pl_op.payload);
4646 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
46484647
46494648 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });
46504649
46514650 try self.dbg_info_relocs.append(self.gpa, .{
46524651 .tag = tag,
46534652 .ty = ty,
4654 .name = name,
4653 .name = name.toSlice(self.air),
46554654 .mcv = mcv,
46564655 });
46574656
src/arch/arm/CodeGen.zig+15-15
......@@ -248,7 +248,9 @@ const DbgInfoReloc = struct {
248248
249249 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
250250 switch (reloc.tag) {
251 .arg => try reloc.genArgDbgInfo(function),
251 .arg,
252 .dbg_arg_inline,
253 => try reloc.genArgDbgInfo(function),
252254
253255 .dbg_var_ptr,
254256 .dbg_var_val,
......@@ -279,7 +281,7 @@ const DbgInfoReloc = struct {
279281 else => unreachable, // not a possible argument
280282 };
281283
282 try dw.genVarDebugInfo(.local_arg, reloc.name, reloc.ty, loc);
284 try dw.genLocalDebugInfo(.local_arg, reloc.name, reloc.ty, loc);
283285 },
284286 .plan9 => {},
285287 .none => {},
......@@ -315,7 +317,7 @@ const DbgInfoReloc = struct {
315317 break :blk .empty;
316318 },
317319 };
318 try dw.genVarDebugInfo(.local_var, reloc.name, reloc.ty, loc);
320 try dw.genLocalDebugInfo(.local_var, reloc.name, reloc.ty, loc);
319321 },
320322 .plan9 => {},
321323 .none => {},
......@@ -786,6 +788,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
786788 .dbg_inline_block => try self.airDbgInlineBlock(inst),
787789 .dbg_var_ptr,
788790 .dbg_var_val,
791 .dbg_arg_inline,
789792 => try self.airDbgVar(inst),
790793
791794 .call => try self.airCall(inst, .auto),
......@@ -4199,16 +4202,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
41994202 const ty = self.typeOfIndex(inst);
42004203 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
42014204
4202 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4203 if (name_nts != .none) {
4204 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
4205 try self.dbg_info_relocs.append(self.gpa, .{
4206 .tag = tag,
4207 .ty = ty,
4208 .name = name,
4209 .mcv = self.args[arg_index],
4210 });
4211 }
4205 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4206 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{
4207 .tag = tag,
4208 .ty = ty,
4209 .name = name.toSlice(self.air),
4210 .mcv = self.args[arg_index],
4211 });
42124212
42134213 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
42144214 return self.finishAir(inst, result, .{ .none, .none, .none });
......@@ -4612,14 +4612,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
46124612 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
46134613 const ty = self.typeOf(operand);
46144614 const mcv = try self.resolveInst(operand);
4615 const name = self.air.nullTerminatedString(pl_op.payload);
4615 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
46164616
46174617 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });
46184618
46194619 try self.dbg_info_relocs.append(self.gpa, .{
46204620 .tag = tag,
46214621 .ty = ty,
4622 .name = name,
4622 .name = name.toSlice(self.air),
46234623 .mcv = mcv,
46244624 });
46254625
src/arch/riscv64/CodeGen.zig+16-6
......@@ -1644,6 +1644,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
16441644
16451645 .dbg_var_ptr,
16461646 .dbg_var_val,
1647 .dbg_arg_inline,
16471648 => try func.airDbgVar(inst),
16481649
16491650 .dbg_inline_block => try func.airDbgInlineBlock(inst),
......@@ -4673,11 +4674,15 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
46734674 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
46744675 const ty = arg.ty.toType();
46754676 if (arg.name == .none) return;
4676 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
46774677
46784678 switch (func.debug_output) {
46794679 .dwarf => |dw| switch (mcv) {
4680 .register => |reg| try dw.genVarDebugInfo(.local_arg, name, ty, .{ .reg = reg.dwarfNum() }),
4680 .register => |reg| try dw.genLocalDebugInfo(
4681 .local_arg,
4682 arg.name.toSlice(func.air),
4683 ty,
4684 .{ .reg = reg.dwarfNum() },
4685 ),
46814686 .load_frame => {},
46824687 else => {},
46834688 },
......@@ -5179,16 +5184,17 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
51795184 const operand = pl_op.operand;
51805185 const ty = func.typeOf(operand);
51815186 const mcv = try func.resolveInst(operand);
5187 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
51825188
5183 const name = func.air.nullTerminatedString(pl_op.payload);
5184
5185 try func.genVarDbgInfo(ty, mcv, name);
5189 const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)];
5190 try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air));
51865191
51875192 return func.finishAir(inst, .unreach, .{ operand, .none, .none });
51885193}
51895194
51905195fn genVarDbgInfo(
51915196 func: Func,
5197 tag: Air.Inst.Tag,
51925198 ty: Type,
51935199 mcv: MCValue,
51945200 name: []const u8,
......@@ -5205,7 +5211,11 @@ fn genVarDbgInfo(
52055211 break :blk .empty;
52065212 },
52075213 };
5208 try dwarf.genVarDebugInfo(.local_var, name, ty, loc);
5214 try dwarf.genLocalDebugInfo(switch (tag) {
5215 else => unreachable,
5216 .dbg_var_ptr, .dbg_var_val => .local_var,
5217 .dbg_arg_inline => .local_arg,
5218 }, name, ty, loc);
52095219 },
52105220 .plan9 => {},
52115221 .none => {},
src/arch/sparc64/CodeGen.zig+8-5
......@@ -643,6 +643,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
643643 .dbg_inline_block => try self.airDbgInlineBlock(inst),
644644 .dbg_var_ptr,
645645 .dbg_var_val,
646 .dbg_arg_inline,
646647 => try self.airDbgVar(inst),
647648
648649 .call => try self.airCall(inst, .auto),
......@@ -1662,7 +1663,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
16621663
16631664fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
16641665 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
1665 const name = self.air.nullTerminatedString(pl_op.payload);
1666 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
16661667 const operand = pl_op.operand;
16671668 // TODO emit debug info for this variable
16681669 _ = name;
......@@ -3582,13 +3583,15 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
35823583 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
35833584 const ty = arg.ty.toType();
35843585 if (arg.name == .none) return;
3585 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
35863586
35873587 switch (self.debug_output) {
35883588 .dwarf => |dw| switch (mcv) {
3589 .register => |reg| try dw.genVarDebugInfo(.local_arg, name, ty, .{
3590 .reg = reg.dwarfNum(),
3591 }),
3589 .register => |reg| try dw.genLocalDebugInfo(
3590 .local_arg,
3591 arg.name.toSlice(self.air),
3592 ty,
3593 .{ .reg = reg.dwarfNum() },
3594 ),
35923595 else => {},
35933596 },
35943597 else => {},
src/arch/wasm/CodeGen.zig+19-13
......@@ -1917,8 +1917,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19171917
19181918 .dbg_stmt => func.airDbgStmt(inst),
19191919 .dbg_inline_block => func.airDbgInlineBlock(inst),
1920 .dbg_var_ptr => func.airDbgVar(inst, true),
1921 .dbg_var_val => func.airDbgVar(inst, false),
1920 .dbg_var_ptr => func.airDbgVar(inst, .local_var, true),
1921 .dbg_var_val => func.airDbgVar(inst, .local_var, false),
1922 .dbg_arg_inline => func.airDbgVar(inst, .local_arg, false),
19221923
19231924 .call => func.airCall(inst, .auto),
19241925 .call_always_tail => func.airCall(inst, .always_tail),
......@@ -2585,13 +2586,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25852586
25862587 switch (func.debug_output) {
25872588 .dwarf => |dwarf| {
2588 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
2589 if (name_nts != .none) {
2590 const name = func.air.nullTerminatedString(@intFromEnum(name_nts));
2591 try dwarf.genVarDebugInfo(.local_arg, name, arg_ty, .{
2592 .wasm_ext = .{ .local = arg.local.value },
2593 });
2594 }
2589 const name = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
2590 if (name != .none) try dwarf.genLocalDebugInfo(
2591 .local_arg,
2592 name.toSlice(func.air),
2593 arg_ty,
2594 .{ .wasm_ext = .{ .local = arg.local.value } },
2595 );
25952596 },
25962597 else => {},
25972598 }
......@@ -6454,7 +6455,12 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64546455 try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
64556456}
64566457
6457fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {
6458fn airDbgVar(
6459 func: *CodeGen,
6460 inst: Air.Inst.Index,
6461 local_tag: link.File.Dwarf.WipNav.LocalTag,
6462 is_ptr: bool,
6463) InnerError!void {
64586464 _ = is_ptr;
64596465 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
64606466
......@@ -6464,8 +6470,8 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
64646470
64656471 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });
64666472
6467 const name = func.air.nullTerminatedString(pl_op.payload);
6468 log.debug(" var name = ({s})", .{name});
6473 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
6474 log.debug(" var name = ({s})", .{name.toSlice(func.air)});
64696475
64706476 const loc: link.File.Dwarf.Loc = switch (operand) {
64716477 .local => |local| .{ .wasm_ext = .{ .local = local.value } },
......@@ -6474,7 +6480,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
64746480 break :blk .empty;
64756481 },
64766482 };
6477 try func.debug_output.dwarf.genVarDebugInfo(.local_var, name, ty, loc);
6483 try func.debug_output.dwarf.genLocalDebugInfo(local_tag, name.toSlice(func.air), ty, loc);
64786484
64796485 return func.finishAir(inst, .none, &.{});
64806486}
src/arch/x86_64/CodeGen.zig+110-116
......@@ -81,9 +81,6 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
8181/// MIR extra data
8282mir_extra: std.ArrayListUnmanaged(u32) = .{},
8383
84stack_args: std.ArrayListUnmanaged(StackVar) = .{},
85stack_vars: std.ArrayListUnmanaged(StackVar) = .{},
86
8784/// Byte offset within the source file of the ending curly.
8885end_di_line: u32,
8986end_di_column: u32,
......@@ -728,12 +725,6 @@ const InstTracking = struct {
728725 }
729726};
730727
731const StackVar = struct {
732 name: []const u8,
733 type: Type,
734 frame_addr: FrameAddr,
735};
736
737728const FrameAlloc = struct {
738729 abi_size: u31,
739730 spill_pad: u3,
......@@ -839,8 +830,6 @@ pub fn generate(
839830 function.exitlude_jump_relocs.deinit(gpa);
840831 function.mir_instructions.deinit(gpa);
841832 function.mir_extra.deinit(gpa);
842 function.stack_args.deinit(gpa);
843 function.stack_vars.deinit(gpa);
844833 }
845834
846835 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
......@@ -913,9 +902,6 @@ pub fn generate(
913902 else => |e| return e,
914903 };
915904
916 try function.genStackVarDebugInfo(.local_arg, function.stack_args.items);
917 try function.genStackVarDebugInfo(.local_var, function.stack_vars.items);
918
919905 var mir: Mir = .{
920906 .instructions = function.mir_instructions.toOwnedSlice(),
921907 .extra = try function.mir_extra.toOwnedSlice(gpa),
......@@ -924,6 +910,7 @@ pub fn generate(
924910 defer mir.deinit(gpa);
925911
926912 var emit: Emit = .{
913 .air = function.air,
927914 .lower = .{
928915 .bin_file = bin_file,
929916 .allocator = gpa,
......@@ -1013,14 +1000,15 @@ pub fn generateLazy(
10131000 else => |e| return e,
10141001 };
10151002
1016 var mir = Mir{
1003 var mir: Mir = .{
10171004 .instructions = function.mir_instructions.toOwnedSlice(),
10181005 .extra = try function.mir_extra.toOwnedSlice(gpa),
10191006 .frame_locs = function.frame_locs.toOwnedSlice(),
10201007 };
10211008 defer mir.deinit(gpa);
10221009
1023 var emit = Emit{
1010 var emit: Emit = .{
1011 .air = function.air,
10241012 .lower = .{
10251013 .bin_file = bin_file,
10261014 .allocator = gpa,
......@@ -1116,7 +1104,7 @@ fn formatWipMir(
11161104) @TypeOf(writer).Error!void {
11171105 const comp = data.self.bin_file.comp;
11181106 const mod = comp.root_mod;
1119 var lower = Lower{
1107 var lower: Lower = .{
11201108 .bin_file = data.self.bin_file,
11211109 .allocator = data.self.gpa,
11221110 .mir = .{
......@@ -1357,6 +1345,56 @@ fn asmPlaceholder(self: *Self) !Mir.Inst.Index {
13571345 });
13581346}
13591347
1348const MirTagAir = enum { dbg_local };
1349
1350fn asmAir(self: *Self, tag: MirTagAir, inst: Air.Inst.Index) !void {
1351 _ = try self.addInst(.{
1352 .tag = .pseudo,
1353 .ops = switch (tag) {
1354 .dbg_local => .pseudo_dbg_local_a,
1355 },
1356 .data = .{ .a = .{ .air_inst = inst } },
1357 });
1358}
1359
1360fn asmAirImmediate(self: *Self, tag: MirTagAir, inst: Air.Inst.Index, imm: Immediate) !void {
1361 const ops: Mir.Inst.Ops, const i: u32 = switch (imm) {
1362 .signed => |s| .{ switch (tag) {
1363 .dbg_local => .pseudo_dbg_local_ai_s,
1364 }, @bitCast(s) },
1365 .unsigned => |u| if (math.cast(u32, u)) |small|
1366 .{ switch (tag) {
1367 .dbg_local => .pseudo_dbg_local_ai_u,
1368 }, small }
1369 else
1370 .{ switch (tag) {
1371 .dbg_local => .pseudo_dbg_local_ai_64,
1372 }, try self.addExtra(Mir.Imm64.encode(u)) },
1373 .reloc => unreachable,
1374 };
1375 _ = try self.addInst(.{
1376 .tag = .pseudo,
1377 .ops = ops,
1378 .data = .{ .ai = .{
1379 .air_inst = inst,
1380 .i = i,
1381 } },
1382 });
1383}
1384
1385fn asmAirMemory(self: *Self, tag: MirTagAir, inst: Air.Inst.Index, m: Memory) !void {
1386 _ = try self.addInst(.{
1387 .tag = .pseudo,
1388 .ops = switch (tag) {
1389 .dbg_local => .pseudo_dbg_local_am,
1390 },
1391 .data = .{ .ax = .{
1392 .air_inst = inst,
1393 .payload = try self.addExtra(Mir.Memory.encode(m)),
1394 } },
1395 });
1396}
1397
13601398fn asmOpOnly(self: *Self, tag: Mir.Inst.FixedTag) !void {
13611399 _ = try self.addInst(.{
13621400 .tag = tag[1],
......@@ -1424,31 +1462,22 @@ fn asmRegisterRegister(self: *Self, tag: Mir.Inst.FixedTag, reg1: Register, reg2
14241462}
14251463
14261464fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: Immediate) !void {
1427 const ops: Mir.Inst.Ops = switch (imm) {
1428 .signed => .ri_s,
1429 .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64,
1465 const ops: Mir.Inst.Ops, const i: u32 = switch (imm) {
1466 .signed => |s| .{ .ri_s, @bitCast(s) },
1467 .unsigned => |u| if (math.cast(u32, u)) |small|
1468 .{ .ri_u, small }
1469 else
1470 .{ .ri_64, try self.addExtra(Mir.Imm64.encode(imm.unsigned)) },
14301471 .reloc => unreachable,
14311472 };
14321473 _ = try self.addInst(.{
14331474 .tag = tag[1],
14341475 .ops = ops,
1435 .data = switch (ops) {
1436 .ri_s, .ri_u => .{ .ri = .{
1437 .fixes = tag[0],
1438 .r1 = reg,
1439 .i = switch (imm) {
1440 .signed => |s| @bitCast(s),
1441 .unsigned => |u| @intCast(u),
1442 .reloc => unreachable,
1443 },
1444 } },
1445 .ri64 => .{ .rx = .{
1446 .fixes = tag[0],
1447 .r1 = reg,
1448 .payload = try self.addExtra(Mir.Imm64.encode(imm.unsigned)),
1449 } },
1450 else => unreachable,
1451 },
1476 .data = .{ .ri = .{
1477 .fixes = tag[0],
1478 .r1 = reg,
1479 .i = i,
1480 } },
14521481 });
14531482}
14541483
......@@ -2158,6 +2187,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
21582187 .dbg_inline_block => try self.airDbgInlineBlock(inst),
21592188 .dbg_var_ptr,
21602189 .dbg_var_val,
2190 .dbg_arg_inline,
21612191 => try self.airDbgVar(inst),
21622192
21632193 .call => try self.airCall(inst, .auto),
......@@ -11951,87 +11981,59 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1195111981fn airDbgArg(self: *Self, inst: Air.Inst.Index) !void {
1195211982 defer self.finishAirBookkeeping();
1195311983 if (self.debug_output == .none) return;
11954 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
11955 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
11956 if (name.len > 0) {
11957 const arg_ty = self.typeOfIndex(inst);
11958 const arg_mcv = self.getResolvedInstValue(inst).short;
11959 try self.genVarDebugInfo(.local_arg, .dbg_var_val, name, arg_ty, arg_mcv);
11960 }
11984 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
11985 if (name != .none) try self.genLocalDebugInfo(inst, self.getResolvedInstValue(inst).short);
1196111986 if (self.liveness.isUnused(inst)) try self.processDeath(inst);
1196211987}
1196311988
11964fn genVarDebugInfo(
11989fn genLocalDebugInfo(
1196511990 self: *Self,
11966 var_tag: link.File.Dwarf.WipNav.VarTag,
11967 tag: Air.Inst.Tag,
11968 name: []const u8,
11969 ty: Type,
11991 inst: Air.Inst.Index,
1197011992 mcv: MCValue,
1197111993) !void {
11972 const stack_vars = switch (var_tag) {
11973 .local_arg => &self.stack_args,
11974 .local_var => &self.stack_vars,
11975 };
11976 switch (self.debug_output) {
11977 .dwarf => |dwarf| switch (tag) {
11978 else => unreachable,
11979 .dbg_var_ptr => {
11980 const var_ty = ty.childType(self.pt.zcu);
11981 switch (mcv) {
11982 else => {
11983 log.info("dbg_var_ptr({s}({}))", .{ @tagName(mcv), mcv });
11984 unreachable;
11985 },
11986 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,
11987 .lea_frame => |frame_addr| try stack_vars.append(self.gpa, .{
11988 .name = name,
11989 .type = var_ty,
11990 .frame_addr = frame_addr,
11991 }),
11992 .lea_symbol => |sym_off| try dwarf.genVarDebugInfo(var_tag, name, var_ty, .{ .plus = .{
11993 &.{ .addr = .{ .sym = sym_off.sym } },
11994 &.{ .consts = sym_off.off },
11995 } }),
11996 }
11997 },
11998 .dbg_var_val => switch (mcv) {
11999 .none => try dwarf.genVarDebugInfo(var_tag, name, ty, .empty),
11994 if (self.debug_output == .none) return;
11995 switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) {
11996 else => unreachable,
11997 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {
11998 switch (mcv) {
11999 .none => try self.asmAir(.dbg_local, inst),
1200012000 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,
12001 .immediate => |immediate| try dwarf.genVarDebugInfo(var_tag, name, ty, .{ .stack_value = &.{
12002 .constu = immediate,
12003 } }),
12001 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, Immediate.u(imm)),
1200412002 else => {
12003 const ty = switch (tag) {
12004 else => unreachable,
12005 .arg => self.typeOfIndex(inst),
12006 .dbg_arg_inline, .dbg_var_val => self.typeOf(
12007 self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand,
12008 ),
12009 };
1200512010 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, self.pt));
1200612011 try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
12007 try stack_vars.append(self.gpa, .{
12008 .name = name,
12009 .type = ty,
12010 .frame_addr = .{ .index = frame_index },
12012 try self.asmAirMemory(.dbg_local, inst, .{
12013 .base = .{ .frame = frame_index },
12014 .mod = .{ .rm = .{ .size = .qword } },
1201112015 });
1201212016 },
12013 },
12017 }
1201412018 },
12015 .plan9 => {},
12016 .none => {},
12017 }
12018}
12019
12020fn genStackVarDebugInfo(
12021 self: Self,
12022 var_tag: link.File.Dwarf.WipNav.VarTag,
12023 stack_vars: []const StackVar,
12024) !void {
12025 switch (self.debug_output) {
12026 .dwarf => |dwarf| for (stack_vars) |stack_var| {
12027 const frame_loc = self.frame_locs.get(@intFromEnum(stack_var.frame_addr.index));
12028 try dwarf.genVarDebugInfo(var_tag, stack_var.name, stack_var.type, .{ .plus = .{
12029 &.{ .breg = frame_loc.base.dwarfNum() },
12030 &.{ .consts = @as(i33, frame_loc.disp) + stack_var.frame_addr.off },
12031 } });
12019 .dbg_var_ptr => switch (mcv) {
12020 else => unreachable,
12021 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,
12022 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{
12023 .base = .{ .frame = frame_addr.index },
12024 .mod = .{ .rm = .{
12025 .size = .qword,
12026 .disp = frame_addr.off,
12027 } },
12028 }),
12029 .lea_symbol => |sym_off| try self.asmAirMemory(.dbg_local, inst, .{
12030 .base = .{ .reloc = .{ .atom_index = undefined, .sym_index = sym_off.sym } },
12031 .mod = .{ .rm = .{
12032 .size = .qword,
12033 .disp = sym_off.off,
12034 } },
12035 }),
1203212036 },
12033 .plan9 => {},
12034 .none => {},
1203512037 }
1203612038}
1203712039
......@@ -13060,29 +13062,21 @@ fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
1306013062 self.inline_func = extra.data.func;
1306113063 _ = try self.addInst(.{
1306213064 .tag = .pseudo,
13063 .ops = .pseudo_dbg_inline_func,
13065 .ops = .pseudo_dbg_enter_inline_func,
1306413066 .data = .{ .func = extra.data.func },
1306513067 });
1306613068 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
1306713069 _ = try self.addInst(.{
1306813070 .tag = .pseudo,
13069 .ops = .pseudo_dbg_inline_func,
13071 .ops = .pseudo_dbg_leave_inline_func,
1307013072 .data = .{ .func = old_inline_func },
1307113073 });
1307213074}
1307313075
1307413076fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
1307513077 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
13076 const operand = pl_op.operand;
13077 const ty = self.typeOf(operand);
13078 const mcv = try self.resolveInst(operand);
13079
13080 const name = self.air.nullTerminatedString(pl_op.payload);
13081
13082 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
13083 try self.genVarDebugInfo(.local_var, tag, name, ty, mcv);
13084
13085 return self.finishAir(inst, .unreach, .{ operand, .none, .none });
13078 try self.genLocalDebugInfo(inst, try self.resolveInst(pl_op.operand));
13079 return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
1308613080}
1308713081
1308813082fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index {
src/arch/x86_64/Emit.zig+89-5
......@@ -1,5 +1,6 @@
11//! This file contains the functionality for emitting x86_64 MIR as machine code
22
3air: Air,
34lower: Lower,
45debug_output: DebugInfoOutput,
56code: *std.ArrayList(u8),
......@@ -232,13 +233,96 @@ pub fn emitMir(emit: *Emit) Error!void {
232233 .none => {},
233234 }
234235 },
235 .pseudo_dbg_inline_func => {
236 .pseudo_dbg_enter_inline_func => {
236237 switch (emit.debug_output) {
237238 .dwarf => |dw| {
238 log.debug("mirDbgInline (line={d}, col={d})", .{
239 log.debug("mirDbgEnterInline (line={d}, col={d})", .{
239240 emit.prev_di_line, emit.prev_di_column,
240241 });
241 try dw.setInlineFunc(mir_inst.data.func);
242 try dw.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_line, emit.prev_di_column);
243 },
244 .plan9 => {},
245 .none => {},
246 }
247 },
248 .pseudo_dbg_leave_inline_func => {
249 switch (emit.debug_output) {
250 .dwarf => |dw| {
251 log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
252 emit.prev_di_line, emit.prev_di_column,
253 });
254 try dw.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);
255 },
256 .plan9 => {},
257 .none => {},
258 }
259 },
260 .pseudo_dbg_local_a,
261 .pseudo_dbg_local_ai_s,
262 .pseudo_dbg_local_ai_u,
263 .pseudo_dbg_local_ai_64,
264 .pseudo_dbg_local_am,
265 => {
266 switch (emit.debug_output) {
267 .dwarf => |dw| {
268 var loc_buf: [2]link.File.Dwarf.Loc = undefined;
269 const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {
270 else => unreachable,
271 .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },
272 .pseudo_dbg_local_ai_s,
273 .pseudo_dbg_local_ai_u,
274 .pseudo_dbg_local_ai_64,
275 => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {
276 loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {
277 .signed => |s| .{ .consts = s },
278 .unsigned => |u| .{ .constu = u },
279 };
280 break :stack_value &loc_buf[0];
281 } } },
282 .pseudo_dbg_local_am => loc: {
283 const mem = emit.lower.mem(mir_inst.data.ax.payload);
284 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
285 base: {
286 loc_buf[0] = switch (mem.base()) {
287 .none => .{ .constu = 0 },
288 .reg => |reg| .{ .breg = reg.dwarfNum() },
289 .frame => unreachable,
290 .reloc => |reloc| .{ .addr = .{ .sym = reloc.sym_index } },
291 };
292 break :base &loc_buf[0];
293 },
294 disp: {
295 loc_buf[1] = switch (mem.disp()) {
296 .signed => |s| .{ .consts = s },
297 .unsigned => |u| .{ .constu = u },
298 };
299 break :disp &loc_buf[1];
300 },
301 } } };
302 },
303 };
304 const ip = &emit.lower.bin_file.comp.module.?.intern_pool;
305 const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));
306 const name: Air.NullTerminatedString = switch (air_inst.tag) {
307 else => unreachable,
308 .arg => air_inst.data.arg.name,
309 .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
310 };
311 try dw.genLocalDebugInfo(
312 switch (air_inst.tag) {
313 else => unreachable,
314 .arg, .dbg_arg_inline => .local_arg,
315 .dbg_var_ptr, .dbg_var_val => .local_var,
316 },
317 name.toSlice(emit.air),
318 switch (air_inst.tag) {
319 else => unreachable,
320 .arg => emit.air.typeOfIndex(air_inst_index, ip),
321 .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),
322 .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
323 },
324 loc,
325 );
242326 },
243327 .plan9 => {},
244328 .none => {},
......@@ -285,7 +369,7 @@ fn fixupRelocs(emit: *Emit) Error!void {
285369 const target = emit.code_offset_mapping.get(reloc.target) orelse
286370 return emit.fail("JMP/CALL relocation target not found!", .{});
287371 const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length));
288 mem.writeInt(i32, emit.code.items[reloc.offset..][0..4], @intCast(disp), .little);
372 std.mem.writeInt(i32, emit.code.items[reloc.offset..][0..4], @intCast(disp), .little);
289373 }
290374}
291375
......@@ -340,9 +424,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
340424
341425const link = @import("../../link.zig");
342426const log = std.log.scoped(.emit);
343const mem = std.mem;
344427const std = @import("std");
345428
429const Air = @import("../../Air.zig");
346430const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
347431const Emit = @This();
348432const Lower = @import("Lower.zig");
src/arch/x86_64/Lower.zig+20-17
......@@ -4,10 +4,10 @@ bin_file: *link.File,
44output_mode: std.builtin.OutputMode,
55link_mode: std.builtin.LinkMode,
66pic: bool,
7allocator: Allocator,
7allocator: std.mem.Allocator,
88mir: Mir,
99cc: std.builtin.CallingConvention,
10err_msg: ?*ErrorMsg = null,
10err_msg: ?*Zcu.ErrorMsg = null,
1111src_loc: Zcu.LazySrcLoc,
1212result_insts_len: u8 = undefined,
1313result_relocs_len: u8 = undefined,
......@@ -267,7 +267,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
267267 .pseudo_dbg_prologue_end_none,
268268 .pseudo_dbg_line_line_column,
269269 .pseudo_dbg_epilogue_begin_none,
270 .pseudo_dbg_inline_func,
270 .pseudo_dbg_enter_inline_func,
271 .pseudo_dbg_leave_inline_func,
272 .pseudo_dbg_local_a,
273 .pseudo_dbg_local_ai_s,
274 .pseudo_dbg_local_ai_u,
275 .pseudo_dbg_local_ai_64,
276 .pseudo_dbg_local_am,
271277 .pseudo_dead_none,
272278 => {},
273279 else => unreachable,
......@@ -283,17 +289,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
283289pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
284290 @setCold(true);
285291 assert(lower.err_msg == null);
286 lower.err_msg = try ErrorMsg.create(lower.allocator, lower.src_loc, format, args);
292 lower.err_msg = try Zcu.ErrorMsg.create(lower.allocator, lower.src_loc, format, args);
287293 return error.LowerFail;
288294}
289295
290fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
296pub fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
291297 return switch (ops) {
292298 .rri_s,
293299 .ri_s,
294300 .i_s,
295301 .mi_s,
296302 .rmi_s,
303 .pseudo_dbg_local_ai_s,
297304 => Immediate.s(@bitCast(i)),
298305
299306 .rrri,
......@@ -306,15 +313,18 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
306313 .mri,
307314 .rrm,
308315 .rrmi,
316 .pseudo_dbg_local_ai_u,
309317 => Immediate.u(i),
310318
311 .ri64 => Immediate.u(lower.mir.extraData(Mir.Imm64, i).data.decode()),
319 .ri_64,
320 .pseudo_dbg_local_ai_64,
321 => Immediate.u(lower.mir.extraData(Mir.Imm64, i).data.decode()),
312322
313323 else => unreachable,
314324 };
315325}
316326
317fn mem(lower: Lower, payload: u32) Memory {
327pub fn mem(lower: Lower, payload: u32) Memory {
318328 return lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode();
319329}
320330
......@@ -490,8 +500,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
490500 .rrrr => inst.data.rrrr.fixes,
491501 .rrri => inst.data.rrri.fixes,
492502 .rri_s, .rri_u => inst.data.rri.fixes,
493 .ri_s, .ri_u => inst.data.ri.fixes,
494 .ri64, .rm, .rmi_s, .mr => inst.data.rx.fixes,
503 .ri_s, .ri_u, .ri_64 => inst.data.ri.fixes,
504 .rm, .rmi_s, .mr => inst.data.rx.fixes,
495505 .mrr, .rrm, .rmr => inst.data.rrx.fixes,
496506 .rmi, .mri => inst.data.rix.fixes,
497507 .rrmr => inst.data.rrrx.fixes,
......@@ -554,14 +564,10 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
554564 .{ .reg = inst.data.rrri.r3 },
555565 .{ .imm = lower.imm(inst.ops, inst.data.rrri.i) },
556566 },
557 .ri_s, .ri_u => &.{
567 .ri_s, .ri_u, .ri_64 => &.{
558568 .{ .reg = inst.data.ri.r1 },
559569 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },
560570 },
561 .ri64 => &.{
562 .{ .reg = inst.data.rx.r1 },
563 .{ .imm = lower.imm(inst.ops, inst.data.rx.payload) },
564 },
565571 .rri_s, .rri_u => &.{
566572 .{ .reg = inst.data.rri.r1 },
567573 .{ .reg = inst.data.rri.r2 },
......@@ -670,9 +676,6 @@ const encoder = @import("encoder.zig");
670676const link = @import("../../link.zig");
671677const std = @import("std");
672678
673const Air = @import("../../Air.zig");
674const Allocator = std.mem.Allocator;
675const ErrorMsg = Zcu.ErrorMsg;
676679const Immediate = Instruction.Immediate;
677680const Instruction = encoder.Instruction;
678681const Lower = @This();
src/arch/x86_64/Mir.zig+38-9
......@@ -760,8 +760,8 @@ pub const Inst = struct {
760760 /// Uses `ri` payload.
761761 ri_u,
762762 /// Register, 64-bit unsigned immediate operands.
763 /// Uses `rx` payload with payload type `Imm64`.
764 ri64,
763 /// Uses `ri` payload with `i` index of extra data of type `Imm64`.
764 ri_64,
765765 /// Immediate (sign-extended) operand.
766766 /// Uses `imm` payload.
767767 i_s,
......@@ -796,7 +796,7 @@ pub const Inst = struct {
796796 /// Uses `rrix` payload with extra data of type `Memory`.
797797 rrmi,
798798 /// Single memory operand.
799 /// Uses `x` with extra data of type `Memory`.
799 /// Uses `x` payload with extra data of type `Memory`.
800800 m,
801801 /// Memory, immediate (sign-extend) operands.
802802 /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`.
......@@ -868,16 +868,16 @@ pub const Inst = struct {
868868 pseudo_j_nz_or_p_inst,
869869
870870 /// Probe alignment
871 /// Uses `ri` payload
871 /// Uses `ri` payload.
872872 pseudo_probe_align_ri_s,
873873 /// Probe adjust unrolled
874 /// Uses `ri` payload
874 /// Uses `ri` payload.
875875 pseudo_probe_adjust_unrolled_ri_s,
876876 /// Probe adjust setup
877 /// Uses `rri` payload
877 /// Uses `rri` payload.
878878 pseudo_probe_adjust_setup_rri_s,
879879 /// Probe adjust loop
880 /// Uses `rr` payload
880 /// Uses `rr` payload.
881881 pseudo_probe_adjust_loop_rr,
882882 /// Push registers
883883 /// Uses `reg_list` payload.
......@@ -893,8 +893,25 @@ pub const Inst = struct {
893893 pseudo_dbg_line_line_column,
894894 /// Start of epilogue
895895 pseudo_dbg_epilogue_begin_none,
896 /// Start or end of inline function
897 pseudo_dbg_inline_func,
896 /// Start of inline function
897 pseudo_dbg_enter_inline_func,
898 /// End of inline function
899 pseudo_dbg_leave_inline_func,
900 /// Local argument or variable.
901 /// Uses `a` payload.
902 pseudo_dbg_local_a,
903 /// Local argument or variable.
904 /// Uses `ai` payload.
905 pseudo_dbg_local_ai_s,
906 /// Local argument or variable.
907 /// Uses `ai` payload.
908 pseudo_dbg_local_ai_u,
909 /// Local argument or variable.
910 /// Uses `ax` payload with extra data of type `Imm64`.
911 pseudo_dbg_local_ai_64,
912 /// Local argument or variable.
913 /// Uses `ax` payload with extra data of type `Memory`.
914 pseudo_dbg_local_am,
898915
899916 /// Tombstone
900917 /// Emitter should skip this instruction.
......@@ -997,6 +1014,17 @@ pub const Inst = struct {
9971014 fixes: Fixes = ._,
9981015 payload: u32,
9991016 },
1017 a: struct {
1018 air_inst: Air.Inst.Index,
1019 },
1020 ai: struct {
1021 air_inst: Air.Inst.Index,
1022 i: u32,
1023 },
1024 ax: struct {
1025 air_inst: Air.Inst.Index,
1026 payload: u32,
1027 },
10001028 /// Relocation for the linker where:
10011029 /// * `atom_index` is the index of the source
10021030 /// * `sym_index` is the index of the target
......@@ -1225,6 +1253,7 @@ const builtin = @import("builtin");
12251253const encoder = @import("encoder.zig");
12261254const std = @import("std");
12271255
1256const Air = @import("../../Air.zig");
12281257const IntegerBitSet = std.bit_set.IntegerBitSet;
12291258const InternPool = @import("../../InternPool.zig");
12301259const Mir = @This();
src/arch/x86_64/encoder.zig+10-2
......@@ -128,8 +128,8 @@ pub const Instruction = struct {
128128 } };
129129 }
130130
131 pub fn rip(ptr_size: PtrSize, disp: i32) Memory {
132 return .{ .rip = .{ .ptr_size = ptr_size, .disp = disp } };
131 pub fn rip(ptr_size: PtrSize, displacement: i32) Memory {
132 return .{ .rip = .{ .ptr_size = ptr_size, .disp = displacement } };
133133 }
134134
135135 pub fn isSegmentRegister(mem: Memory) bool {
......@@ -158,6 +158,14 @@ pub const Instruction = struct {
158158 };
159159 }
160160
161 pub fn disp(mem: Memory) Immediate {
162 return switch (mem) {
163 .sib => |s| Immediate.s(s.disp),
164 .rip => |r| Immediate.s(r.disp),
165 .moffs => |m| Immediate.u(m.offset),
166 };
167 }
168
161169 pub fn bitSize(mem: Memory) u64 {
162170 return switch (mem) {
163171 .rip => |r| r.ptr_size.bitSize(),
src/codegen/c.zig+4-3
......@@ -3293,7 +3293,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
32933293
32943294 .dbg_stmt => try airDbgStmt(f, inst),
32953295 .dbg_inline_block => try airDbgInlineBlock(f, inst),
3296 .dbg_var_ptr, .dbg_var_val => try airDbgVar(f, inst),
3296 .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => try airDbgVar(f, inst),
32973297
32983298 .call => try airCall(f, inst, .auto),
32993299 .call_always_tail => .none,
......@@ -4590,14 +4590,15 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
45904590fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
45914591 const pt = f.object.dg.pt;
45924592 const zcu = pt.zcu;
4593 const tag = f.air.instructions.items(.tag)[@intFromEnum(inst)];
45934594 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
4594 const name = f.air.nullTerminatedString(pl_op.payload);
4595 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
45954596 const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false;
45964597 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
45974598
45984599 try reap(f, inst, &.{pl_op.operand});
45994600 const writer = f.object.writer();
4600 try writer.print("/* var:{s} */\n", .{name});
4601 try writer.print("/* {s}:{s} */\n", .{ @tagName(tag), name.toSlice(f.air) });
46014602 return .none;
46024603}
46034604
src/codegen/llvm.zig+24-10
......@@ -1665,6 +1665,7 @@ pub const Object = struct {
16651665 .ret_ptr = ret_ptr,
16661666 .args = args.items,
16671667 .arg_index = 0,
1668 .arg_inline_index = 0,
16681669 .func_inst_table = .{},
16691670 .blocks = .{},
16701671 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
......@@ -4769,7 +4770,8 @@ pub const FuncGen = struct {
47694770 /// it omits 0-bit types. If the function uses sret as the first parameter,
47704771 /// this slice does not include it.
47714772 args: []const Builder.Value,
4772 arg_index: usize,
4773 arg_index: u32,
4774 arg_inline_index: u32,
47734775
47744776 err_ret_trace: Builder.Value = .none,
47754777
......@@ -5082,7 +5084,8 @@ pub const FuncGen = struct {
50825084 .dbg_stmt => try self.airDbgStmt(inst),
50835085 .dbg_inline_block => try self.airDbgInlineBlock(inst),
50845086 .dbg_var_ptr => try self.airDbgVarPtr(inst),
5085 .dbg_var_val => try self.airDbgVarVal(inst),
5087 .dbg_var_val => try self.airDbgVarVal(inst, false),
5088 .dbg_arg_inline => try self.airDbgVarVal(inst, true),
50865089
50875090 .c_va_arg => try self.airCVaArg(inst),
50885091 .c_va_copy => try self.airCVaCopy(inst),
......@@ -6677,6 +6680,7 @@ pub const FuncGen = struct {
66776680 fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
66786681 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
66796682 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
6683 self.arg_inline_index = 0;
66806684 return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
66816685 }
66826686
......@@ -6685,11 +6689,11 @@ pub const FuncGen = struct {
66856689 const mod = o.pt.zcu;
66866690 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
66876691 const operand = try self.resolveInst(pl_op.operand);
6688 const name = self.air.nullTerminatedString(pl_op.payload);
6692 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
66896693 const ptr_ty = self.typeOf(pl_op.operand);
66906694
66916695 const debug_local_var = try o.builder.debugLocalVar(
6692 try o.builder.metadataString(name),
6696 try o.builder.metadataString(name.toSlice(self.air)),
66936697 self.file,
66946698 self.scope,
66956699 self.prev_dbg_line,
......@@ -6712,15 +6716,25 @@ pub const FuncGen = struct {
67126716 return .none;
67136717 }
67146718
6715 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6719 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index, is_arg: bool) !Builder.Value {
67166720 const o = self.ng.object;
67176721 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
67186722 const operand = try self.resolveInst(pl_op.operand);
67196723 const operand_ty = self.typeOf(pl_op.operand);
6720 const name = self.air.nullTerminatedString(pl_op.payload);
6724 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
67216725
6722 const debug_local_var = try o.builder.debugLocalVar(
6723 try o.builder.metadataString(name),
6726 const debug_local_var = if (is_arg) try o.builder.debugParameter(
6727 try o.builder.metadataString(name.toSlice(self.air)),
6728 self.file,
6729 self.scope,
6730 self.prev_dbg_line,
6731 try o.lowerDebugType(operand_ty),
6732 arg_no: {
6733 self.arg_inline_index += 1;
6734 break :arg_no self.arg_inline_index;
6735 },
6736 ) else try o.builder.debugLocalVar(
6737 try o.builder.metadataString(name.toSlice(self.air)),
67246738 self.file,
67256739 self.scope,
67266740 self.prev_dbg_line,
......@@ -8835,12 +8849,12 @@ pub const FuncGen = struct {
88358849 const lbrace_col = func.lbrace_column + 1;
88368850
88378851 const debug_parameter = try o.builder.debugParameter(
8838 try o.builder.metadataString(self.air.nullTerminatedString(@intFromEnum(name))),
8852 try o.builder.metadataString(name.toSlice(self.air)),
88398853 self.file,
88408854 self.scope,
88418855 lbrace_line,
88428856 try o.lowerDebugType(inst_ty),
8843 @intCast(self.arg_index),
8857 self.arg_index,
88448858 );
88458859
88468860 const old_location = self.wip.debug_location;
src/codegen/spirv.zig+2-2
......@@ -6366,8 +6366,8 @@ const NavGen = struct {
63666366 fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void {
63676367 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
63686368 const target_id = try self.resolve(pl_op.operand);
6369 const name = self.air.nullTerminatedString(pl_op.payload);
6370 try self.spv.debugName(target_id, name);
6369 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
6370 try self.spv.debugName(target_id, name.toSlice(self.air));
63716371 }
63726372
63736373 fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
src/link/Dwarf.zig+135-7
......@@ -986,7 +986,9 @@ pub const WipNav = struct {
986986 entry: Entry.Index,
987987 any_children: bool,
988988 func: InternPool.Index,
989 func_sym_index: u32,
989990 func_high_reloc: u32,
991 inlined_funcs_high_reloc: std.ArrayListUnmanaged(u32),
990992 debug_info: std.ArrayListUnmanaged(u8),
991993 debug_line: std.ArrayListUnmanaged(u8),
992994 debug_loclists: std.ArrayListUnmanaged(u8),
......@@ -994,6 +996,7 @@ pub const WipNav = struct {
994996
995997 pub fn deinit(wip_nav: *WipNav) void {
996998 const gpa = wip_nav.dwarf.gpa;
999 if (wip_nav.func != .none) wip_nav.inlined_funcs_high_reloc.deinit(gpa);
9971000 wip_nav.debug_info.deinit(gpa);
9981001 wip_nav.debug_line.deinit(gpa);
9991002 wip_nav.debug_loclists.deinit(gpa);
......@@ -1004,10 +1007,10 @@ pub const WipNav = struct {
10041007 return wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
10051008 }
10061009
1007 pub const VarTag = enum { local_arg, local_var };
1008 pub fn genVarDebugInfo(
1010 pub const LocalTag = enum { local_arg, local_var };
1011 pub fn genLocalDebugInfo(
10091012 wip_nav: *WipNav,
1010 tag: VarTag,
1013 tag: LocalTag,
10111014 name: []const u8,
10121015 ty: Type,
10131016 loc: Loc,
......@@ -1078,7 +1081,45 @@ pub const WipNav = struct {
10781081 try dlw.writeByte(DW.LNS.set_epilogue_begin);
10791082 }
10801083
1084 pub fn enterInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64, line: u32, column: u32) UpdateError!void {
1085 const dwarf = wip_nav.dwarf;
1086 const zcu = wip_nav.pt.zcu;
1087 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1088 try wip_nav.inlined_funcs_high_reloc.ensureUnusedCapacity(dwarf.gpa, 1);
1089
1090 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs;
1091 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);
1092 try uleb128(diw, @intFromEnum(AbbrevCode.inlined_func));
1093 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
1094 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
1095 try uleb128(diw, column);
1096 external_relocs.appendAssumeCapacity(.{
1097 .source_entry = wip_nav.entry,
1098 .source_off = @intCast(wip_nav.debug_info.items.len),
1099 .target_sym = wip_nav.func_sym_index,
1100 .target_off = code_off,
1101 });
1102 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1103 wip_nav.inlined_funcs_high_reloc.appendAssumeCapacity(@intCast(external_relocs.items.len));
1104 external_relocs.appendAssumeCapacity(.{
1105 .source_entry = wip_nav.entry,
1106 .source_off = @intCast(wip_nav.debug_info.items.len),
1107 .target_sym = wip_nav.func_sym_index,
1108 .target_off = undefined,
1109 });
1110 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1111 try wip_nav.setInlineFunc(func);
1112 }
1113
1114 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {
1115 const external_relocs = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs;
1116 external_relocs.items[wip_nav.inlined_funcs_high_reloc.pop()].target_off = code_off;
1117 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null));
1118 try wip_nav.setInlineFunc(func);
1119 }
1120
10811121 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {
1122 wip_nav.any_children = true;
10821123 const zcu = wip_nav.pt.zcu;
10831124 const dwarf = wip_nav.dwarf;
10841125 if (wip_nav.func == func) return;
......@@ -1217,6 +1258,15 @@ pub const WipNav = struct {
12171258 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
12181259 }
12191260
1261 fn refNav(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!void {
1262 const zcu = wip_nav.pt.zcu;
1263 const ip = &zcu.intern_pool;
1264 const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod);
1265 const nav_gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);
1266 if (!nav_gop.found_existing) nav_gop.value_ptr.* = try wip_nav.dwarf.addCommonEntry(unit);
1267 try wip_nav.infoSectionOffset(.debug_info, unit, nav_gop.value_ptr.*, 0);
1268 }
1269
12201270 fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 {
12211271 const dwarf = wip_nav.dwarf;
12221272 const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs;
......@@ -1554,7 +1604,9 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
15541604 .entry = nav_gop.value_ptr.*,
15551605 .any_children = false,
15561606 .func = .none,
1607 .func_sym_index = undefined,
15571608 .func_high_reloc = undefined,
1609 .inlined_funcs_high_reloc = undefined,
15581610 .debug_info = .{},
15591611 .debug_line = .{},
15601612 .debug_loclists = .{},
......@@ -1694,6 +1746,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
16941746
16951747 const func_type = ip.indexToKey(func.ty).func_type;
16961748 wip_nav.func = nav_val.toIntern();
1749 wip_nav.func_sym_index = sym_index;
1750 wip_nav.inlined_funcs_high_reloc = .{};
16971751
16981752 const diw = wip_nav.debug_info.writer(dwarf.gpa);
16991753 try uleb128(diw, @intFromEnum(AbbrevCode.decl_func));
......@@ -1706,17 +1760,19 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
17061760 try wip_nav.strp(nav.fqn.toSlice(ip));
17071761 try wip_nav.refType(Type.fromInterned(func_type.return_type));
17081762 const external_relocs = &dwarf.debug_info.section.getUnit(unit).external_relocs;
1709 try external_relocs.append(dwarf.gpa, .{
1763 try external_relocs.ensureUnusedCapacity(dwarf.gpa, 2);
1764 external_relocs.appendAssumeCapacity(.{
17101765 .source_entry = wip_nav.entry,
17111766 .source_off = @intCast(wip_nav.debug_info.items.len),
17121767 .target_sym = sym_index,
17131768 });
17141769 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
17151770 wip_nav.func_high_reloc = @intCast(external_relocs.items.len);
1716 try external_relocs.append(dwarf.gpa, .{
1771 external_relocs.appendAssumeCapacity(.{
17171772 .source_entry = wip_nav.entry,
17181773 .source_off = @intCast(wip_nav.debug_info.items.len),
17191774 .target_sym = sym_index,
1775 .target_off = undefined,
17201776 });
17211777 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
17221778 try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
......@@ -1779,7 +1835,8 @@ pub fn finishWipNav(
17791835 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
17801836
17811837 if (wip_nav.func != .none) {
1782 dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs.items[wip_nav.func_high_reloc].target_off = sym.size;
1838 const external_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).external_relocs;
1839 external_relocs.items[wip_nav.func_high_reloc].target_off = sym.size;
17831840 if (wip_nav.any_children) {
17841841 const diw = wip_nav.debug_info.writer(dwarf.gpa);
17851842 try uleb128(diw, @intFromEnum(AbbrevCode.null));
......@@ -1864,7 +1921,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
18641921 .entry = undefined,
18651922 .any_children = false,
18661923 .func = .none,
1924 .func_sym_index = undefined,
18671925 .func_high_reloc = undefined,
1926 .inlined_funcs_high_reloc = undefined,
18681927 .debug_info = .{},
18691928 .debug_line = .{},
18701929 .debug_loclists = .{},
......@@ -1875,6 +1934,40 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
18751934 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
18761935 errdefer _ = dwarf.navs.pop();
18771936 switch (ip.indexToKey(nav_val.toIntern())) {
1937 .func => |func| {
1938 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
1939 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
1940 break :parent .{
1941 parent_namespace_ptr.owner_type,
1942 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
1943 DW.ACCESS.public
1944 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
1945 DW.ACCESS.private
1946 else
1947 unreachable,
1948 };
1949 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
1950
1951 if (!nav_gop.found_existing) nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
1952 wip_nav.entry = nav_gop.value_ptr.*;
1953
1954 const func_type = ip.indexToKey(func.ty).func_type;
1955 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1956 try uleb128(diw, @intFromEnum(@as(AbbrevCode, if (func_type.param_types.len > 0 and func_type.is_var_args) .decl_func_generic else .decl_func_generic_empty)));
1957 try wip_nav.refType(Type.fromInterned(parent_type));
1958 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
1959 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
1960 try uleb128(diw, loc.column + 1);
1961 try diw.writeByte(accessibility);
1962 try wip_nav.strp(nav.name.toSlice(ip));
1963 try wip_nav.refType(Type.fromInterned(func_type.return_type));
1964 for (0..func_type.param_types.len) |param_index| {
1965 try uleb128(diw, @intFromEnum(AbbrevCode.func_type_param));
1966 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
1967 }
1968 if (func_type.is_var_args) try uleb128(diw, @intFromEnum(AbbrevCode.is_var_args));
1969 try uleb128(diw, @intFromEnum(AbbrevCode.null));
1970 },
18781971 .struct_type => done: {
18791972 const loaded_struct = ip.loadStructType(nav_val.toIntern());
18801973
......@@ -2277,7 +2370,9 @@ fn updateType(
22772370 .entry = dwarf.types.get(type_index).?,
22782371 .any_children = false,
22792372 .func = .none,
2373 .func_sym_index = undefined,
22802374 .func_high_reloc = undefined,
2375 .inlined_funcs_high_reloc = undefined,
22812376 .debug_info = .{},
22822377 .debug_line = .{},
22832378 .debug_loclists = .{},
......@@ -2678,7 +2773,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
26782773 .entry = type_gop.value_ptr.*,
26792774 .any_children = false,
26802775 .func = .none,
2776 .func_sym_index = undefined,
26812777 .func_high_reloc = undefined,
2778 .inlined_funcs_high_reloc = undefined,
26822779 .debug_info = .{},
26832780 .debug_line = .{},
26842781 .debug_loclists = .{},
......@@ -2739,7 +2836,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
27392836 .entry = type_gop.value_ptr.*,
27402837 .any_children = false,
27412838 .func = .none,
2839 .func_sym_index = undefined,
27422840 .func_high_reloc = undefined,
2841 .inlined_funcs_high_reloc = undefined,
27432842 .debug_info = .{},
27442843 .debug_line = .{},
27452844 .debug_loclists = .{},
......@@ -2913,7 +3012,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
29133012 .entry = entry,
29143013 .any_children = false,
29153014 .func = .none,
3015 .func_sym_index = undefined,
29163016 .func_high_reloc = undefined,
3017 .inlined_funcs_high_reloc = undefined,
29173018 .debug_info = .{},
29183019 .debug_line = .{},
29193020 .debug_loclists = .{},
......@@ -3283,6 +3384,8 @@ const AbbrevCode = enum(u8) {
32833384 decl_var,
32843385 decl_func,
32853386 decl_func_empty,
3387 decl_func_generic,
3388 decl_func_generic_empty,
32863389 // the rest are unrestricted
32873390 compile_unit,
32883391 module,
......@@ -3317,10 +3420,11 @@ const AbbrevCode = enum(u8) {
33173420 struct_type,
33183421 packed_struct_type,
33193422 union_type,
3423 inlined_func,
33203424 local_arg,
33213425 local_var,
33223426
3323 const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_empty));
3427 const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_generic_empty));
33243428
33253429 const Attr = struct {
33263430 DeclValEnum(DW.AT),
......@@ -3424,6 +3528,19 @@ const AbbrevCode = enum(u8) {
34243528 .{ .noreturn, .flag },
34253529 },
34263530 },
3531 .decl_func_generic = .{
3532 .tag = .subprogram,
3533 .children = true,
3534 .attrs = decl_abbrev_common_attrs ++ .{
3535 .{ .type, .ref_addr },
3536 },
3537 },
3538 .decl_func_generic_empty = .{
3539 .tag = .subprogram,
3540 .attrs = decl_abbrev_common_attrs ++ .{
3541 .{ .type, .ref_addr },
3542 },
3543 },
34273544 .compile_unit = .{
34283545 .tag = .compile_unit,
34293546 .children = true,
......@@ -3679,6 +3796,17 @@ const AbbrevCode = enum(u8) {
36793796 .{ .alignment, .udata },
36803797 },
36813798 },
3799 .inlined_func = .{
3800 .tag = .inlined_subroutine,
3801 .children = true,
3802 .attrs = &.{
3803 .{ .abstract_origin, .ref_addr },
3804 .{ .call_line, .udata },
3805 .{ .call_column, .udata },
3806 .{ .low_pc, .addr },
3807 .{ .high_pc, .addr },
3808 },
3809 },
36823810 .local_arg = .{
36833811 .tag = .formal_parameter,
36843812 .attrs = &.{
src/print_air.zig+4-6
......@@ -283,6 +283,7 @@ const Writer = struct {
283283
284284 .dbg_var_ptr,
285285 .dbg_var_val,
286 .dbg_arg_inline,
286287 => try w.writeDbgVar(s, inst),
287288
288289 .struct_field_ptr => try w.writeStructField(s, inst),
......@@ -358,10 +359,7 @@ const Writer = struct {
358359 try w.writeType(s, arg.ty.toType());
359360 switch (arg.name) {
360361 .none => {},
361 _ => {
362 const name = w.air.nullTerminatedString(@intFromEnum(arg.name));
363 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
364 },
362 _ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}),
365363 }
366364 }
367365
......@@ -686,8 +684,8 @@ const Writer = struct {
686684 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
687685 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
688686 try w.writeOperand(s, inst, 0, pl_op.operand);
689 const name = w.air.nullTerminatedString(pl_op.payload);
690 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
687 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
688 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))});
691689 }
692690
693691 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {