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 {...@@ -456,6 +456,8 @@ pub const Inst = struct {
456 /// Same as `dbg_var_ptr` except the local is a const, not a var, and the456 /// Same as `dbg_var_ptr` except the local is a const, not a var, and the
457 /// operand is the local's value.457 /// operand is the local's value.
458 dbg_var_val,458 dbg_var_val,
459 /// Same as `dbg_var_val` except the local is an inline function argument.
460 dbg_arg_inline,
459 /// ?T => bool461 /// ?T => bool
460 /// Result type is always bool.462 /// Result type is always bool.
461 /// Uses the `un_op` field.463 /// Uses the `un_op` field.
...@@ -1022,10 +1024,7 @@ pub const Inst = struct {...@@ -1022,10 +1024,7 @@ pub const Inst = struct {
1022 ty: Ref,1024 ty: Ref,
1023 /// Index into `extra` of a null-terminated string representing the parameter name.1025 /// Index into `extra` of a null-terminated string representing the parameter name.
1024 /// This is `.none` if debug info is stripped.1026 /// This is `.none` if debug info is stripped.
1025 name: enum(u32) {1027 name: NullTerminatedString,
1026 none = std.math.maxInt(u32),
1027 _,
1028 },
1029 },1028 },
1030 ty_op: struct {1029 ty_op: struct {
1031 ty: Ref,1030 ty: Ref,
...@@ -1440,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)...@@ -1440,6 +1439,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
1440 .dbg_stmt,1439 .dbg_stmt,
1441 .dbg_var_ptr,1440 .dbg_var_ptr,
1442 .dbg_var_val,1441 .dbg_var_val,
1442 .dbg_arg_inline,
1443 .store,1443 .store,
1444 .store_safe,1444 .store_safe,
1445 .fence,1445 .fence,
...@@ -1562,14 +1562,16 @@ pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value {...@@ -1562,14 +1562,16 @@ pub fn value(air: Air, inst: Inst.Ref, pt: Zcu.PerThread) !?Value {
1562 return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt);1562 return air.typeOfIndex(index, &pt.zcu.intern_pool).onePossibleValue(pt);
1563}1563}
15641564
1565pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {1565pub const NullTerminatedString = enum(u32) {
1566 const bytes = std.mem.sliceAsBytes(air.extra[index..]);1566 none = std.math.maxInt(u32),
1567 var end: usize = 0;1567 _,
1568 while (bytes[end] != 0) {1568
1569 end += 1;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];
1570 }1573 }
1571 return bytes[0..end :0];1574};
1572}
15731575
1574/// Returns whether the given instruction must always be lowered, for instance1576/// Returns whether the given instruction must always be lowered, for instance
1575/// because it can cause side effects. If an instruction does not need to be1577/// 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 {...@@ -1596,6 +1598,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
1596 .dbg_inline_block,1598 .dbg_inline_block,
1597 .dbg_var_ptr,1599 .dbg_var_ptr,
1598 .dbg_var_val,1600 .dbg_var_val,
1601 .dbg_arg_inline,
1599 .ret,1602 .ret,
1600 .ret_safe,1603 .ret_safe,
1601 .ret_load,1604 .ret_load,
src/Air/types_resolved.zig+1
...@@ -339,6 +339,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {...@@ -339,6 +339,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {
339339
340 .dbg_var_ptr,340 .dbg_var_ptr,
341 .dbg_var_val,341 .dbg_var_val,
342 .dbg_arg_inline,
342 => {343 => {
343 if (!checkRef(data.pl_op.operand, zcu)) return false;344 if (!checkRef(data.pl_op.operand, zcu)) return false;
344 },345 },
src/Liveness.zig+2
...@@ -464,6 +464,7 @@ pub fn categorizeOperand(...@@ -464,6 +464,7 @@ pub fn categorizeOperand(
464464
465 .dbg_var_ptr,465 .dbg_var_ptr,
466 .dbg_var_val,466 .dbg_var_val,
467 .dbg_arg_inline,
467 => {468 => {
468 const o = air_datas[@intFromEnum(inst)].pl_op.operand;469 const o = air_datas[@intFromEnum(inst)].pl_op.operand;
469 if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);470 if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
...@@ -1097,6 +1098,7 @@ fn analyzeInst(...@@ -1097,6 +1098,7 @@ fn analyzeInst(
10971098
1098 .dbg_var_ptr,1099 .dbg_var_ptr,
1099 .dbg_var_val,1100 .dbg_var_val,
1101 .dbg_arg_inline,
1100 => {1102 => {
1101 const operand = inst_datas[@intFromEnum(inst)].pl_op.operand;1103 const operand = inst_datas[@intFromEnum(inst)].pl_op.operand;
1102 return analyzeOperands(a, pass, data, inst, .{ operand, .none, .none });1104 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 {...@@ -157,6 +157,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
157 },157 },
158 .dbg_var_ptr,158 .dbg_var_ptr,
159 .dbg_var_val,159 .dbg_var_val,
160 .dbg_arg_inline,
160 .wasm_memory_grow,161 .wasm_memory_grow,
161 => {162 => {
162 const pl_op = data[@intFromEnum(inst)].pl_op;163 const pl_op = data[@intFromEnum(inst)].pl_op;
src/Sema.zig+11-10
...@@ -376,7 +376,7 @@ pub const Block = struct {...@@ -376,7 +376,7 @@ pub const Block = struct {
376376
377 c_import_buf: ?*std.ArrayList(u8) = null,377 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`.
380 /// instruction is emitted. It signals that the innermost lexically380 /// instruction is emitted. It signals that the innermost lexically
381 /// enclosing `block`/`block_inline` should be translated into a real AIR381 /// enclosing `block`/`block_inline` should be translated into a real AIR
382 /// `block` in order for codegen to match lexical scoping for debug vars.382 /// `block` in order for codegen to match lexical scoping for debug vars.
...@@ -6567,7 +6567,7 @@ fn addDbgVar(...@@ -6567,7 +6567,7 @@ fn addDbgVar(
6567 const operand_ty = sema.typeOf(operand);6567 const operand_ty = sema.typeOf(operand);
6568 const val_ty = switch (air_tag) {6568 const val_ty = switch (air_tag) {
6569 .dbg_var_ptr => operand_ty.childType(mod),6569 .dbg_var_ptr => operand_ty.childType(mod),
6570 .dbg_var_val => operand_ty,6570 .dbg_var_val, .dbg_arg_inline => operand_ty,
6571 else => unreachable,6571 else => unreachable,
6572 };6572 };
6573 if (try sema.typeRequiresComptime(val_ty)) return;6573 if (try sema.typeRequiresComptime(val_ty)) return;
...@@ -6586,25 +6586,26 @@ fn addDbgVar(...@@ -6586,25 +6586,26 @@ fn addDbgVar(
6586 if (block.need_debug_scope) |ptr| ptr.* = true;6586 if (block.need_debug_scope) |ptr| ptr.* = true;
65876587
6588 // Add the name to the AIR.6588 // Add the name to the AIR.
6589 const name_extra_index = try sema.appendAirString(name);6589 const name_nts = try sema.appendAirString(name);
65906590
6591 _ = try block.addInst(.{6591 _ = try block.addInst(.{
6592 .tag = air_tag,6592 .tag = air_tag,
6593 .data = .{ .pl_op = .{6593 .data = .{ .pl_op = .{
6594 .payload = name_extra_index,6594 .payload = @intFromEnum(name_nts),
6595 .operand = operand,6595 .operand = operand,
6596 } },6596 } },
6597 });6597 });
6598}6598}
65996599
6600pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 {6600pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!Air.NullTerminatedString {
6601 const str_extra_index: u32 = @intCast(sema.air_extra.items.len);6601 if (str.len == 0) return .none;
6602 const nts: Air.NullTerminatedString = @enumFromInt(sema.air_extra.items.len);
6602 const elements_used = str.len / 4 + 1;6603 const elements_used = str.len / 4 + 1;
6603 const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used);6604 const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used);
6604 const buffer = mem.sliceAsBytes(elements);6605 const buffer = mem.sliceAsBytes(elements);
6605 @memcpy(buffer[0..str.len], str);6606 @memcpy(buffer[0..str.len], str);
6606 buffer[str.len] = 0;6607 buffer[str.len] = 0;
6607 return str_extra_index;6608 return nts;
6608}6609}
66096610
6610fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6611fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -7748,14 +7749,14 @@ fn analyzeCall(...@@ -7748,14 +7749,14 @@ fn analyzeCall(
7748 const param_name = sema.code.nullTerminatedString(extra.data.name);7749 const param_name = sema.code.nullTerminatedString(extra.data.name);
7749 const inst = sema.inst_map.get(param).?;7750 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);
7752 },7753 },
7753 .param_anytype, .param_anytype_comptime => {7754 .param_anytype, .param_anytype_comptime => {
7754 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok;7755 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok;
7755 const param_name = inst_data.get(sema.code);7756 const param_name = inst_data.get(sema.code);
7756 const inst = sema.inst_map.get(param).?;7757 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);
7759 },7760 },
7760 else => continue,7761 else => continue,
7761 };7762 };
...@@ -8266,7 +8267,7 @@ fn instantiateGenericCall(...@@ -8266,7 +8267,7 @@ fn instantiateGenericCall(
8266 .name = if (child_block.ownerModule().strip)8267 .name = if (child_block.ownerModule().strip)
8267 .none8268 .none
8268 else8269 else
8269 @enumFromInt(try sema.appendAirString(fn_zir.nullTerminatedString(param_name))),8270 try sema.appendAirString(fn_zir.nullTerminatedString(param_name)),
8270 } },8271 } },
8271 }));8272 }));
8272 try child_block.params.append(sema.arena, .{8273 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 {...@@ -1241,7 +1241,10 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
1241 }1241 }
12421242
1243 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {1243 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 },
1245 .variable => |v| .{ false, v.owner_nav == nav_index },1248 .variable => |v| .{ false, v.owner_nav == nav_index },
1246 .@"extern" => .{ false, false },1249 .@"extern" => .{ false, false },
1247 else => .{ false, true },1250 else => .{ false, true },
...@@ -2158,7 +2161,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!...@@ -2158,7 +2161,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!
2158 .name = if (inner_block.ownerModule().strip)2161 .name = if (inner_block.ownerModule().strip)
2159 .none2162 .none
2160 else2163 else
2161 @enumFromInt(try sema.appendAirString(sema.code.nullTerminatedString(param_name))),2164 try sema.appendAirString(sema.code.nullTerminatedString(param_name)),
2162 } },2165 } },
2163 });2166 });
2164 }2167 }
src/arch/aarch64/CodeGen.zig+15-16
...@@ -170,7 +170,9 @@ const DbgInfoReloc = struct {...@@ -170,7 +170,9 @@ const DbgInfoReloc = struct {
170170
171 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {171 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
172 switch (reloc.tag) {172 switch (reloc.tag) {
173 .arg => try reloc.genArgDbgInfo(function),173 .arg,
174 .dbg_arg_inline,
175 => try reloc.genArgDbgInfo(function),
174176
175 .dbg_var_ptr,177 .dbg_var_ptr,
176 .dbg_var_val,178 .dbg_var_val,
...@@ -201,7 +203,7 @@ const DbgInfoReloc = struct {...@@ -201,7 +203,7 @@ const DbgInfoReloc = struct {
201 else => unreachable, // not a possible argument203 else => unreachable, // not a possible argument
202204
203 };205 };
204 try dw.genVarDebugInfo(.local_arg, reloc.name, reloc.ty, loc);206 try dw.genLocalDebugInfo(.local_arg, reloc.name, reloc.ty, loc);
205 },207 },
206 .plan9 => {},208 .plan9 => {},
207 .none => {},209 .none => {},
...@@ -237,7 +239,7 @@ const DbgInfoReloc = struct {...@@ -237,7 +239,7 @@ const DbgInfoReloc = struct {
237 break :blk .empty;239 break :blk .empty;
238 },240 },
239 };241 };
240 try dwarf.genVarDebugInfo(.local_var, reloc.name, reloc.ty, loc);242 try dwarf.genLocalDebugInfo(.local_var, reloc.name, reloc.ty, loc);
241 },243 },
242 .plan9 => {},244 .plan9 => {},
243 .none => {},245 .none => {},
...@@ -799,6 +801,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -799,6 +801,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
799 .dbg_inline_block => try self.airDbgInlineBlock(inst),801 .dbg_inline_block => try self.airDbgInlineBlock(inst),
800 .dbg_var_ptr,802 .dbg_var_ptr,
801 .dbg_var_val,803 .dbg_var_val,
804 .dbg_arg_inline,
802 => try self.airDbgVar(inst),805 => try self.airDbgVar(inst),
803806
804 .call => try self.airCall(inst, .auto),807 .call => try self.airCall(inst, .auto),
...@@ -4220,17 +4223,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4220,17 +4223,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
42204223
4221 const ty = self.typeOfIndex(inst);4224 const ty = self.typeOfIndex(inst);
4222 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4225 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
42234226 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4224 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;4227 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{
4225 if (name_nts != .none) {4228 .tag = tag,
4226 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));4229 .ty = ty,
4227 try self.dbg_info_relocs.append(self.gpa, .{4230 .name = name.toSlice(self.air),
4228 .tag = tag,4231 .mcv = self.args[arg_index],
4229 .ty = ty,4232 });
4230 .name = name,
4231 .mcv = self.args[arg_index],
4232 });
4233 }
42344233
4235 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4234 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4236 return self.finishAir(inst, result, .{ .none, .none, .none });4235 return self.finishAir(inst, result, .{ .none, .none, .none });
...@@ -4644,14 +4643,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {...@@ -4644,14 +4643,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
4644 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4643 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4645 const ty = self.typeOf(operand);4644 const ty = self.typeOf(operand);
4646 const mcv = try self.resolveInst(operand);4645 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
4649 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });4648 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });
46504649
4651 try self.dbg_info_relocs.append(self.gpa, .{4650 try self.dbg_info_relocs.append(self.gpa, .{
4652 .tag = tag,4651 .tag = tag,
4653 .ty = ty,4652 .ty = ty,
4654 .name = name,4653 .name = name.toSlice(self.air),
4655 .mcv = mcv,4654 .mcv = mcv,
4656 });4655 });
46574656
src/arch/arm/CodeGen.zig+15-15
...@@ -248,7 +248,9 @@ const DbgInfoReloc = struct {...@@ -248,7 +248,9 @@ const DbgInfoReloc = struct {
248248
249 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {249 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
250 switch (reloc.tag) {250 switch (reloc.tag) {
251 .arg => try reloc.genArgDbgInfo(function),251 .arg,
252 .dbg_arg_inline,
253 => try reloc.genArgDbgInfo(function),
252254
253 .dbg_var_ptr,255 .dbg_var_ptr,
254 .dbg_var_val,256 .dbg_var_val,
...@@ -279,7 +281,7 @@ const DbgInfoReloc = struct {...@@ -279,7 +281,7 @@ const DbgInfoReloc = struct {
279 else => unreachable, // not a possible argument281 else => unreachable, // not a possible argument
280 };282 };
281283
282 try dw.genVarDebugInfo(.local_arg, reloc.name, reloc.ty, loc);284 try dw.genLocalDebugInfo(.local_arg, reloc.name, reloc.ty, loc);
283 },285 },
284 .plan9 => {},286 .plan9 => {},
285 .none => {},287 .none => {},
...@@ -315,7 +317,7 @@ const DbgInfoReloc = struct {...@@ -315,7 +317,7 @@ const DbgInfoReloc = struct {
315 break :blk .empty;317 break :blk .empty;
316 },318 },
317 };319 };
318 try dw.genVarDebugInfo(.local_var, reloc.name, reloc.ty, loc);320 try dw.genLocalDebugInfo(.local_var, reloc.name, reloc.ty, loc);
319 },321 },
320 .plan9 => {},322 .plan9 => {},
321 .none => {},323 .none => {},
...@@ -786,6 +788,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -786,6 +788,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
786 .dbg_inline_block => try self.airDbgInlineBlock(inst),788 .dbg_inline_block => try self.airDbgInlineBlock(inst),
787 .dbg_var_ptr,789 .dbg_var_ptr,
788 .dbg_var_val,790 .dbg_var_val,
791 .dbg_arg_inline,
789 => try self.airDbgVar(inst),792 => try self.airDbgVar(inst),
790793
791 .call => try self.airCall(inst, .auto),794 .call => try self.airCall(inst, .auto),
...@@ -4199,16 +4202,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4199,16 +4202,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4199 const ty = self.typeOfIndex(inst);4202 const ty = self.typeOfIndex(inst);
4200 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4203 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
42014204
4202 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;4205 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4203 if (name_nts != .none) {4206 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{
4204 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));4207 .tag = tag,
4205 try self.dbg_info_relocs.append(self.gpa, .{4208 .ty = ty,
4206 .tag = tag,4209 .name = name.toSlice(self.air),
4207 .ty = ty,4210 .mcv = self.args[arg_index],
4208 .name = name,4211 });
4209 .mcv = self.args[arg_index],
4210 });
4211 }
42124212
4213 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4213 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4214 return self.finishAir(inst, result, .{ .none, .none, .none });4214 return self.finishAir(inst, result, .{ .none, .none, .none });
...@@ -4612,14 +4612,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {...@@ -4612,14 +4612,14 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
4612 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4612 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4613 const ty = self.typeOf(operand);4613 const ty = self.typeOf(operand);
4614 const mcv = try self.resolveInst(operand);4614 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
4617 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });4617 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });
46184618
4619 try self.dbg_info_relocs.append(self.gpa, .{4619 try self.dbg_info_relocs.append(self.gpa, .{
4620 .tag = tag,4620 .tag = tag,
4621 .ty = ty,4621 .ty = ty,
4622 .name = name,4622 .name = name.toSlice(self.air),
4623 .mcv = mcv,4623 .mcv = mcv,
4624 });4624 });
46254625
src/arch/riscv64/CodeGen.zig+16-6
...@@ -1644,6 +1644,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {...@@ -1644,6 +1644,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
16441644
1645 .dbg_var_ptr,1645 .dbg_var_ptr,
1646 .dbg_var_val,1646 .dbg_var_val,
1647 .dbg_arg_inline,
1647 => try func.airDbgVar(inst),1648 => try func.airDbgVar(inst),
16481649
1649 .dbg_inline_block => try func.airDbgInlineBlock(inst),1650 .dbg_inline_block => try func.airDbgInlineBlock(inst),
...@@ -4673,11 +4674,15 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -4673,11 +4674,15 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4673 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4674 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4674 const ty = arg.ty.toType();4675 const ty = arg.ty.toType();
4675 if (arg.name == .none) return;4676 if (arg.name == .none) return;
4676 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
46774677
4678 switch (func.debug_output) {4678 switch (func.debug_output) {
4679 .dwarf => |dw| switch (mcv) {4679 .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 ),
4681 .load_frame => {},4686 .load_frame => {},
4682 else => {},4687 else => {},
4683 },4688 },
...@@ -5179,16 +5184,17 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {...@@ -5179,16 +5184,17 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
5179 const operand = pl_op.operand;5184 const operand = pl_op.operand;
5180 const ty = func.typeOf(operand);5185 const ty = func.typeOf(operand);
5181 const mcv = try func.resolveInst(operand);5186 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);5189 const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)];
51845190 try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air));
5185 try func.genVarDbgInfo(ty, mcv, name);
51865191
5187 return func.finishAir(inst, .unreach, .{ operand, .none, .none });5192 return func.finishAir(inst, .unreach, .{ operand, .none, .none });
5188}5193}
51895194
5190fn genVarDbgInfo(5195fn genVarDbgInfo(
5191 func: Func,5196 func: Func,
5197 tag: Air.Inst.Tag,
5192 ty: Type,5198 ty: Type,
5193 mcv: MCValue,5199 mcv: MCValue,
5194 name: []const u8,5200 name: []const u8,
...@@ -5205,7 +5211,11 @@ fn genVarDbgInfo(...@@ -5205,7 +5211,11 @@ fn genVarDbgInfo(
5205 break :blk .empty;5211 break :blk .empty;
5206 },5212 },
5207 };5213 };
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);
5209 },5219 },
5210 .plan9 => {},5220 .plan9 => {},
5211 .none => {},5221 .none => {},
src/arch/sparc64/CodeGen.zig+8-5
...@@ -643,6 +643,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -643,6 +643,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
643 .dbg_inline_block => try self.airDbgInlineBlock(inst),643 .dbg_inline_block => try self.airDbgInlineBlock(inst),
644 .dbg_var_ptr,644 .dbg_var_ptr,
645 .dbg_var_val,645 .dbg_var_val,
646 .dbg_arg_inline,
646 => try self.airDbgVar(inst),647 => try self.airDbgVar(inst),
647648
648 .call => try self.airCall(inst, .auto),649 .call => try self.airCall(inst, .auto),
...@@ -1662,7 +1663,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {...@@ -1662,7 +1663,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
16621663
1663fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {1664fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
1664 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;1665 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);
1666 const operand = pl_op.operand;1667 const operand = pl_op.operand;
1667 // TODO emit debug info for this variable1668 // TODO emit debug info for this variable
1668 _ = name;1669 _ = name;
...@@ -3582,13 +3583,15 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -3582,13 +3583,15 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3582 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;3583 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
3583 const ty = arg.ty.toType();3584 const ty = arg.ty.toType();
3584 if (arg.name == .none) return;3585 if (arg.name == .none) return;
3585 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
35863586
3587 switch (self.debug_output) {3587 switch (self.debug_output) {
3588 .dwarf => |dw| switch (mcv) {3588 .dwarf => |dw| switch (mcv) {
3589 .register => |reg| try dw.genVarDebugInfo(.local_arg, name, ty, .{3589 .register => |reg| try dw.genLocalDebugInfo(
3590 .reg = reg.dwarfNum(),3590 .local_arg,
3591 }),3591 arg.name.toSlice(self.air),
3592 ty,
3593 .{ .reg = reg.dwarfNum() },
3594 ),
3592 else => {},3595 else => {},
3593 },3596 },
3594 else => {},3597 else => {},
src/arch/wasm/CodeGen.zig+19-13
...@@ -1917,8 +1917,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1917,8 +1917,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19171917
1918 .dbg_stmt => func.airDbgStmt(inst),1918 .dbg_stmt => func.airDbgStmt(inst),
1919 .dbg_inline_block => func.airDbgInlineBlock(inst),1919 .dbg_inline_block => func.airDbgInlineBlock(inst),
1920 .dbg_var_ptr => func.airDbgVar(inst, true),1920 .dbg_var_ptr => func.airDbgVar(inst, .local_var, true),
1921 .dbg_var_val => func.airDbgVar(inst, false),1921 .dbg_var_val => func.airDbgVar(inst, .local_var, false),
1922 .dbg_arg_inline => func.airDbgVar(inst, .local_arg, false),
19221923
1923 .call => func.airCall(inst, .auto),1924 .call => func.airCall(inst, .auto),
1924 .call_always_tail => func.airCall(inst, .always_tail),1925 .call_always_tail => func.airCall(inst, .always_tail),
...@@ -2585,13 +2586,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2585,13 +2586,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25852586
2586 switch (func.debug_output) {2587 switch (func.debug_output) {
2587 .dwarf => |dwarf| {2588 .dwarf => |dwarf| {
2588 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;2589 const name = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
2589 if (name_nts != .none) {2590 if (name != .none) try dwarf.genLocalDebugInfo(
2590 const name = func.air.nullTerminatedString(@intFromEnum(name_nts));2591 .local_arg,
2591 try dwarf.genVarDebugInfo(.local_arg, name, arg_ty, .{2592 name.toSlice(func.air),
2592 .wasm_ext = .{ .local = arg.local.value },2593 arg_ty,
2593 });2594 .{ .wasm_ext = .{ .local = arg.local.value } },
2594 }2595 );
2595 },2596 },
2596 else => {},2597 else => {},
2597 }2598 }
...@@ -6454,7 +6455,12 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6454,7 +6455,12 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6454 try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));6455 try func.lowerBlock(inst, ty_pl.ty.toType(), @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
6455}6456}
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 {
6458 _ = is_ptr;6464 _ = is_ptr;
6459 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});6465 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...@@ -6464,8 +6470,8 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
64646470
6465 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });6471 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });
64666472
6467 const name = func.air.nullTerminatedString(pl_op.payload);6473 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
6468 log.debug(" var name = ({s})", .{name});6474 log.debug(" var name = ({s})", .{name.toSlice(func.air)});
64696475
6470 const loc: link.File.Dwarf.Loc = switch (operand) {6476 const loc: link.File.Dwarf.Loc = switch (operand) {
6471 .local => |local| .{ .wasm_ext = .{ .local = local.value } },6477 .local => |local| .{ .wasm_ext = .{ .local = local.value } },
...@@ -6474,7 +6480,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void...@@ -6474,7 +6480,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
6474 break :blk .empty;6480 break :blk .empty;
6475 },6481 },
6476 };6482 };
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
6479 return func.finishAir(inst, .none, &.{});6485 return func.finishAir(inst, .none, &.{});
6480}6486}
src/arch/x86_64/CodeGen.zig+110-116
...@@ -81,9 +81,6 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{},...@@ -81,9 +81,6 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
81/// MIR extra data81/// MIR extra data
82mir_extra: std.ArrayListUnmanaged(u32) = .{},82mir_extra: std.ArrayListUnmanaged(u32) = .{},
8383
84stack_args: std.ArrayListUnmanaged(StackVar) = .{},
85stack_vars: std.ArrayListUnmanaged(StackVar) = .{},
86
87/// Byte offset within the source file of the ending curly.84/// Byte offset within the source file of the ending curly.
88end_di_line: u32,85end_di_line: u32,
89end_di_column: u32,86end_di_column: u32,
...@@ -728,12 +725,6 @@ const InstTracking = struct {...@@ -728,12 +725,6 @@ const InstTracking = struct {
728 }725 }
729};726};
730727
731const StackVar = struct {
732 name: []const u8,
733 type: Type,
734 frame_addr: FrameAddr,
735};
736
737const FrameAlloc = struct {728const FrameAlloc = struct {
738 abi_size: u31,729 abi_size: u31,
739 spill_pad: u3,730 spill_pad: u3,
...@@ -839,8 +830,6 @@ pub fn generate(...@@ -839,8 +830,6 @@ pub fn generate(
839 function.exitlude_jump_relocs.deinit(gpa);830 function.exitlude_jump_relocs.deinit(gpa);
840 function.mir_instructions.deinit(gpa);831 function.mir_instructions.deinit(gpa);
841 function.mir_extra.deinit(gpa);832 function.mir_extra.deinit(gpa);
842 function.stack_args.deinit(gpa);
843 function.stack_vars.deinit(gpa);
844 }833 }
845834
846 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});835 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
...@@ -913,9 +902,6 @@ pub fn generate(...@@ -913,9 +902,6 @@ pub fn generate(
913 else => |e| return e,902 else => |e| return e,
914 };903 };
915904
916 try function.genStackVarDebugInfo(.local_arg, function.stack_args.items);
917 try function.genStackVarDebugInfo(.local_var, function.stack_vars.items);
918
919 var mir: Mir = .{905 var mir: Mir = .{
920 .instructions = function.mir_instructions.toOwnedSlice(),906 .instructions = function.mir_instructions.toOwnedSlice(),
921 .extra = try function.mir_extra.toOwnedSlice(gpa),907 .extra = try function.mir_extra.toOwnedSlice(gpa),
...@@ -924,6 +910,7 @@ pub fn generate(...@@ -924,6 +910,7 @@ pub fn generate(
924 defer mir.deinit(gpa);910 defer mir.deinit(gpa);
925911
926 var emit: Emit = .{912 var emit: Emit = .{
913 .air = function.air,
927 .lower = .{914 .lower = .{
928 .bin_file = bin_file,915 .bin_file = bin_file,
929 .allocator = gpa,916 .allocator = gpa,
...@@ -1013,14 +1000,15 @@ pub fn generateLazy(...@@ -1013,14 +1000,15 @@ pub fn generateLazy(
1013 else => |e| return e,1000 else => |e| return e,
1014 };1001 };
10151002
1016 var mir = Mir{1003 var mir: Mir = .{
1017 .instructions = function.mir_instructions.toOwnedSlice(),1004 .instructions = function.mir_instructions.toOwnedSlice(),
1018 .extra = try function.mir_extra.toOwnedSlice(gpa),1005 .extra = try function.mir_extra.toOwnedSlice(gpa),
1019 .frame_locs = function.frame_locs.toOwnedSlice(),1006 .frame_locs = function.frame_locs.toOwnedSlice(),
1020 };1007 };
1021 defer mir.deinit(gpa);1008 defer mir.deinit(gpa);
10221009
1023 var emit = Emit{1010 var emit: Emit = .{
1011 .air = function.air,
1024 .lower = .{1012 .lower = .{
1025 .bin_file = bin_file,1013 .bin_file = bin_file,
1026 .allocator = gpa,1014 .allocator = gpa,
...@@ -1116,7 +1104,7 @@ fn formatWipMir(...@@ -1116,7 +1104,7 @@ fn formatWipMir(
1116) @TypeOf(writer).Error!void {1104) @TypeOf(writer).Error!void {
1117 const comp = data.self.bin_file.comp;1105 const comp = data.self.bin_file.comp;
1118 const mod = comp.root_mod;1106 const mod = comp.root_mod;
1119 var lower = Lower{1107 var lower: Lower = .{
1120 .bin_file = data.self.bin_file,1108 .bin_file = data.self.bin_file,
1121 .allocator = data.self.gpa,1109 .allocator = data.self.gpa,
1122 .mir = .{1110 .mir = .{
...@@ -1357,6 +1345,56 @@ fn asmPlaceholder(self: *Self) !Mir.Inst.Index {...@@ -1357,6 +1345,56 @@ fn asmPlaceholder(self: *Self) !Mir.Inst.Index {
1357 });1345 });
1358}1346}
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
1360fn asmOpOnly(self: *Self, tag: Mir.Inst.FixedTag) !void {1398fn asmOpOnly(self: *Self, tag: Mir.Inst.FixedTag) !void {
1361 _ = try self.addInst(.{1399 _ = try self.addInst(.{
1362 .tag = tag[1],1400 .tag = tag[1],
...@@ -1424,31 +1462,22 @@ fn asmRegisterRegister(self: *Self, tag: Mir.Inst.FixedTag, reg1: Register, reg2...@@ -1424,31 +1462,22 @@ fn asmRegisterRegister(self: *Self, tag: Mir.Inst.FixedTag, reg1: Register, reg2
1424}1462}
14251463
1426fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: Immediate) !void {1464fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: Immediate) !void {
1427 const ops: Mir.Inst.Ops = switch (imm) {1465 const ops: Mir.Inst.Ops, const i: u32 = switch (imm) {
1428 .signed => .ri_s,1466 .signed => |s| .{ .ri_s, @bitCast(s) },
1429 .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64,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)) },
1430 .reloc => unreachable,1471 .reloc => unreachable,
1431 };1472 };
1432 _ = try self.addInst(.{1473 _ = try self.addInst(.{
1433 .tag = tag[1],1474 .tag = tag[1],
1434 .ops = ops,1475 .ops = ops,
1435 .data = switch (ops) {1476 .data = .{ .ri = .{
1436 .ri_s, .ri_u => .{ .ri = .{1477 .fixes = tag[0],
1437 .fixes = tag[0],1478 .r1 = reg,
1438 .r1 = reg,1479 .i = i,
1439 .i = switch (imm) {1480 } },
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 },
1452 });1481 });
1453}1482}
14541483
...@@ -2158,6 +2187,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -2158,6 +2187,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
2158 .dbg_inline_block => try self.airDbgInlineBlock(inst),2187 .dbg_inline_block => try self.airDbgInlineBlock(inst),
2159 .dbg_var_ptr,2188 .dbg_var_ptr,
2160 .dbg_var_val,2189 .dbg_var_val,
2190 .dbg_arg_inline,
2161 => try self.airDbgVar(inst),2191 => try self.airDbgVar(inst),
21622192
2163 .call => try self.airCall(inst, .auto),2193 .call => try self.airCall(inst, .auto),
...@@ -11951,87 +11981,59 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -11951,87 +11981,59 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
11951fn airDbgArg(self: *Self, inst: Air.Inst.Index) !void {11981fn airDbgArg(self: *Self, inst: Air.Inst.Index) !void {
11952 defer self.finishAirBookkeeping();11982 defer self.finishAirBookkeeping();
11953 if (self.debug_output == .none) return;11983 if (self.debug_output == .none) return;
11954 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;11984 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
11955 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));11985 if (name != .none) try self.genLocalDebugInfo(inst, self.getResolvedInstValue(inst).short);
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 }
11961 if (self.liveness.isUnused(inst)) try self.processDeath(inst);11986 if (self.liveness.isUnused(inst)) try self.processDeath(inst);
11962}11987}
1196311988
11964fn genVarDebugInfo(11989fn genLocalDebugInfo(
11965 self: *Self,11990 self: *Self,
11966 var_tag: link.File.Dwarf.WipNav.VarTag,11991 inst: Air.Inst.Index,
11967 tag: Air.Inst.Tag,
11968 name: []const u8,
11969 ty: Type,
11970 mcv: MCValue,11992 mcv: MCValue,
11971) !void {11993) !void {
11972 const stack_vars = switch (var_tag) {11994 if (self.debug_output == .none) return;
11973 .local_arg => &self.stack_args,11995 switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) {
11974 .local_var => &self.stack_vars,11996 else => unreachable,
11975 };11997 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {
11976 switch (self.debug_output) {11998 switch (mcv) {
11977 .dwarf => |dwarf| switch (tag) {11999 .none => try self.asmAir(.dbg_local, inst),
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),
12000 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,12000 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,
12001 .immediate => |immediate| try dwarf.genVarDebugInfo(var_tag, name, ty, .{ .stack_value = &.{12001 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, Immediate.u(imm)),
12002 .constu = immediate,
12003 } }),
12004 else => {12002 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 };
12005 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, self.pt));12010 const frame_index = try self.allocFrameIndex(FrameAlloc.initSpill(ty, self.pt));
12006 try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});12011 try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
12007 try stack_vars.append(self.gpa, .{12012 try self.asmAirMemory(.dbg_local, inst, .{
12008 .name = name,12013 .base = .{ .frame = frame_index },
12009 .type = ty,12014 .mod = .{ .rm = .{ .size = .qword } },
12010 .frame_addr = .{ .index = frame_index },
12011 });12015 });
12012 },12016 },
12013 },12017 }
12014 },12018 },
12015 .plan9 => {},12019 .dbg_var_ptr => switch (mcv) {
12016 .none => {},12020 else => unreachable,
12017 }12021 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,
12018}12022 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{
1201912023 .base = .{ .frame = frame_addr.index },
12020fn genStackVarDebugInfo(12024 .mod = .{ .rm = .{
12021 self: Self,12025 .size = .qword,
12022 var_tag: link.File.Dwarf.WipNav.VarTag,12026 .disp = frame_addr.off,
12023 stack_vars: []const StackVar,12027 } },
12024) !void {12028 }),
12025 switch (self.debug_output) {12029 .lea_symbol => |sym_off| try self.asmAirMemory(.dbg_local, inst, .{
12026 .dwarf => |dwarf| for (stack_vars) |stack_var| {12030 .base = .{ .reloc = .{ .atom_index = undefined, .sym_index = sym_off.sym } },
12027 const frame_loc = self.frame_locs.get(@intFromEnum(stack_var.frame_addr.index));12031 .mod = .{ .rm = .{
12028 try dwarf.genVarDebugInfo(var_tag, stack_var.name, stack_var.type, .{ .plus = .{12032 .size = .qword,
12029 &.{ .breg = frame_loc.base.dwarfNum() },12033 .disp = sym_off.off,
12030 &.{ .consts = @as(i33, frame_loc.disp) + stack_var.frame_addr.off },12034 } },
12031 } });12035 }),
12032 },12036 },
12033 .plan9 => {},
12034 .none => {},
12035 }12037 }
12036}12038}
1203712039
...@@ -13060,29 +13062,21 @@ fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -13060,29 +13062,21 @@ fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
13060 self.inline_func = extra.data.func;13062 self.inline_func = extra.data.func;
13061 _ = try self.addInst(.{13063 _ = try self.addInst(.{
13062 .tag = .pseudo,13064 .tag = .pseudo,
13063 .ops = .pseudo_dbg_inline_func,13065 .ops = .pseudo_dbg_enter_inline_func,
13064 .data = .{ .func = extra.data.func },13066 .data = .{ .func = extra.data.func },
13065 });13067 });
13066 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));13068 try self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
13067 _ = try self.addInst(.{13069 _ = try self.addInst(.{
13068 .tag = .pseudo,13070 .tag = .pseudo,
13069 .ops = .pseudo_dbg_inline_func,13071 .ops = .pseudo_dbg_leave_inline_func,
13070 .data = .{ .func = old_inline_func },13072 .data = .{ .func = old_inline_func },
13071 });13073 });
13072}13074}
1307313075
13074fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {13076fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
13075 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;13077 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
13076 const operand = pl_op.operand;13078 try self.genLocalDebugInfo(inst, try self.resolveInst(pl_op.operand));
13077 const ty = self.typeOf(operand);13079 return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
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 });
13086}13080}
1308713081
13088fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index {13082fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index {
src/arch/x86_64/Emit.zig+89-5
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1//! This file contains the functionality for emitting x86_64 MIR as machine code1//! This file contains the functionality for emitting x86_64 MIR as machine code
22
3air: Air,
3lower: Lower,4lower: Lower,
4debug_output: DebugInfoOutput,5debug_output: DebugInfoOutput,
5code: *std.ArrayList(u8),6code: *std.ArrayList(u8),
...@@ -232,13 +233,96 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -232,13 +233,96 @@ pub fn emitMir(emit: *Emit) Error!void {
232 .none => {},233 .none => {},
233 }234 }
234 },235 },
235 .pseudo_dbg_inline_func => {236 .pseudo_dbg_enter_inline_func => {
236 switch (emit.debug_output) {237 switch (emit.debug_output) {
237 .dwarf => |dw| {238 .dwarf => |dw| {
238 log.debug("mirDbgInline (line={d}, col={d})", .{239 log.debug("mirDbgEnterInline (line={d}, col={d})", .{
239 emit.prev_di_line, emit.prev_di_column,240 emit.prev_di_line, emit.prev_di_column,
240 });241 });
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 );
242 },326 },
243 .plan9 => {},327 .plan9 => {},
244 .none => {},328 .none => {},
...@@ -285,7 +369,7 @@ fn fixupRelocs(emit: *Emit) Error!void {...@@ -285,7 +369,7 @@ fn fixupRelocs(emit: *Emit) Error!void {
285 const target = emit.code_offset_mapping.get(reloc.target) orelse369 const target = emit.code_offset_mapping.get(reloc.target) orelse
286 return emit.fail("JMP/CALL relocation target not found!", .{});370 return emit.fail("JMP/CALL relocation target not found!", .{});
287 const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length));371 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);
289 }373 }
290}374}
291375
...@@ -340,9 +424,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {...@@ -340,9 +424,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
340424
341const link = @import("../../link.zig");425const link = @import("../../link.zig");
342const log = std.log.scoped(.emit);426const log = std.log.scoped(.emit);
343const mem = std.mem;
344const std = @import("std");427const std = @import("std");
345428
429const Air = @import("../../Air.zig");
346const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;430const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
347const Emit = @This();431const Emit = @This();
348const Lower = @import("Lower.zig");432const Lower = @import("Lower.zig");
src/arch/x86_64/Lower.zig+20-17
...@@ -4,10 +4,10 @@ bin_file: *link.File,...@@ -4,10 +4,10 @@ bin_file: *link.File,
4output_mode: std.builtin.OutputMode,4output_mode: std.builtin.OutputMode,
5link_mode: std.builtin.LinkMode,5link_mode: std.builtin.LinkMode,
6pic: bool,6pic: bool,
7allocator: Allocator,7allocator: std.mem.Allocator,
8mir: Mir,8mir: Mir,
9cc: std.builtin.CallingConvention,9cc: std.builtin.CallingConvention,
10err_msg: ?*ErrorMsg = null,10err_msg: ?*Zcu.ErrorMsg = null,
11src_loc: Zcu.LazySrcLoc,11src_loc: Zcu.LazySrcLoc,
12result_insts_len: u8 = undefined,12result_insts_len: u8 = undefined,
13result_relocs_len: u8 = undefined,13result_relocs_len: u8 = undefined,
...@@ -267,7 +267,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -267,7 +267,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
267 .pseudo_dbg_prologue_end_none,267 .pseudo_dbg_prologue_end_none,
268 .pseudo_dbg_line_line_column,268 .pseudo_dbg_line_line_column,
269 .pseudo_dbg_epilogue_begin_none,269 .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,
271 .pseudo_dead_none,277 .pseudo_dead_none,
272 => {},278 => {},
273 else => unreachable,279 else => unreachable,
...@@ -283,17 +289,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -283,17 +289,18 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
283pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {289pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
284 @setCold(true);290 @setCold(true);
285 assert(lower.err_msg == null);291 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);
287 return error.LowerFail;293 return error.LowerFail;
288}294}
289295
290fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {296pub fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
291 return switch (ops) {297 return switch (ops) {
292 .rri_s,298 .rri_s,
293 .ri_s,299 .ri_s,
294 .i_s,300 .i_s,
295 .mi_s,301 .mi_s,
296 .rmi_s,302 .rmi_s,
303 .pseudo_dbg_local_ai_s,
297 => Immediate.s(@bitCast(i)),304 => Immediate.s(@bitCast(i)),
298305
299 .rrri,306 .rrri,
...@@ -306,15 +313,18 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {...@@ -306,15 +313,18 @@ fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
306 .mri,313 .mri,
307 .rrm,314 .rrm,
308 .rrmi,315 .rrmi,
316 .pseudo_dbg_local_ai_u,
309 => Immediate.u(i),317 => 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
313 else => unreachable,323 else => unreachable,
314 };324 };
315}325}
316326
317fn mem(lower: Lower, payload: u32) Memory {327pub fn mem(lower: Lower, payload: u32) Memory {
318 return lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode();328 return lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode();
319}329}
320330
...@@ -490,8 +500,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -490,8 +500,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
490 .rrrr => inst.data.rrrr.fixes,500 .rrrr => inst.data.rrrr.fixes,
491 .rrri => inst.data.rrri.fixes,501 .rrri => inst.data.rrri.fixes,
492 .rri_s, .rri_u => inst.data.rri.fixes,502 .rri_s, .rri_u => inst.data.rri.fixes,
493 .ri_s, .ri_u => inst.data.ri.fixes,503 .ri_s, .ri_u, .ri_64 => inst.data.ri.fixes,
494 .ri64, .rm, .rmi_s, .mr => inst.data.rx.fixes,504 .rm, .rmi_s, .mr => inst.data.rx.fixes,
495 .mrr, .rrm, .rmr => inst.data.rrx.fixes,505 .mrr, .rrm, .rmr => inst.data.rrx.fixes,
496 .rmi, .mri => inst.data.rix.fixes,506 .rmi, .mri => inst.data.rix.fixes,
497 .rrmr => inst.data.rrrx.fixes,507 .rrmr => inst.data.rrrx.fixes,
...@@ -554,14 +564,10 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -554,14 +564,10 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
554 .{ .reg = inst.data.rrri.r3 },564 .{ .reg = inst.data.rrri.r3 },
555 .{ .imm = lower.imm(inst.ops, inst.data.rrri.i) },565 .{ .imm = lower.imm(inst.ops, inst.data.rrri.i) },
556 },566 },
557 .ri_s, .ri_u => &.{567 .ri_s, .ri_u, .ri_64 => &.{
558 .{ .reg = inst.data.ri.r1 },568 .{ .reg = inst.data.ri.r1 },
559 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },569 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },
560 },570 },
561 .ri64 => &.{
562 .{ .reg = inst.data.rx.r1 },
563 .{ .imm = lower.imm(inst.ops, inst.data.rx.payload) },
564 },
565 .rri_s, .rri_u => &.{571 .rri_s, .rri_u => &.{
566 .{ .reg = inst.data.rri.r1 },572 .{ .reg = inst.data.rri.r1 },
567 .{ .reg = inst.data.rri.r2 },573 .{ .reg = inst.data.rri.r2 },
...@@ -670,9 +676,6 @@ const encoder = @import("encoder.zig");...@@ -670,9 +676,6 @@ const encoder = @import("encoder.zig");
670const link = @import("../../link.zig");676const link = @import("../../link.zig");
671const std = @import("std");677const std = @import("std");
672678
673const Air = @import("../../Air.zig");
674const Allocator = std.mem.Allocator;
675const ErrorMsg = Zcu.ErrorMsg;
676const Immediate = Instruction.Immediate;679const Immediate = Instruction.Immediate;
677const Instruction = encoder.Instruction;680const Instruction = encoder.Instruction;
678const Lower = @This();681const Lower = @This();
src/arch/x86_64/Mir.zig+38-9
...@@ -760,8 +760,8 @@ pub const Inst = struct {...@@ -760,8 +760,8 @@ pub const Inst = struct {
760 /// Uses `ri` payload.760 /// Uses `ri` payload.
761 ri_u,761 ri_u,
762 /// Register, 64-bit unsigned immediate operands.762 /// Register, 64-bit unsigned immediate operands.
763 /// Uses `rx` payload with payload type `Imm64`.763 /// Uses `ri` payload with `i` index of extra data of type `Imm64`.
764 ri64,764 ri_64,
765 /// Immediate (sign-extended) operand.765 /// Immediate (sign-extended) operand.
766 /// Uses `imm` payload.766 /// Uses `imm` payload.
767 i_s,767 i_s,
...@@ -796,7 +796,7 @@ pub const Inst = struct {...@@ -796,7 +796,7 @@ pub const Inst = struct {
796 /// Uses `rrix` payload with extra data of type `Memory`.796 /// Uses `rrix` payload with extra data of type `Memory`.
797 rrmi,797 rrmi,
798 /// Single memory operand.798 /// Single memory operand.
799 /// Uses `x` with extra data of type `Memory`.799 /// Uses `x` payload with extra data of type `Memory`.
800 m,800 m,
801 /// Memory, immediate (sign-extend) operands.801 /// Memory, immediate (sign-extend) operands.
802 /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`.802 /// Uses `x` payload with extra data of type `Imm32` followed by `Memory`.
...@@ -868,16 +868,16 @@ pub const Inst = struct {...@@ -868,16 +868,16 @@ pub const Inst = struct {
868 pseudo_j_nz_or_p_inst,868 pseudo_j_nz_or_p_inst,
869869
870 /// Probe alignment870 /// Probe alignment
871 /// Uses `ri` payload871 /// Uses `ri` payload.
872 pseudo_probe_align_ri_s,872 pseudo_probe_align_ri_s,
873 /// Probe adjust unrolled873 /// Probe adjust unrolled
874 /// Uses `ri` payload874 /// Uses `ri` payload.
875 pseudo_probe_adjust_unrolled_ri_s,875 pseudo_probe_adjust_unrolled_ri_s,
876 /// Probe adjust setup876 /// Probe adjust setup
877 /// Uses `rri` payload877 /// Uses `rri` payload.
878 pseudo_probe_adjust_setup_rri_s,878 pseudo_probe_adjust_setup_rri_s,
879 /// Probe adjust loop879 /// Probe adjust loop
880 /// Uses `rr` payload880 /// Uses `rr` payload.
881 pseudo_probe_adjust_loop_rr,881 pseudo_probe_adjust_loop_rr,
882 /// Push registers882 /// Push registers
883 /// Uses `reg_list` payload.883 /// Uses `reg_list` payload.
...@@ -893,8 +893,25 @@ pub const Inst = struct {...@@ -893,8 +893,25 @@ pub const Inst = struct {
893 pseudo_dbg_line_line_column,893 pseudo_dbg_line_line_column,
894 /// Start of epilogue894 /// Start of epilogue
895 pseudo_dbg_epilogue_begin_none,895 pseudo_dbg_epilogue_begin_none,
896 /// Start or end of inline function896 /// Start of inline function
897 pseudo_dbg_inline_func,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
899 /// Tombstone916 /// Tombstone
900 /// Emitter should skip this instruction.917 /// Emitter should skip this instruction.
...@@ -997,6 +1014,17 @@ pub const Inst = struct {...@@ -997,6 +1014,17 @@ pub const Inst = struct {
997 fixes: Fixes = ._,1014 fixes: Fixes = ._,
998 payload: u32,1015 payload: u32,
999 },1016 },
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 },
1000 /// Relocation for the linker where:1028 /// Relocation for the linker where:
1001 /// * `atom_index` is the index of the source1029 /// * `atom_index` is the index of the source
1002 /// * `sym_index` is the index of the target1030 /// * `sym_index` is the index of the target
...@@ -1225,6 +1253,7 @@ const builtin = @import("builtin");...@@ -1225,6 +1253,7 @@ const builtin = @import("builtin");
1225const encoder = @import("encoder.zig");1253const encoder = @import("encoder.zig");
1226const std = @import("std");1254const std = @import("std");
12271255
1256const Air = @import("../../Air.zig");
1228const IntegerBitSet = std.bit_set.IntegerBitSet;1257const IntegerBitSet = std.bit_set.IntegerBitSet;
1229const InternPool = @import("../../InternPool.zig");1258const InternPool = @import("../../InternPool.zig");
1230const Mir = @This();1259const Mir = @This();
src/arch/x86_64/encoder.zig+10-2
...@@ -128,8 +128,8 @@ pub const Instruction = struct {...@@ -128,8 +128,8 @@ pub const Instruction = struct {
128 } };128 } };
129 }129 }
130130
131 pub fn rip(ptr_size: PtrSize, disp: i32) Memory {131 pub fn rip(ptr_size: PtrSize, displacement: i32) Memory {
132 return .{ .rip = .{ .ptr_size = ptr_size, .disp = disp } };132 return .{ .rip = .{ .ptr_size = ptr_size, .disp = displacement } };
133 }133 }
134134
135 pub fn isSegmentRegister(mem: Memory) bool {135 pub fn isSegmentRegister(mem: Memory) bool {
...@@ -158,6 +158,14 @@ pub const Instruction = struct {...@@ -158,6 +158,14 @@ pub const Instruction = struct {
158 };158 };
159 }159 }
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
161 pub fn bitSize(mem: Memory) u64 {169 pub fn bitSize(mem: Memory) u64 {
162 return switch (mem) {170 return switch (mem) {
163 .rip => |r| r.ptr_size.bitSize(),171 .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,...@@ -3293,7 +3293,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
32933293
3294 .dbg_stmt => try airDbgStmt(f, inst),3294 .dbg_stmt => try airDbgStmt(f, inst),
3295 .dbg_inline_block => try airDbgInlineBlock(f, inst),3295 .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
3298 .call => try airCall(f, inst, .auto),3298 .call => try airCall(f, inst, .auto),
3299 .call_always_tail => .none,3299 .call_always_tail => .none,
...@@ -4590,14 +4590,15 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4590,14 +4590,15 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4590fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {4590fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4591 const pt = f.object.dg.pt;4591 const pt = f.object.dg.pt;
4592 const zcu = pt.zcu;4592 const zcu = pt.zcu;
4593 const tag = f.air.instructions.items(.tag)[@intFromEnum(inst)];
4593 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4594 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);
4595 const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false;4596 const operand_is_undef = if (try f.air.value(pl_op.operand, pt)) |v| v.isUndefDeep(zcu) else false;
4596 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4597 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
45974598
4598 try reap(f, inst, &.{pl_op.operand});4599 try reap(f, inst, &.{pl_op.operand});
4599 const writer = f.object.writer();4600 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) });
4601 return .none;4602 return .none;
4602}4603}
46034604
src/codegen/llvm.zig+24-10
...@@ -1665,6 +1665,7 @@ pub const Object = struct {...@@ -1665,6 +1665,7 @@ pub const Object = struct {
1665 .ret_ptr = ret_ptr,1665 .ret_ptr = ret_ptr,
1666 .args = args.items,1666 .args = args.items,
1667 .arg_index = 0,1667 .arg_index = 0,
1668 .arg_inline_index = 0,
1668 .func_inst_table = .{},1669 .func_inst_table = .{},
1669 .blocks = .{},1670 .blocks = .{},
1670 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,1671 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
...@@ -4769,7 +4770,8 @@ pub const FuncGen = struct {...@@ -4769,7 +4770,8 @@ pub const FuncGen = struct {
4769 /// it omits 0-bit types. If the function uses sret as the first parameter,4770 /// it omits 0-bit types. If the function uses sret as the first parameter,
4770 /// this slice does not include it.4771 /// this slice does not include it.
4771 args: []const Builder.Value,4772 args: []const Builder.Value,
4772 arg_index: usize,4773 arg_index: u32,
4774 arg_inline_index: u32,
47734775
4774 err_ret_trace: Builder.Value = .none,4776 err_ret_trace: Builder.Value = .none,
47754777
...@@ -5082,7 +5084,8 @@ pub const FuncGen = struct {...@@ -5082,7 +5084,8 @@ pub const FuncGen = struct {
5082 .dbg_stmt => try self.airDbgStmt(inst),5084 .dbg_stmt => try self.airDbgStmt(inst),
5083 .dbg_inline_block => try self.airDbgInlineBlock(inst),5085 .dbg_inline_block => try self.airDbgInlineBlock(inst),
5084 .dbg_var_ptr => try self.airDbgVarPtr(inst),5086 .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
5087 .c_va_arg => try self.airCVaArg(inst),5090 .c_va_arg => try self.airCVaArg(inst),
5088 .c_va_copy => try self.airCVaCopy(inst),5091 .c_va_copy => try self.airCVaCopy(inst),
...@@ -6677,6 +6680,7 @@ pub const FuncGen = struct {...@@ -6677,6 +6680,7 @@ pub const FuncGen = struct {
6677 fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6680 fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6678 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6681 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6679 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);6682 const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
6683 self.arg_inline_index = 0;
6680 return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));6684 return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
6681 }6685 }
66826686
...@@ -6685,11 +6689,11 @@ pub const FuncGen = struct {...@@ -6685,11 +6689,11 @@ pub const FuncGen = struct {
6685 const mod = o.pt.zcu;6689 const mod = o.pt.zcu;
6686 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6690 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6687 const operand = try self.resolveInst(pl_op.operand);6691 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);
6689 const ptr_ty = self.typeOf(pl_op.operand);6693 const ptr_ty = self.typeOf(pl_op.operand);
66906694
6691 const debug_local_var = try o.builder.debugLocalVar(6695 const debug_local_var = try o.builder.debugLocalVar(
6692 try o.builder.metadataString(name),6696 try o.builder.metadataString(name.toSlice(self.air)),
6693 self.file,6697 self.file,
6694 self.scope,6698 self.scope,
6695 self.prev_dbg_line,6699 self.prev_dbg_line,
...@@ -6712,15 +6716,25 @@ pub const FuncGen = struct {...@@ -6712,15 +6716,25 @@ pub const FuncGen = struct {
6712 return .none;6716 return .none;
6713 }6717 }
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 {
6716 const o = self.ng.object;6720 const o = self.ng.object;
6717 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6721 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6718 const operand = try self.resolveInst(pl_op.operand);6722 const operand = try self.resolveInst(pl_op.operand);
6719 const operand_ty = self.typeOf(pl_op.operand);6723 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(6726 const debug_local_var = if (is_arg) try o.builder.debugParameter(
6723 try o.builder.metadataString(name),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)),
6724 self.file,6738 self.file,
6725 self.scope,6739 self.scope,
6726 self.prev_dbg_line,6740 self.prev_dbg_line,
...@@ -8835,12 +8849,12 @@ pub const FuncGen = struct {...@@ -8835,12 +8849,12 @@ pub const FuncGen = struct {
8835 const lbrace_col = func.lbrace_column + 1;8849 const lbrace_col = func.lbrace_column + 1;
88368850
8837 const debug_parameter = try o.builder.debugParameter(8851 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)),
8839 self.file,8853 self.file,
8840 self.scope,8854 self.scope,
8841 lbrace_line,8855 lbrace_line,
8842 try o.lowerDebugType(inst_ty),8856 try o.lowerDebugType(inst_ty),
8843 @intCast(self.arg_index),8857 self.arg_index,
8844 );8858 );
88458859
8846 const old_location = self.wip.debug_location;8860 const old_location = self.wip.debug_location;
src/codegen/spirv.zig+2-2
...@@ -6366,8 +6366,8 @@ const NavGen = struct {...@@ -6366,8 +6366,8 @@ const NavGen = struct {
6366 fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void {6366 fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void {
6367 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6367 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6368 const target_id = try self.resolve(pl_op.operand);6368 const target_id = try self.resolve(pl_op.operand);
6369 const name = self.air.nullTerminatedString(pl_op.payload);6369 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
6370 try self.spv.debugName(target_id, name);6370 try self.spv.debugName(target_id, name.toSlice(self.air));
6371 }6371 }
63726372
6373 fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef {6373 fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
src/link/Dwarf.zig+135-7
...@@ -986,7 +986,9 @@ pub const WipNav = struct {...@@ -986,7 +986,9 @@ pub const WipNav = struct {
986 entry: Entry.Index,986 entry: Entry.Index,
987 any_children: bool,987 any_children: bool,
988 func: InternPool.Index,988 func: InternPool.Index,
989 func_sym_index: u32,
989 func_high_reloc: u32,990 func_high_reloc: u32,
991 inlined_funcs_high_reloc: std.ArrayListUnmanaged(u32),
990 debug_info: std.ArrayListUnmanaged(u8),992 debug_info: std.ArrayListUnmanaged(u8),
991 debug_line: std.ArrayListUnmanaged(u8),993 debug_line: std.ArrayListUnmanaged(u8),
992 debug_loclists: std.ArrayListUnmanaged(u8),994 debug_loclists: std.ArrayListUnmanaged(u8),
...@@ -994,6 +996,7 @@ pub const WipNav = struct {...@@ -994,6 +996,7 @@ pub const WipNav = struct {
994996
995 pub fn deinit(wip_nav: *WipNav) void {997 pub fn deinit(wip_nav: *WipNav) void {
996 const gpa = wip_nav.dwarf.gpa;998 const gpa = wip_nav.dwarf.gpa;
999 if (wip_nav.func != .none) wip_nav.inlined_funcs_high_reloc.deinit(gpa);
997 wip_nav.debug_info.deinit(gpa);1000 wip_nav.debug_info.deinit(gpa);
998 wip_nav.debug_line.deinit(gpa);1001 wip_nav.debug_line.deinit(gpa);
999 wip_nav.debug_loclists.deinit(gpa);1002 wip_nav.debug_loclists.deinit(gpa);
...@@ -1004,10 +1007,10 @@ pub const WipNav = struct {...@@ -1004,10 +1007,10 @@ pub const WipNav = struct {
1004 return wip_nav.debug_info.writer(wip_nav.dwarf.gpa);1007 return wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
1005 }1008 }
10061009
1007 pub const VarTag = enum { local_arg, local_var };1010 pub const LocalTag = enum { local_arg, local_var };
1008 pub fn genVarDebugInfo(1011 pub fn genLocalDebugInfo(
1009 wip_nav: *WipNav,1012 wip_nav: *WipNav,
1010 tag: VarTag,1013 tag: LocalTag,
1011 name: []const u8,1014 name: []const u8,
1012 ty: Type,1015 ty: Type,
1013 loc: Loc,1016 loc: Loc,
...@@ -1078,7 +1081,45 @@ pub const WipNav = struct {...@@ -1078,7 +1081,45 @@ pub const WipNav = struct {
1078 try dlw.writeByte(DW.LNS.set_epilogue_begin);1081 try dlw.writeByte(DW.LNS.set_epilogue_begin);
1079 }1082 }
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
1081 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {1121 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {
1122 wip_nav.any_children = true;
1082 const zcu = wip_nav.pt.zcu;1123 const zcu = wip_nav.pt.zcu;
1083 const dwarf = wip_nav.dwarf;1124 const dwarf = wip_nav.dwarf;
1084 if (wip_nav.func == func) return;1125 if (wip_nav.func == func) return;
...@@ -1217,6 +1258,15 @@ pub const WipNav = struct {...@@ -1217,6 +1258,15 @@ pub const WipNav = struct {
1217 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);1258 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
1218 }1259 }
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
1220 fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 {1270 fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 {
1221 const dwarf = wip_nav.dwarf;1271 const dwarf = wip_nav.dwarf;
1222 const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).cross_entry_relocs;1272 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...@@ -1554,7 +1604,9 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1554 .entry = nav_gop.value_ptr.*,1604 .entry = nav_gop.value_ptr.*,
1555 .any_children = false,1605 .any_children = false,
1556 .func = .none,1606 .func = .none,
1607 .func_sym_index = undefined,
1557 .func_high_reloc = undefined,1608 .func_high_reloc = undefined,
1609 .inlined_funcs_high_reloc = undefined,
1558 .debug_info = .{},1610 .debug_info = .{},
1559 .debug_line = .{},1611 .debug_line = .{},
1560 .debug_loclists = .{},1612 .debug_loclists = .{},
...@@ -1694,6 +1746,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -1694,6 +1746,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
16941746
1695 const func_type = ip.indexToKey(func.ty).func_type;1747 const func_type = ip.indexToKey(func.ty).func_type;
1696 wip_nav.func = nav_val.toIntern();1748 wip_nav.func = nav_val.toIntern();
1749 wip_nav.func_sym_index = sym_index;
1750 wip_nav.inlined_funcs_high_reloc = .{};
16971751
1698 const diw = wip_nav.debug_info.writer(dwarf.gpa);1752 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1699 try uleb128(diw, @intFromEnum(AbbrevCode.decl_func));1753 try uleb128(diw, @intFromEnum(AbbrevCode.decl_func));
...@@ -1706,17 +1760,19 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In...@@ -1706,17 +1760,19 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
1706 try wip_nav.strp(nav.fqn.toSlice(ip));1760 try wip_nav.strp(nav.fqn.toSlice(ip));
1707 try wip_nav.refType(Type.fromInterned(func_type.return_type));1761 try wip_nav.refType(Type.fromInterned(func_type.return_type));
1708 const external_relocs = &dwarf.debug_info.section.getUnit(unit).external_relocs;1762 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(.{
1710 .source_entry = wip_nav.entry,1765 .source_entry = wip_nav.entry,
1711 .source_off = @intCast(wip_nav.debug_info.items.len),1766 .source_off = @intCast(wip_nav.debug_info.items.len),
1712 .target_sym = sym_index,1767 .target_sym = sym_index,
1713 });1768 });
1714 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));1769 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1715 wip_nav.func_high_reloc = @intCast(external_relocs.items.len);1770 wip_nav.func_high_reloc = @intCast(external_relocs.items.len);
1716 try external_relocs.append(dwarf.gpa, .{1771 external_relocs.appendAssumeCapacity(.{
1717 .source_entry = wip_nav.entry,1772 .source_entry = wip_nav.entry,
1718 .source_off = @intCast(wip_nav.debug_info.items.len),1773 .source_off = @intCast(wip_nav.debug_info.items.len),
1719 .target_sym = sym_index,1774 .target_sym = sym_index,
1775 .target_off = undefined,
1720 });1776 });
1721 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));1777 try diw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
1722 try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse1778 try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse
...@@ -1779,7 +1835,8 @@ pub fn finishWipNav(...@@ -1779,7 +1835,8 @@ pub fn finishWipNav(
1779 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});1835 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
17801836
1781 if (wip_nav.func != .none) {1837 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;
1783 if (wip_nav.any_children) {1840 if (wip_nav.any_children) {
1784 const diw = wip_nav.debug_info.writer(dwarf.gpa);1841 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1785 try uleb128(diw, @intFromEnum(AbbrevCode.null));1842 try uleb128(diw, @intFromEnum(AbbrevCode.null));
...@@ -1864,7 +1921,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -1864,7 +1921,9 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
1864 .entry = undefined,1921 .entry = undefined,
1865 .any_children = false,1922 .any_children = false,
1866 .func = .none,1923 .func = .none,
1924 .func_sym_index = undefined,
1867 .func_high_reloc = undefined,1925 .func_high_reloc = undefined,
1926 .inlined_funcs_high_reloc = undefined,
1868 .debug_info = .{},1927 .debug_info = .{},
1869 .debug_line = .{},1928 .debug_line = .{},
1870 .debug_loclists = .{},1929 .debug_loclists = .{},
...@@ -1875,6 +1934,40 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -1875,6 +1934,40 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
1875 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);1934 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
1876 errdefer _ = dwarf.navs.pop();1935 errdefer _ = dwarf.navs.pop();
1877 switch (ip.indexToKey(nav_val.toIntern())) {1936 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 },
1878 .struct_type => done: {1971 .struct_type => done: {
1879 const loaded_struct = ip.loadStructType(nav_val.toIntern());1972 const loaded_struct = ip.loadStructType(nav_val.toIntern());
18801973
...@@ -2277,7 +2370,9 @@ fn updateType(...@@ -2277,7 +2370,9 @@ fn updateType(
2277 .entry = dwarf.types.get(type_index).?,2370 .entry = dwarf.types.get(type_index).?,
2278 .any_children = false,2371 .any_children = false,
2279 .func = .none,2372 .func = .none,
2373 .func_sym_index = undefined,
2280 .func_high_reloc = undefined,2374 .func_high_reloc = undefined,
2375 .inlined_funcs_high_reloc = undefined,
2281 .debug_info = .{},2376 .debug_info = .{},
2282 .debug_line = .{},2377 .debug_line = .{},
2283 .debug_loclists = .{},2378 .debug_loclists = .{},
...@@ -2678,7 +2773,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2678,7 +2773,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2678 .entry = type_gop.value_ptr.*,2773 .entry = type_gop.value_ptr.*,
2679 .any_children = false,2774 .any_children = false,
2680 .func = .none,2775 .func = .none,
2776 .func_sym_index = undefined,
2681 .func_high_reloc = undefined,2777 .func_high_reloc = undefined,
2778 .inlined_funcs_high_reloc = undefined,
2682 .debug_info = .{},2779 .debug_info = .{},
2683 .debug_line = .{},2780 .debug_line = .{},
2684 .debug_loclists = .{},2781 .debug_loclists = .{},
...@@ -2739,7 +2836,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP...@@ -2739,7 +2836,9 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
2739 .entry = type_gop.value_ptr.*,2836 .entry = type_gop.value_ptr.*,
2740 .any_children = false,2837 .any_children = false,
2741 .func = .none,2838 .func = .none,
2839 .func_sym_index = undefined,
2742 .func_high_reloc = undefined,2840 .func_high_reloc = undefined,
2841 .inlined_funcs_high_reloc = undefined,
2743 .debug_info = .{},2842 .debug_info = .{},
2744 .debug_line = .{},2843 .debug_line = .{},
2745 .debug_loclists = .{},2844 .debug_loclists = .{},
...@@ -2913,7 +3012,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {...@@ -2913,7 +3012,9 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
2913 .entry = entry,3012 .entry = entry,
2914 .any_children = false,3013 .any_children = false,
2915 .func = .none,3014 .func = .none,
3015 .func_sym_index = undefined,
2916 .func_high_reloc = undefined,3016 .func_high_reloc = undefined,
3017 .inlined_funcs_high_reloc = undefined,
2917 .debug_info = .{},3018 .debug_info = .{},
2918 .debug_line = .{},3019 .debug_line = .{},
2919 .debug_loclists = .{},3020 .debug_loclists = .{},
...@@ -3283,6 +3384,8 @@ const AbbrevCode = enum(u8) {...@@ -3283,6 +3384,8 @@ const AbbrevCode = enum(u8) {
3283 decl_var,3384 decl_var,
3284 decl_func,3385 decl_func,
3285 decl_func_empty,3386 decl_func_empty,
3387 decl_func_generic,
3388 decl_func_generic_empty,
3286 // the rest are unrestricted3389 // the rest are unrestricted
3287 compile_unit,3390 compile_unit,
3288 module,3391 module,
...@@ -3317,10 +3420,11 @@ const AbbrevCode = enum(u8) {...@@ -3317,10 +3420,11 @@ const AbbrevCode = enum(u8) {
3317 struct_type,3420 struct_type,
3318 packed_struct_type,3421 packed_struct_type,
3319 union_type,3422 union_type,
3423 inlined_func,
3320 local_arg,3424 local_arg,
3321 local_var,3425 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
3325 const Attr = struct {3429 const Attr = struct {
3326 DeclValEnum(DW.AT),3430 DeclValEnum(DW.AT),
...@@ -3424,6 +3528,19 @@ const AbbrevCode = enum(u8) {...@@ -3424,6 +3528,19 @@ const AbbrevCode = enum(u8) {
3424 .{ .noreturn, .flag },3528 .{ .noreturn, .flag },
3425 },3529 },
3426 },3530 },
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 },
3427 .compile_unit = .{3544 .compile_unit = .{
3428 .tag = .compile_unit,3545 .tag = .compile_unit,
3429 .children = true,3546 .children = true,
...@@ -3679,6 +3796,17 @@ const AbbrevCode = enum(u8) {...@@ -3679,6 +3796,17 @@ const AbbrevCode = enum(u8) {
3679 .{ .alignment, .udata },3796 .{ .alignment, .udata },
3680 },3797 },
3681 },3798 },
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 },
3682 .local_arg = .{3810 .local_arg = .{
3683 .tag = .formal_parameter,3811 .tag = .formal_parameter,
3684 .attrs = &.{3812 .attrs = &.{
src/print_air.zig+4-6
...@@ -283,6 +283,7 @@ const Writer = struct {...@@ -283,6 +283,7 @@ const Writer = struct {
283283
284 .dbg_var_ptr,284 .dbg_var_ptr,
285 .dbg_var_val,285 .dbg_var_val,
286 .dbg_arg_inline,
286 => try w.writeDbgVar(s, inst),287 => try w.writeDbgVar(s, inst),
287288
288 .struct_field_ptr => try w.writeStructField(s, inst),289 .struct_field_ptr => try w.writeStructField(s, inst),
...@@ -358,10 +359,7 @@ const Writer = struct {...@@ -358,10 +359,7 @@ const Writer = struct {
358 try w.writeType(s, arg.ty.toType());359 try w.writeType(s, arg.ty.toType());
359 switch (arg.name) {360 switch (arg.name) {
360 .none => {},361 .none => {},
361 _ => {362 _ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}),
362 const name = w.air.nullTerminatedString(@intFromEnum(arg.name));
363 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
364 },
365 }363 }
366 }364 }
367365
...@@ -686,8 +684,8 @@ const Writer = struct {...@@ -686,8 +684,8 @@ const Writer = struct {
686 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {684 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
687 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;685 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
688 try w.writeOperand(s, inst, 0, pl_op.operand);686 try w.writeOperand(s, inst, 0, pl_op.operand);
689 const name = w.air.nullTerminatedString(pl_op.payload);687 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
690 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});688 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))});
691 }689 }
692690
693 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {691 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {