| author | |
| committer | |
| log | 62f7276501bee7460cd004c17fdc1545487ad99b |
| tree | 36681df690d8baf3e090072d4c2adab9a58a3f4d |
| parent | ef90eb0d4d88e0f4ab4ba72bfb2b523dbd5001fa |
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 the | 456 | /// 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 => bool | 461 | /// ?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 | } |
| 1564 | 1564 | ||
| 1565 | pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 { | 1565 | pub 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 | } | ||
| 1573 | 1575 | ||
| 1574 | /// Returns whether the given instruction must always be lowered, for instance | 1576 | /// 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 be | 1577 | /// 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 { |
| 339 | 339 | ||
| 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( |
| 464 | 464 | ||
| 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( |
| 1097 | 1098 | ||
| 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 { |
| 376 | 376 | ||
| 377 | c_import_buf: ?*std.ArrayList(u8) = null, | 377 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 378 | 378 | ||
| 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 lexically | 380 | /// instruction is emitted. It signals that the innermost lexically |
| 381 | /// enclosing `block`/`block_inline` should be translated into a real AIR | 381 | /// 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; |
| 6587 | 6587 | ||
| 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); |
| 6590 | 6590 | ||
| 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 | } |
| 6599 | 6599 | ||
| 6600 | pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 { | 6600 | pub 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 | } |
| 6609 | 6610 | ||
| 6610 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6611 | fn 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).?; |
| 7750 | 7751 | ||
| 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).?; |
| 7757 | 7758 | ||
| 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 | .none | 8268 | .none |
| 8268 | else | 8269 | 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 | } |
| 1242 | 1242 | ||
| 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 | .none | 2162 | .none |
| 2160 | else | 2163 | 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 { |
| 170 | 170 | ||
| 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), | ||
| 174 | 176 | ||
| 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 argument | 203 | else => unreachable, // not a possible argument |
| 202 | 204 | ||
| 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), |
| 803 | 806 | ||
| 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 { |
| 4220 | 4223 | ||
| 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)]; |
| 4223 | 4226 | 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 | } | ||
| 4234 | 4233 | ||
| 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); |
| 4648 | 4647 | ||
| 4649 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); | 4648 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); |
| 4650 | 4649 | ||
| 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 | }); |
| 4657 | 4656 |
src/arch/arm/CodeGen.zig+15-15| ... | @@ -248,7 +248,9 @@ const DbgInfoReloc = struct { | ... | @@ -248,7 +248,9 @@ const DbgInfoReloc = struct { |
| 248 | 248 | ||
| 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), | ||
| 252 | 254 | ||
| 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 argument | 281 | else => unreachable, // not a possible argument |
| 280 | }; | 282 | }; |
| 281 | 283 | ||
| 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), |
| 790 | 793 | ||
| 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)]; |
| 4201 | 4204 | ||
| 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 | } | ||
| 4212 | 4212 | ||
| 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); |
| 4616 | 4616 | ||
| 4617 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); | 4617 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); |
| 4618 | 4618 | ||
| 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 | }); |
| 4625 | 4625 |
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 { |
| 1644 | 1644 | ||
| 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), |
| 1648 | 1649 | ||
| 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)); | ||
| 4677 | 4677 | ||
| 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); | ||
| 5182 | 5188 | ||
| 5183 | const name = func.air.nullTerminatedString(pl_op.payload); | 5189 | const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 5184 | 5190 | try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air)); | |
| 5185 | try func.genVarDbgInfo(ty, mcv, name); | ||
| 5186 | 5191 | ||
| 5187 | return func.finishAir(inst, .unreach, .{ operand, .none, .none }); | 5192 | return func.finishAir(inst, .unreach, .{ operand, .none, .none }); |
| 5188 | } | 5193 | } |
| 5189 | 5194 | ||
| 5190 | fn genVarDbgInfo( | 5195 | fn 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), |
| 647 | 648 | ||
| 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 { |
| 1662 | 1663 | ||
| 1663 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 1664 | fn 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 variable | 1668 | // 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)); | ||
| 3586 | 3586 | ||
| 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 { |
| 1917 | 1917 | ||
| 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), | ||
| 1922 | 1923 | ||
| 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 { |
| 2585 | 2586 | ||
| 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 | } |
| 6456 | 6457 | ||
| 6457 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void { | 6458 | fn 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, &.{}); |
| 6460 | 6466 | ||
| ... | @@ -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 |
| 6464 | 6470 | ||
| 6465 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand }); | 6471 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand }); |
| 6466 | 6472 | ||
| 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)}); |
| 6469 | 6475 | ||
| 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); |
| 6478 | 6484 | ||
| 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 data | 81 | /// MIR extra data |
| 82 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, | 82 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 83 | 83 | ||
| 84 | stack_args: std.ArrayListUnmanaged(StackVar) = .{}, | ||
| 85 | stack_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. |
| 88 | end_di_line: u32, | 85 | end_di_line: u32, |
| 89 | end_di_column: u32, | 86 | end_di_column: u32, |
| ... | @@ -728,12 +725,6 @@ const InstTracking = struct { | ... | @@ -728,12 +725,6 @@ const InstTracking = struct { |
| 728 | } | 725 | } |
| 729 | }; | 726 | }; |
| 730 | 727 | ||
| 731 | const StackVar = struct { | ||
| 732 | name: []const u8, | ||
| 733 | type: Type, | ||
| 734 | frame_addr: FrameAddr, | ||
| 735 | }; | ||
| 736 | |||
| 737 | const FrameAlloc = struct { | 728 | const 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 | } |
| 845 | 834 | ||
| 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 | }; |
| 915 | 904 | ||
| 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); |
| 925 | 911 | ||
| 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 | }; |
| 1015 | 1002 | ||
| 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); |
| 1022 | 1009 | ||
| 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 | } |
| 1359 | 1347 | ||
| 1348 | const MirTagAir = enum { dbg_local }; | ||
| 1349 | |||
| 1350 | fn 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 | |||
| 1360 | fn 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 | |||
| 1385 | fn 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 | |||
| 1360 | fn asmOpOnly(self: *Self, tag: Mir.Inst.FixedTag) !void { | 1398 | fn 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 | } |
| 1425 | 1463 | ||
| 1426 | fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: Immediate) !void { | 1464 | fn 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 | } |
| 1454 | 1483 | ||
| ... | @@ -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), |
| 2162 | 2192 | ||
| 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 { |
| 11951 | fn airDbgArg(self: *Self, inst: Air.Inst.Index) !void { | 11981 | fn 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 | } |
| 11963 | 11988 | ||
| 11964 | fn genVarDebugInfo( | 11989 | fn 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, .{ |
| 12019 | 12023 | .base = .{ .frame = frame_addr.index }, | |
| 12020 | fn 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 | } |
| 12037 | 12039 | ||
| ... | @@ -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 | } |
| 13073 | 13075 | ||
| 13074 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 13076 | fn 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 | } |
| 13087 | 13081 | ||
| 13088 | fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index { | 13082 | fn 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 code | 1 | //! This file contains the functionality for emitting x86_64 MIR as machine code |
| 2 | 2 | ||
| 3 | air: Air, | ||
| 3 | lower: Lower, | 4 | lower: Lower, |
| 4 | debug_output: DebugInfoOutput, | 5 | debug_output: DebugInfoOutput, |
| 5 | code: *std.ArrayList(u8), | 6 | code: *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) orelse | 369 | 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 | } |
| 291 | 375 | ||
| ... | @@ -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 { |
| 340 | 424 | ||
| 341 | const link = @import("../../link.zig"); | 425 | const link = @import("../../link.zig"); |
| 342 | const log = std.log.scoped(.emit); | 426 | const log = std.log.scoped(.emit); |
| 343 | const mem = std.mem; | ||
| 344 | const std = @import("std"); | 427 | const std = @import("std"); |
| 345 | 428 | ||
| 429 | const Air = @import("../../Air.zig"); | ||
| 346 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; | 430 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; |
| 347 | const Emit = @This(); | 431 | const Emit = @This(); |
| 348 | const Lower = @import("Lower.zig"); | 432 | const 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, |
| 4 | output_mode: std.builtin.OutputMode, | 4 | output_mode: std.builtin.OutputMode, |
| 5 | link_mode: std.builtin.LinkMode, | 5 | link_mode: std.builtin.LinkMode, |
| 6 | pic: bool, | 6 | pic: bool, |
| 7 | allocator: Allocator, | 7 | allocator: std.mem.Allocator, |
| 8 | mir: Mir, | 8 | mir: Mir, |
| 9 | cc: std.builtin.CallingConvention, | 9 | cc: std.builtin.CallingConvention, |
| 10 | err_msg: ?*ErrorMsg = null, | 10 | err_msg: ?*Zcu.ErrorMsg = null, |
| 11 | src_loc: Zcu.LazySrcLoc, | 11 | src_loc: Zcu.LazySrcLoc, |
| 12 | result_insts_len: u8 = undefined, | 12 | result_insts_len: u8 = undefined, |
| 13 | result_relocs_len: u8 = undefined, | 13 | result_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 { |
| 283 | pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error { | 289 | pub 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 | } |
| 289 | 295 | ||
| 290 | fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate { | 296 | pub 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)), |
| 298 | 305 | ||
| 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), |
| 310 | 318 | ||
| 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()), | ||
| 312 | 322 | ||
| 313 | else => unreachable, | 323 | else => unreachable, |
| 314 | }; | 324 | }; |
| 315 | } | 325 | } |
| 316 | 326 | ||
| 317 | fn mem(lower: Lower, payload: u32) Memory { | 327 | pub 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 | } |
| 320 | 330 | ||
| ... | @@ -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"); |
| 670 | const link = @import("../../link.zig"); | 676 | const link = @import("../../link.zig"); |
| 671 | const std = @import("std"); | 677 | const std = @import("std"); |
| 672 | 678 | ||
| 673 | const Air = @import("../../Air.zig"); | ||
| 674 | const Allocator = std.mem.Allocator; | ||
| 675 | const ErrorMsg = Zcu.ErrorMsg; | ||
| 676 | const Immediate = Instruction.Immediate; | 679 | const Immediate = Instruction.Immediate; |
| 677 | const Instruction = encoder.Instruction; | 680 | const Instruction = encoder.Instruction; |
| 678 | const Lower = @This(); | 681 | const 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, |
| 869 | 869 | ||
| 870 | /// Probe alignment | 870 | /// Probe alignment |
| 871 | /// Uses `ri` payload | 871 | /// Uses `ri` payload. |
| 872 | pseudo_probe_align_ri_s, | 872 | pseudo_probe_align_ri_s, |
| 873 | /// Probe adjust unrolled | 873 | /// Probe adjust unrolled |
| 874 | /// Uses `ri` payload | 874 | /// Uses `ri` payload. |
| 875 | pseudo_probe_adjust_unrolled_ri_s, | 875 | pseudo_probe_adjust_unrolled_ri_s, |
| 876 | /// Probe adjust setup | 876 | /// Probe adjust setup |
| 877 | /// Uses `rri` payload | 877 | /// Uses `rri` payload. |
| 878 | pseudo_probe_adjust_setup_rri_s, | 878 | pseudo_probe_adjust_setup_rri_s, |
| 879 | /// Probe adjust loop | 879 | /// Probe adjust loop |
| 880 | /// Uses `rr` payload | 880 | /// Uses `rr` payload. |
| 881 | pseudo_probe_adjust_loop_rr, | 881 | pseudo_probe_adjust_loop_rr, |
| 882 | /// Push registers | 882 | /// 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 epilogue | 894 | /// Start of epilogue |
| 895 | pseudo_dbg_epilogue_begin_none, | 895 | pseudo_dbg_epilogue_begin_none, |
| 896 | /// Start or end of inline function | 896 | /// 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, | ||
| 898 | 915 | ||
| 899 | /// Tombstone | 916 | /// 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 source | 1029 | /// * `atom_index` is the index of the source |
| 1002 | /// * `sym_index` is the index of the target | 1030 | /// * `sym_index` is the index of the target |
| ... | @@ -1225,6 +1253,7 @@ const builtin = @import("builtin"); | ... | @@ -1225,6 +1253,7 @@ const builtin = @import("builtin"); |
| 1225 | const encoder = @import("encoder.zig"); | 1253 | const encoder = @import("encoder.zig"); |
| 1226 | const std = @import("std"); | 1254 | const std = @import("std"); |
| 1227 | 1255 | ||
| 1256 | const Air = @import("../../Air.zig"); | ||
| 1228 | const IntegerBitSet = std.bit_set.IntegerBitSet; | 1257 | const IntegerBitSet = std.bit_set.IntegerBitSet; |
| 1229 | const InternPool = @import("../../InternPool.zig"); | 1258 | const InternPool = @import("../../InternPool.zig"); |
| 1230 | const Mir = @This(); | 1259 | const 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 | } |
| 130 | 130 | ||
| 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 | } |
| 134 | 134 | ||
| 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 | } |
| 160 | 160 | ||
| 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, |
| 3293 | 3293 | ||
| 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), |
| 3297 | 3297 | ||
| 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 { |
| 4590 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { | 4590 | fn 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); |
| 4597 | 4598 | ||
| 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 | } |
| 4603 | 4604 |
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, | ||
| 4773 | 4775 | ||
| 4774 | err_ret_trace: Builder.Value = .none, | 4776 | err_ret_trace: Builder.Value = .none, |
| 4775 | 4777 | ||
| ... | @@ -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), | ||
| 5086 | 5089 | ||
| 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 | } |
| 6682 | 6686 | ||
| ... | @@ -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); |
| 6690 | 6694 | ||
| 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 | } |
| 6714 | 6718 | ||
| 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); |
| 6721 | 6725 | ||
| 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; |
| 8836 | 8850 | ||
| 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 | ); |
| 8845 | 8859 | ||
| 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 | } |
| 6372 | 6372 | ||
| 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 { |
| 994 | 996 | ||
| 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 | } |
| 1006 | 1009 | ||
| 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 | } |
| 1080 | 1083 | ||
| 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 | } |
| 1219 | 1260 | ||
| 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 |
| 1694 | 1746 | ||
| 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 = .{}; | ||
| 1697 | 1751 | ||
| 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() orelse | 1778 | 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)}); |
| 1780 | 1836 | ||
| 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()); |
| 1880 | 1973 | ||
| ... | @@ -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 unrestricted | 3389 | // 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, |
| 3322 | 3426 | ||
| 3323 | const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_empty)); | 3427 | const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_func_generic_empty)); |
| 3324 | 3428 | ||
| 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 { |
| 283 | 283 | ||
| 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), |
| 287 | 288 | ||
| 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 | } |
| 367 | 365 | ||
| ... | @@ -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 | } |
| 692 | 690 | ||
| 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 { |