Commit c95b1bf2d3
Changed files (34)
lib
std
zig
src
Air
arch
aarch64
riscv64
sparc64
wasm
codegen
link
lib/std/zig/Zir.zig
@@ -4861,6 +4861,15 @@ pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const Zir.Inst.Index {
}
}
+pub fn getParamName(zir: Zir, param_inst: Inst.Index) ?NullTerminatedString {
+ const inst = zir.instructions.get(@intFromEnum(param_inst));
+ return switch (inst.tag) {
+ .param, .param_comptime => zir.extraData(Inst.Param, inst.data.pl_tok.payload_index).data.name,
+ .param_anytype, .param_anytype_comptime => inst.data.str_tok.start,
+ else => null,
+ };
+}
+
pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
const tags = zir.instructions.items(.tag);
const datas = zir.instructions.items(.data);
src/Air/print.zig
@@ -363,10 +363,7 @@ const Writer = struct {
fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
try w.writeType(s, arg.ty.toType());
- switch (arg.name) {
- .none => {},
- _ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}),
- }
+ try s.print(", {d}", .{arg.zir_param_index});
}
fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/arch/aarch64/CodeGen.zig
@@ -4208,15 +4208,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
while (self.args[arg_index] == .none) arg_index += 1;
self.arg_index = arg_index + 1;
- const ty = self.typeOfIndex(inst);
- const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
- const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
- if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{
- .tag = tag,
- .ty = ty,
- .name = name.toSlice(self.air),
- .mcv = self.args[arg_index],
- });
+ const zcu = self.pt.zcu;
+ const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
+ const file = zcu.fileByIndex(func_zir.file);
+ if (!file.mod.?.strip) {
+ const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
+ const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
+ const ty = self.typeOfIndex(inst);
+ const zir = &file.zir.?;
+ const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
+ try self.dbg_info_relocs.append(self.gpa, .{
+ .tag = tag,
+ .ty = ty,
+ .name = name,
+ .mcv = self.args[arg_index],
+ });
+ }
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/aarch64/Mir.zig
@@ -514,9 +514,7 @@ pub fn emit(
func_index: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
- air: *const @import("../../Air.zig"),
) codegen.CodeGenError!void {
- _ = air; // using this would be a bug
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const nav = func.owner_nav;
src/arch/arm/CodeGen.zig
@@ -4191,16 +4191,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
while (self.args[arg_index] == .none) arg_index += 1;
self.arg_index = arg_index + 1;
- const ty = self.typeOfIndex(inst);
- const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
-
- const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
- if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{
- .tag = tag,
- .ty = ty,
- .name = name.toSlice(self.air),
- .mcv = self.args[arg_index],
- });
+ const zcu = self.pt.zcu;
+ const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
+ const file = zcu.fileByIndex(func_zir.file);
+ if (!file.mod.?.strip) {
+ const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
+ const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
+ const ty = self.typeOfIndex(inst);
+ const zir = &file.zir.?;
+ const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
+ try self.dbg_info_relocs.append(self.gpa, .{
+ .tag = tag,
+ .ty = ty,
+ .name = name,
+ .mcv = self.args[arg_index],
+ });
+ }
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/arm/Mir.zig
@@ -294,9 +294,7 @@ pub fn emit(
func_index: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
- air: *const @import("../../Air.zig"),
) codegen.CodeGenError!void {
- _ = air; // using this would be a bug
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const nav = func.owner_nav;
src/arch/riscv64/CodeGen.zig
@@ -70,6 +70,7 @@ mod: *Package.Module,
target: *const std.Target,
args: []MCValue,
ret_mcv: InstTracking,
+func_index: InternPool.Index,
fn_type: Type,
arg_index: usize,
src_loc: Zcu.LazySrcLoc,
@@ -774,6 +775,7 @@ pub fn generate(
.owner = .{ .nav_index = func.owner_nav },
.args = undefined, // populated after `resolveCallingConventionValues`
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
+ .func_index = func_index,
.fn_type = fn_type,
.arg_index = 0,
.branch_stack = &branch_stack,
@@ -877,6 +879,7 @@ pub fn generateLazy(
.owner = .{ .lazy_sym = lazy_sym },
.args = undefined, // populated after `resolveCallingConventionValues`
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
+ .func_index = undefined,
.fn_type = undefined,
.arg_index = 0,
.branch_stack = undefined,
@@ -4724,10 +4727,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
return func.fail("TODO implement codegen airFieldParentPtr", .{});
}
-fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerError!void {
- const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
- const ty = arg.ty.toType();
- if (arg.name == .none) return;
+fn genArgDbgInfo(func: *const Func, name: []const u8, ty: Type, mcv: MCValue) InnerError!void {
+ assert(!func.mod.strip);
// TODO: Add a pseudo-instruction or something to defer this work until Emit.
// We aren't allowed to interact with linker state here.
@@ -4736,7 +4737,7 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr
.dwarf => |dw| switch (mcv) {
.register => |reg| dw.genLocalDebugInfo(
.local_arg,
- arg.name.toSlice(func.air),
+ name,
ty,
.{ .reg = reg.dwarfNum() },
) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),
@@ -4749,6 +4750,8 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr
}
fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
+ const zcu = func.pt.zcu;
+
var arg_index = func.arg_index;
// we skip over args that have no bits
@@ -4765,7 +4768,14 @@ fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
try func.genCopy(arg_ty, dst_mcv, src_mcv);
- try func.genArgDbgInfo(inst, src_mcv);
+ const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
+ // can delete `func.func_index` if this logic is moved to emit
+ const func_zir = zcu.funcInfo(func.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
+ const file = zcu.fileByIndex(func_zir.file);
+ const zir = &file.zir.?;
+ const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
+
+ try func.genArgDbgInfo(name, arg_ty, src_mcv);
break :result dst_mcv;
};
src/arch/riscv64/Mir.zig
@@ -117,9 +117,7 @@ pub fn emit(
func_index: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
- air: *const @import("../../Air.zig"),
) codegen.CodeGenError!void {
- _ = air; // using this would be a bug
const zcu = pt.zcu;
const comp = zcu.comp;
const gpa = comp.gpa;
src/arch/sparc64/CodeGen.zig
@@ -995,23 +995,29 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
self.arg_index += 1;
const ty = self.typeOfIndex(inst);
-
- const arg = self.args[arg_index];
- const mcv = blk: {
- switch (arg) {
+ const mcv: MCValue = blk: {
+ switch (self.args[arg_index]) {
.stack_offset => |off| {
const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse {
return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
};
const offset = off + abi_size;
- break :blk MCValue{ .stack_offset = offset };
+ break :blk .{ .stack_offset = offset };
},
- else => break :blk arg,
+ else => |mcv| break :blk mcv,
}
};
- self.genArgDbgInfo(inst, mcv) catch |err|
- return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});
+ const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
+ const file = zcu.fileByIndex(func_zir.file);
+ if (!file.mod.?.strip) {
+ const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
+ const zir = &file.zir.?;
+ const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
+
+ self.genArgDbgInfo(name, ty, mcv) catch |err|
+ return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});
+ }
if (self.liveness.isUnused(inst))
return self.finishAirBookkeeping();
@@ -3539,11 +3545,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Air.
self.finishAirBookkeeping();
}
-fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
- const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
- const ty = arg.ty.toType();
- if (arg.name == .none) return;
-
+fn genArgDbgInfo(self: Self, name: []const u8, ty: Type, mcv: MCValue) !void {
// TODO: Add a pseudo-instruction or something to defer this work until Emit.
// We aren't allowed to interact with linker state here.
if (true) return;
@@ -3551,7 +3553,7 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
.dwarf => |dw| switch (mcv) {
.register => |reg| try dw.genLocalDebugInfo(
.local_arg,
- arg.name.toSlice(self.air),
+ name,
ty,
.{ .reg = reg.dwarfNum() },
),
src/arch/sparc64/Mir.zig
@@ -382,9 +382,7 @@ pub fn emit(
func_index: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
- air: *const @import("../../Air.zig"),
) codegen.CodeGenError!void {
- _ = air; // using this would be a bug
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
const nav = func.owner_nav;
src/arch/wasm/CodeGen.zig
@@ -1877,7 +1877,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.dbg_inline_block => cg.airDbgInlineBlock(inst),
.dbg_var_ptr => cg.airDbgVar(inst, .local_var, true),
.dbg_var_val => cg.airDbgVar(inst, .local_var, false),
- .dbg_arg_inline => cg.airDbgVar(inst, .local_arg, false),
+ .dbg_arg_inline => cg.airDbgVar(inst, .arg, false),
.call => cg.airCall(inst, .auto),
.call_always_tail => cg.airCall(inst, .always_tail),
@@ -6427,7 +6427,7 @@ fn airDbgInlineBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airDbgVar(
cg: *CodeGen,
inst: Air.Inst.Index,
- local_tag: link.File.Dwarf.WipNav.LocalTag,
+ local_tag: link.File.Dwarf.WipNav.LocalVarTag,
is_ptr: bool,
) InnerError!void {
_ = is_ptr;
src/arch/x86_64/CodeGen.zig
@@ -129,7 +129,6 @@ target: *const std.Target,
owner: Owner,
inline_func: InternPool.Index,
mod: *Module,
-arg_index: u32,
args: []MCValue,
va_info: union {
sysv: struct {
@@ -151,6 +150,8 @@ eflags_inst: ?Air.Inst.Index = null,
mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,
/// MIR extra data
mir_extra: std.ArrayListUnmanaged(u32) = .empty,
+mir_local_name_bytes: std.ArrayListUnmanaged(u8) = .empty,
+mir_local_types: std.ArrayListUnmanaged(InternPool.Index) = .empty,
mir_table: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,
/// The value is an offset into the `Function` `code` from the beginning.
@@ -978,8 +979,10 @@ pub fn generate(
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
const func = zcu.funcInfo(func_index);
+ const func_zir = func.zir_body_inst.resolveFull(ip).?;
+ const file = zcu.fileByIndex(func_zir.file);
const fn_type: Type = .fromInterned(func.ty);
- const mod = zcu.navFileScope(func.owner_nav).mod.?;
+ const mod = file.mod.?;
var function: CodeGen = .{
.gpa = gpa,
@@ -991,7 +994,6 @@ pub fn generate(
.bin_file = bin_file,
.owner = .{ .nav_index = func.owner_nav },
.inline_func = func_index,
- .arg_index = undefined,
.args = undefined, // populated after `resolveCallingConventionValues`
.va_info = undefined, // populated after `resolveCallingConventionValues`
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
@@ -1011,6 +1013,8 @@ pub fn generate(
function.inst_tracking.deinit(gpa);
function.epilogue_relocs.deinit(gpa);
function.mir_instructions.deinit(gpa);
+ function.mir_local_name_bytes.deinit(gpa);
+ function.mir_local_types.deinit(gpa);
function.mir_extra.deinit(gpa);
function.mir_table.deinit(gpa);
}
@@ -1078,7 +1082,7 @@ pub fn generate(
);
}
- function.gen() catch |err| switch (err) {
+ function.gen(&file.zir.?, func_zir.inst, func.comptime_args, call_info.air_arg_count) catch |err| switch (err) {
error.CodegenFail => return error.CodegenFail,
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
else => |e| return e,
@@ -1097,17 +1101,32 @@ pub fn generate(
var mir: Mir = .{
.instructions = .empty,
.extra = &.{},
+ .local_name_bytes = &.{},
+ .local_types = &.{},
.table = &.{},
.frame_locs = .empty,
};
errdefer mir.deinit(gpa);
mir.instructions = function.mir_instructions.toOwnedSlice();
mir.extra = try function.mir_extra.toOwnedSlice(gpa);
+ mir.local_name_bytes = try function.mir_local_name_bytes.toOwnedSlice(gpa);
+ mir.local_types = try function.mir_local_types.toOwnedSlice(gpa);
mir.table = try function.mir_table.toOwnedSlice(gpa);
mir.frame_locs = function.frame_locs.toOwnedSlice();
return mir;
}
+pub fn toTmpMir(cg: *CodeGen) Mir {
+ return .{
+ .instructions = cg.mir_instructions.slice(),
+ .extra = cg.mir_extra.items,
+ .local_name_bytes = cg.mir_local_name_bytes.items,
+ .local_types = cg.mir_local_types.items,
+ .table = cg.mir_table.items,
+ .frame_locs = cg.frame_locs.slice(),
+ };
+}
+
pub fn generateLazy(
bin_file: *link.File,
pt: Zcu.PerThread,
@@ -1130,7 +1149,6 @@ pub fn generateLazy(
.bin_file = bin_file,
.owner = .{ .lazy_sym = lazy_sym },
.inline_func = undefined,
- .arg_index = undefined,
.args = undefined,
.va_info = undefined,
.ret_mcv = undefined,
@@ -1141,6 +1159,8 @@ pub fn generateLazy(
defer {
function.inst_tracking.deinit(gpa);
function.mir_instructions.deinit(gpa);
+ function.mir_local_name_bytes.deinit(gpa);
+ function.mir_local_types.deinit(gpa);
function.mir_extra.deinit(gpa);
function.mir_table.deinit(gpa);
}
@@ -1156,21 +1176,12 @@ pub fn generateLazy(
else => |e| return e,
};
- var mir: Mir = .{
- .instructions = function.mir_instructions.toOwnedSlice(),
- .extra = try function.mir_extra.toOwnedSlice(gpa),
- .table = try function.mir_table.toOwnedSlice(gpa),
- .frame_locs = function.frame_locs.toOwnedSlice(),
- };
- defer mir.deinit(gpa);
-
var emit: Emit = .{
- .air = function.air,
.lower = .{
.bin_file = bin_file,
.target = function.target,
.allocator = gpa,
- .mir = mir,
+ .mir = function.toTmpMir(),
.cc = .auto,
.src_loc = src_loc,
.output_mode = comp.config.output_mode,
@@ -1240,22 +1251,16 @@ fn formatWipMir(
writer: anytype,
) @TypeOf(writer).Error!void {
const comp = data.self.bin_file.comp;
- const mod = comp.root_mod;
var lower: Lower = .{
.bin_file = data.self.bin_file,
.target = data.self.target,
.allocator = data.self.gpa,
- .mir = .{
- .instructions = data.self.mir_instructions.slice(),
- .extra = data.self.mir_extra.items,
- .table = data.self.mir_table.items,
- .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(),
- },
+ .mir = data.self.toTmpMir(),
.cc = .auto,
.src_loc = data.self.src_loc,
.output_mode = comp.config.output_mode,
.link_mode = comp.config.link_mode,
- .pic = mod.pic,
+ .pic = data.self.mod.pic,
};
var first = true;
for ((lower.lowerMir(data.inst) catch |err| switch (err) {
@@ -1291,7 +1296,9 @@ fn formatWipMir(
.pseudo_dbg_epilogue_begin_none,
.pseudo_dbg_enter_block_none,
.pseudo_dbg_leave_block_none,
+ .pseudo_dbg_arg_none,
.pseudo_dbg_var_args_none,
+ .pseudo_dbg_var_none,
.pseudo_dead_none,
=> {},
.pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(
@@ -1299,57 +1306,47 @@ fn formatWipMir(
mir_inst.data.line_column,
),
.pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{
- ip.getNav(ip.indexToKey(mir_inst.data.func).func.owner_nav).name.fmt(ip),
+ ip.getNav(ip.indexToKey(mir_inst.data.ip_index).func.owner_nav).name.fmt(ip),
}),
- .pseudo_dbg_local_a => try writer.print(" {}", .{mir_inst.data.a.air_inst}),
- .pseudo_dbg_local_ai_s => try writer.print(" {}, {d}", .{
- mir_inst.data.ai.air_inst,
- @as(i32, @bitCast(mir_inst.data.ai.i)),
+ .pseudo_dbg_arg_i_s, .pseudo_dbg_var_i_s => try writer.print(" {d}", .{
+ @as(i32, @bitCast(mir_inst.data.i.i)),
}),
- .pseudo_dbg_local_ai_u => try writer.print(" {}, {d}", .{
- mir_inst.data.ai.air_inst,
- mir_inst.data.ai.i,
+ .pseudo_dbg_arg_i_u, .pseudo_dbg_var_i_u => try writer.print(" {d}", .{
+ mir_inst.data.i.i,
}),
- .pseudo_dbg_local_ai_64 => try writer.print(" {}, {d}", .{
- mir_inst.data.ai.air_inst,
- lower.mir.extraData(Mir.Imm64, mir_inst.data.ai.i).data.decode(),
+ .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => try writer.print(" {d}", .{
+ mir_inst.data.i64,
}),
- .pseudo_dbg_local_as => {
+ .pseudo_dbg_arg_reloc, .pseudo_dbg_var_reloc => {
const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
- .base = .{ .reloc = mir_inst.data.as.sym_index },
+ .base = .{ .reloc = mir_inst.data.reloc.sym_index },
+ .disp = mir_inst.data.reloc.off,
}) };
- try writer.print(" {}, {}", .{ mir_inst.data.as.air_inst, mem_op.fmt(.m) });
+ try writer.print(" {}", .{mem_op.fmt(.m)});
},
- .pseudo_dbg_local_aso => {
- const sym_off = lower.mir.extraData(bits.SymbolOffset, mir_inst.data.ax.payload).data;
+ .pseudo_dbg_arg_ro, .pseudo_dbg_var_ro => {
const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
- .base = .{ .reloc = sym_off.sym_index },
- .disp = sym_off.off,
+ .base = .{ .reg = mir_inst.data.ro.reg },
+ .disp = mir_inst.data.ro.off,
}) };
- try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });
+ try writer.print(" {}", .{mem_op.fmt(.m)});
},
- .pseudo_dbg_local_aro => {
- const air_off = lower.mir.extraData(Mir.AirOffset, mir_inst.data.rx.payload).data;
+ .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
- .base = .{ .reg = mir_inst.data.rx.r1 },
- .disp = air_off.off,
+ .base = .{ .frame = mir_inst.data.fa.index },
+ .disp = mir_inst.data.fa.off,
}) };
- try writer.print(" {}, {}", .{ air_off.air_inst, mem_op.fmt(.m) });
+ try writer.print(" {}", .{mem_op.fmt(.m)});
},
- .pseudo_dbg_local_af => {
- const frame_addr = lower.mir.extraData(bits.FrameAddr, mir_inst.data.ax.payload).data;
- const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
- .base = .{ .frame = frame_addr.index },
- .disp = frame_addr.off,
- }) };
- try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });
- },
- .pseudo_dbg_local_am => {
+ .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
const mem_op: encoder.Instruction.Operand = .{
- .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.ax.payload).data.decode(),
+ .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.x.payload).data.decode(),
};
- try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });
+ try writer.print(" {}", .{mem_op.fmt(.m)});
},
+ .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try writer.print(" {}", .{
+ Value.fromInterned(mir_inst.data.ip_index).fmtValue(data.self.pt),
+ }),
}
}
}
@@ -1640,124 +1637,6 @@ fn asmPlaceholder(self: *CodeGen) !Mir.Inst.Index {
});
}
-const MirTagAir = enum { dbg_local };
-
-fn asmAir(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index) !void {
- _ = try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_a,
- },
- .data = .{ .a = .{ .air_inst = inst } },
- });
-}
-
-fn asmAirImmediate(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index, imm: Immediate) !void {
- switch (imm) {
- .signed => |s| _ = try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_ai_s,
- },
- .data = .{ .ai = .{
- .air_inst = inst,
- .i = @bitCast(s),
- } },
- }),
- .unsigned => |u| _ = if (std.math.cast(u32, u)) |small| try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_ai_u,
- },
- .data = .{ .ai = .{
- .air_inst = inst,
- .i = small,
- } },
- }) else try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_ai_64,
- },
- .data = .{ .ai = .{
- .air_inst = inst,
- .i = try self.addExtra(Mir.Imm64.encode(u)),
- } },
- }),
- .reloc => |sym_off| _ = if (sym_off.off == 0) try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_as,
- },
- .data = .{ .as = .{
- .air_inst = inst,
- .sym_index = sym_off.sym_index,
- } },
- }) else try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_aso,
- },
- .data = .{ .ax = .{
- .air_inst = inst,
- .payload = try self.addExtra(sym_off),
- } },
- }),
- }
-}
-
-fn asmAirRegisterImmediate(
- self: *CodeGen,
- tag: MirTagAir,
- inst: Air.Inst.Index,
- reg: Register,
- imm: Immediate,
-) !void {
- _ = try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_aro,
- },
- .data = .{ .rx = .{
- .r1 = reg,
- .payload = try self.addExtra(Mir.AirOffset{
- .air_inst = inst,
- .off = imm.signed,
- }),
- } },
- });
-}
-
-fn asmAirFrameAddress(
- self: *CodeGen,
- tag: MirTagAir,
- inst: Air.Inst.Index,
- frame_addr: bits.FrameAddr,
-) !void {
- _ = try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_af,
- },
- .data = .{ .ax = .{
- .air_inst = inst,
- .payload = try self.addExtra(frame_addr),
- } },
- });
-}
-
-fn asmAirMemory(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index, m: Memory) !void {
- _ = try self.addInst(.{
- .tag = .pseudo,
- .ops = switch (tag) {
- .dbg_local => .pseudo_dbg_local_am,
- },
- .data = .{ .ax = .{
- .air_inst = inst,
- .payload = try self.addExtra(Mir.Memory.encode(m)),
- } },
- });
-}
-
fn asmOpOnly(self: *CodeGen, tag: Mir.Inst.FixedTag) !void {
_ = try self.addInst(.{
.tag = tag[1],
@@ -2233,7 +2112,13 @@ fn asmMemoryRegisterImmediate(
});
}
-fn gen(self: *CodeGen) InnerError!void {
+fn gen(
+ self: *CodeGen,
+ zir: *const std.zig.Zir,
+ func_zir_inst: std.zig.Zir.Inst.Index,
+ comptime_args: InternPool.Index.Slice,
+ air_arg_count: u32,
+) InnerError!void {
const pt = self.pt;
const zcu = pt.zcu;
const fn_info = zcu.typeToFunc(self.fn_type).?;
@@ -2303,7 +2188,7 @@ fn gen(self: *CodeGen) InnerError!void {
if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
- try self.genBody(self.air.getMainBody());
+ try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {
var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);
@@ -2438,20 +2323,81 @@ fn gen(self: *CodeGen) InnerError!void {
}
} else {
if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
- try self.genBody(self.air.getMainBody());
+ try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
}
}
-fn checkInvariantsAfterAirInst(self: *CodeGen) void {
- assert(!self.register_manager.lockedRegsExist());
+fn genMainBody(
+ cg: *CodeGen,
+ zir: *const std.zig.Zir,
+ func_zir_inst: std.zig.Zir.Inst.Index,
+ comptime_args: InternPool.Index.Slice,
+ air_arg_count: u32,
+) InnerError!void {
+ const pt = cg.pt;
+ const zcu = pt.zcu;
+ const ip = &zcu.intern_pool;
+
+ const main_body = cg.air.getMainBody();
+ const air_args_body = main_body[0..air_arg_count];
+ try cg.genBody(air_args_body);
+
+ if (!cg.mod.strip) {
+ var air_arg_index: usize = 0;
+ const fn_info = zcu.typeToFunc(cg.fn_type).?;
+ var fn_param_index: usize = 0;
+ try cg.mir_local_types.ensureTotalCapacity(cg.gpa, fn_info.param_types.len);
+ var zir_param_index: usize = 0;
+ for (zir.getParamBody(func_zir_inst)) |zir_param_inst| {
+ const name = zir.nullTerminatedString(zir.getParamName(zir_param_inst) orelse continue);
+ defer zir_param_index += 1;
+ try cg.mir_local_name_bytes.appendSlice(cg.gpa, name[0 .. name.len + 1]);
+
+ if (comptime_args.len > 0) switch (comptime_args.get(ip)[zir_param_index]) {
+ .none => {},
+ else => |comptime_arg| {
+ _ = try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = .pseudo_dbg_arg_val,
+ .data = .{ .ip_index = comptime_arg },
+ });
+ continue;
+ },
+ };
+
+ const arg_ty: Type = .fromInterned(fn_info.param_types.get(ip)[fn_param_index]);
+ fn_param_index += 1;
+ cg.mir_local_types.appendAssumeCapacity(arg_ty.toIntern());
+
+ if (air_arg_index == air_args_body.len) {
+ try cg.asmPseudo(.pseudo_dbg_arg_none);
+ continue;
+ }
+ const air_arg_inst = air_args_body[air_arg_index];
+ const air_arg_data = cg.air.instructions.items(.data)[air_arg_index].arg;
+ if (air_arg_data.zir_param_index != zir_param_index) {
+ try cg.asmPseudo(.pseudo_dbg_arg_none);
+ continue;
+ }
+ air_arg_index += 1;
+ try cg.genLocalDebugInfo(.arg, arg_ty, cg.getResolvedInstValue(air_arg_inst).short);
+ }
+ if (fn_info.is_var_args) try cg.asmPseudo(.pseudo_dbg_var_args_none);
+ }
+
+ try cg.genBody(main_body[air_arg_count..]);
+}
+
+fn checkInvariantsAfterAirInst(cg: *CodeGen) void {
+ assert(!cg.register_manager.lockedRegsExist());
if (std.debug.runtime_safety) {
// check consistency of tracked registers
- var it = self.register_manager.free_registers.iterator(.{ .kind = .unset });
+ var it = cg.register_manager.free_registers.iterator(.{ .kind = .unset });
while (it.next()) |index| {
- const tracked_inst = self.register_manager.registers[index];
- const tracking = self.getResolvedInstValue(tracked_inst);
+ const tracked_inst = cg.register_manager.registers[index];
+ const tracking = cg.getResolvedInstValue(tracked_inst);
for (tracking.getRegs()) |reg| {
if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;
} else unreachable; // tracked register not in use
@@ -2459,10 +2405,10 @@ fn checkInvariantsAfterAirInst(self: *CodeGen) void {
}
}
-fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
- if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_enter_block_none);
- try self.genBody(body);
- if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_leave_block_none);
+fn genBodyBlock(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
+ if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_enter_block_none);
+ try cg.genBody(body);
+ if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_leave_block_none);
}
fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
@@ -2474,25 +2420,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
const air_datas = cg.air.instructions.items(.data);
const use_old = cg.target.ofmt == .coff;
- cg.arg_index = 0;
- for (body) |inst| switch (air_tags[@intFromEnum(inst)]) {
- .arg => {
- wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
- verbose_tracking_log.debug("{}", .{cg.fmtTracking()});
-
- cg.reused_operands = .initEmpty();
- try cg.inst_tracking.ensureUnusedCapacity(cg.gpa, 1);
-
- try cg.airArg(inst);
-
- try cg.resetTemps(@enumFromInt(0));
- cg.checkInvariantsAfterAirInst();
- },
- else => break,
- };
-
- if (cg.arg_index == 0) try cg.airDbgVarArgs();
- cg.arg_index = 0;
for (body) |inst| {
if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;
wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
@@ -2506,20 +2433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
.shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"),
// zig fmt: on
- .arg => if (!cg.mod.strip) {
- // skip zero-bit arguments as they don't have a corresponding arg instruction
- var arg_index = cg.arg_index;
- while (cg.args[arg_index] == .none) arg_index += 1;
- cg.arg_index = arg_index + 1;
-
- const name = air_datas[@intFromEnum(inst)].arg.name;
- if (name != .none) try cg.genLocalDebugInfo(inst, cg.getResolvedInstValue(inst).short);
- if (cg.liveness.isUnused(inst)) try cg.processDeath(inst);
-
- for (cg.args[arg_index + 1 ..]) |arg| {
- if (arg != .none) break;
- } else try cg.airDbgVarArgs();
- },
+ .arg => try cg.airArg(inst),
.add, .add_optimized, .add_wrap => |air_tag| if (use_old) try cg.airBinOp(inst, switch (air_tag) {
else => unreachable,
.add, .add_optimized => .add,
@@ -85181,19 +85095,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
if (!cg.mod.strip) _ = try cg.addInst(.{
.tag = .pseudo,
.ops = .pseudo_dbg_enter_inline_func,
- .data = .{ .func = dbg_inline_block.data.func },
+ .data = .{ .ip_index = dbg_inline_block.data.func },
});
try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[dbg_inline_block.end..][0..dbg_inline_block.data.body_len]));
if (!cg.mod.strip) _ = try cg.addInst(.{
.tag = .pseudo,
.ops = .pseudo_dbg_leave_inline_func,
- .data = .{ .func = old_inline_func },
+ .data = .{ .ip_index = old_inline_func },
});
},
.dbg_var_ptr,
.dbg_var_val,
.dbg_arg_inline,
- => if (use_old) try cg.airDbgVar(inst) else if (!cg.mod.strip) {
+ => |air_tag| if (use_old) try cg.airDbgVar(inst) else if (!cg.mod.strip) {
const pl_op = air_datas[@intFromEnum(inst)].pl_op;
var ops = try cg.tempsFromOperands(inst, .{pl_op.operand});
var mcv = ops[0].tracking(cg).short;
@@ -85209,7 +85123,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
},
},
}
- try cg.genLocalDebugInfo(inst, ops[0].tracking(cg).short);
+
+ const name_nts: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
+ assert(name_nts != .none);
+ const name = name_nts.toSlice(cg.air);
+ try cg.mir_local_name_bytes.appendSlice(cg.gpa, name[0 .. name.len + 1]);
+
+ const ty = cg.typeOf(pl_op.operand);
+ try cg.mir_local_types.append(cg.gpa, ty.toIntern());
+
+ try cg.genLocalDebugInfo(air_tag, ty, ops[0].tracking(cg).short);
try ops[0].die(cg);
},
.is_null => if (use_old) try cg.airIsNull(inst) else {
@@ -173321,16 +173244,14 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
}
fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
- const pt = self.pt;
- const zcu = pt.zcu;
- // skip zero-bit arguments as they don't have a corresponding arg instruction
- var arg_index = self.arg_index;
- while (self.args[arg_index] == .none) arg_index += 1;
- self.arg_index = arg_index + 1;
-
+ const zcu = self.pt.zcu;
+ const arg_index = for (self.args, 0..) |arg, arg_index| {
+ if (arg != .none) break arg_index;
+ } else unreachable;
+ const src_mcv = self.args[arg_index];
+ self.args = self.args[arg_index + 1 ..];
const result: MCValue = if (self.mod.strip and self.liveness.isUnused(inst)) .unreach else result: {
const arg_ty = self.typeOfIndex(inst);
- const src_mcv = self.args[arg_index];
switch (src_mcv) {
.register, .register_pair, .load_frame => {
for (src_mcv.getRegs()) |reg| self.register_manager.getRegAssumeFree(reg, inst);
@@ -173429,68 +173350,108 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
return self.finishAir(inst, result, .{ .none, .none, .none });
}
-fn airDbgVarArgs(self: *CodeGen) !void {
- if (self.mod.strip) return;
- if (!self.pt.zcu.typeToFunc(self.fn_type).?.is_var_args) return;
- try self.asmPseudo(.pseudo_dbg_var_args_none);
-}
-
-fn genLocalDebugInfo(
- self: *CodeGen,
- inst: Air.Inst.Index,
- mcv: MCValue,
-) !void {
- if (self.mod.strip) return;
- switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) {
+fn genLocalDebugInfo(cg: *CodeGen, air_tag: Air.Inst.Tag, ty: Type, mcv: MCValue) !void {
+ assert(!cg.mod.strip);
+ _ = switch (air_tag) {
else => unreachable,
- .arg, .dbg_arg_inline, .dbg_var_val => |tag| {
- switch (mcv) {
- .none => try self.asmAir(.dbg_local, inst),
- .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
- .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)),
- .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr),
- .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)),
- else => {
- const ty = switch (tag) {
- else => unreachable,
- .arg => self.typeOfIndex(inst),
- .dbg_arg_inline, .dbg_var_val => self.typeOf(
- self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand,
- ),
- };
- const frame_index = try self.allocFrameIndex(.initSpill(ty, self.pt.zcu));
- try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
- try self.asmAirMemory(.dbg_local, inst, .{
- .base = .{ .frame = frame_index },
- .mod = .{ .rm = .{ .size = .qword } },
- });
+ .arg, .dbg_var_val, .dbg_arg_inline => switch (mcv) {
+ .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
+ .immediate => |imm| if (std.math.cast(u32, imm)) |small| try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = switch (air_tag) {
+ else => unreachable,
+ .arg, .dbg_arg_inline => .pseudo_dbg_arg_i_u,
+ .dbg_var_val => .pseudo_dbg_var_i_u,
},
- }
+ .data = .{ .i = .{ .i = small } },
+ }) else try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = switch (air_tag) {
+ else => unreachable,
+ .arg, .dbg_arg_inline => .pseudo_dbg_arg_i_64,
+ .dbg_var_val => .pseudo_dbg_var_i_64,
+ },
+ .data = .{ .i64 = imm },
+ }),
+ .lea_frame => |frame_addr| try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = switch (air_tag) {
+ else => unreachable,
+ .arg, .dbg_arg_inline => .pseudo_dbg_arg_fa,
+ .dbg_var_val => .pseudo_dbg_var_fa,
+ },
+ .data = .{ .fa = frame_addr },
+ }),
+ .lea_symbol => |sym_off| try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = switch (air_tag) {
+ else => unreachable,
+ .arg, .dbg_arg_inline => .pseudo_dbg_arg_reloc,
+ .dbg_var_val => .pseudo_dbg_var_reloc,
+ },
+ .data = .{ .reloc = sym_off },
+ }),
+ else => {
+ const frame_index = try cg.allocFrameIndex(.initSpill(ty, cg.pt.zcu));
+ try cg.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
+ _ = try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = switch (air_tag) {
+ else => unreachable,
+ .arg, .dbg_arg_inline => .pseudo_dbg_arg_m,
+ .dbg_var_val => .pseudo_dbg_var_m,
+ },
+ .data = .{ .x = .{
+ .payload = try cg.addExtra(Mir.Memory.encode(.{
+ .base = .{ .frame = frame_index },
+ .mod = .{ .rm = .{ .size = .qword } },
+ })),
+ } },
+ });
+ },
},
.dbg_var_ptr => switch (mcv) {
else => unreachable,
- .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
- .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{
- .base = .{ .frame = frame_addr.index },
- .mod = .{ .rm = .{
- .size = .qword,
- .disp = frame_addr.off,
+ .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
+ .lea_frame => |frame_addr| try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = .pseudo_dbg_var_m,
+ .data = .{ .x = .{
+ .payload = try cg.addExtra(Mir.Memory.encode(.{
+ .base = .{ .frame = frame_addr.index },
+ .mod = .{ .rm = .{
+ .size = .qword,
+ .disp = frame_addr.off,
+ } },
+ })),
} },
}),
// debug info should explicitly ignore pcrel requirements
- .lea_symbol, .lea_pcrel => |sym_off| try self.asmAirMemory(.dbg_local, inst, .{
- .base = .{ .reloc = sym_off.sym_index },
- .mod = .{ .rm = .{
- .size = .qword,
- .disp = sym_off.off,
+ .lea_symbol, .lea_pcrel => |sym_off| try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = .pseudo_dbg_var_m,
+ .data = .{ .x = .{
+ .payload = try cg.addExtra(Mir.Memory.encode(.{
+ .base = .{ .reloc = sym_off.sym_index },
+ .mod = .{ .rm = .{
+ .size = .qword,
+ .disp = sym_off.off,
+ } },
+ })),
} },
}),
- .lea_direct, .lea_got => |sym_index| try self.asmAirMemory(.dbg_local, inst, .{
- .base = .{ .reloc = sym_index },
- .mod = .{ .rm = .{ .size = .qword } },
+ .lea_direct, .lea_got => |sym_index| try cg.addInst(.{
+ .tag = .pseudo,
+ .ops = .pseudo_dbg_var_m,
+ .data = .{ .x = .{
+ .payload = try cg.addExtra(Mir.Memory.encode(.{
+ .base = .{ .reloc = sym_index },
+ .mod = .{ .rm = .{ .size = .qword } },
+ })),
+ } },
}),
},
- }
+ };
}
fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void {
@@ -173514,8 +173475,8 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
@ptrCast(self.air.extra.items[extra.end..][0..extra.data.args_len]);
const ExpectedContents = extern struct {
- tys: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),
- vals: [16][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
+ tys: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
+ vals: [32][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
};
var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
@@ -173570,9 +173531,9 @@ fn genCall(self: *CodeGen, info: union(enum) {
const fn_info = zcu.typeToFunc(fn_ty).?;
const ExpectedContents = extern struct {
- var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),
- frame_indices: [16]FrameIndex,
- reg_locks: [16][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),
+ var_args: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
+ frame_indices: [32]FrameIndex,
+ reg_locks: [32][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),
};
var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
@@ -174488,10 +174449,21 @@ fn genTry(
return result;
}
-fn airDbgVar(self: *CodeGen, inst: Air.Inst.Index) !void {
- const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
- try self.genLocalDebugInfo(inst, try self.resolveInst(pl_op.operand));
- return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
+fn airDbgVar(cg: *CodeGen, inst: Air.Inst.Index) !void {
+ if (cg.mod.strip) return;
+ const air_tag = cg.air.instructions.items(.tag)[@intFromEnum(inst)];
+ const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
+
+ const name_nts: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
+ assert(name_nts != .none);
+ const name = name_nts.toSlice(cg.air);
+ try cg.mir_local_name_bytes.appendSlice(cg.gpa, name[0 .. name.len + 1]);
+
+ const ty = cg.typeOf(pl_op.operand);
+ try cg.mir_local_types.append(cg.gpa, ty.toIntern());
+
+ try cg.genLocalDebugInfo(air_tag, ty, try cg.resolveInst(pl_op.operand));
+ return cg.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
}
fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {
@@ -181477,6 +181449,7 @@ fn lowerUav(self: *CodeGen, val: Value, alignment: InternPool.Alignment) InnerEr
const CallMCValues = struct {
args: []MCValue,
+ air_arg_count: u32,
return_value: InstTracking,
stack_byte_count: u31,
stack_align: InternPool.Alignment,
@@ -181512,13 +181485,14 @@ fn resolveCallingConventionValues(
const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);
defer allocator.free(param_types);
- for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src|
- dest.* = .fromInterned(src);
+ for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*param_ty, arg_ty|
+ param_ty.* = .fromInterned(arg_ty);
for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty|
param_ty.* = self.promoteVarArg(arg_ty);
var result: CallMCValues = .{
.args = try self.gpa.alloc(MCValue, param_types.len),
+ .air_arg_count = 0,
// These undefined values must be populated before returning from this function.
.return_value = undefined,
.stack_byte_count = 0,
@@ -181640,6 +181614,7 @@ fn resolveCallingConventionValues(
// Input params
for (param_types, result.args) |ty, *arg| {
assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
+ result.air_arg_count += 1;
switch (cc) {
.x86_64_sysv => {},
.x86_64_win => {
@@ -181812,6 +181787,7 @@ fn resolveCallingConventionValues(
arg.* = .none;
continue;
}
+ result.air_arg_count += 1;
const param_size: u31 = @intCast(param_ty.abiSize(zcu));
if (abi.zigcc.params_in_regs) switch (self.regClassForType(param_ty)) {
.general_purpose, .gphi => if (param_gpr.len >= 1 and param_size <= @as(u4, switch (self.target.cpu.arch) {
src/arch/x86_64/Emit.zig
@@ -1,6 +1,5 @@
//! This file contains the functionality for emitting x86_64 MIR as machine code
-air: Air,
lower: Lower,
atom_index: u32,
debug_output: link.File.DebugInfoOutput,
@@ -22,6 +21,8 @@ pub fn emitMir(emit: *Emit) Error!void {
defer relocs.deinit(emit.lower.allocator);
var table_relocs: std.ArrayListUnmanaged(TableReloc) = .empty;
defer table_relocs.deinit(emit.lower.allocator);
+ var local_name_index: usize = 0;
+ var local_index: usize = 0;
for (0..emit.lower.mir.instructions.len) |mir_i| {
const mir_index: Mir.Inst.Index = @intCast(mir_i);
code_offset_mapping[mir_index] = @intCast(emit.code.items.len);
@@ -338,7 +339,7 @@ pub fn emitMir(emit: *Emit) Error!void {
log.debug("mirDbgEnterInline (line={d}, col={d})", .{
emit.prev_di_loc.line, emit.prev_di_loc.column,
});
- try dwarf.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
+ try dwarf.enterInlineFunc(mir_inst.data.ip_index, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
},
.plan9 => {},
.none => {},
@@ -348,77 +349,61 @@ pub fn emitMir(emit: *Emit) Error!void {
log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
emit.prev_di_loc.line, emit.prev_di_loc.column,
});
- try dwarf.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);
+ try dwarf.leaveInlineFunc(mir_inst.data.ip_index, emit.code.items.len);
},
.plan9 => {},
.none => {},
},
- .pseudo_dbg_local_a,
- .pseudo_dbg_local_ai_s,
- .pseudo_dbg_local_ai_u,
- .pseudo_dbg_local_ai_64,
- .pseudo_dbg_local_as,
- .pseudo_dbg_local_aso,
- .pseudo_dbg_local_aro,
- .pseudo_dbg_local_af,
- .pseudo_dbg_local_am,
+ .pseudo_dbg_arg_none,
+ .pseudo_dbg_arg_i_s,
+ .pseudo_dbg_arg_i_u,
+ .pseudo_dbg_arg_i_64,
+ .pseudo_dbg_arg_reloc,
+ .pseudo_dbg_arg_ro,
+ .pseudo_dbg_arg_fa,
+ .pseudo_dbg_arg_m,
+ .pseudo_dbg_var_none,
+ .pseudo_dbg_var_i_s,
+ .pseudo_dbg_var_i_u,
+ .pseudo_dbg_var_i_64,
+ .pseudo_dbg_var_reloc,
+ .pseudo_dbg_var_ro,
+ .pseudo_dbg_var_fa,
+ .pseudo_dbg_var_m,
=> switch (emit.debug_output) {
.dwarf => |dwarf| {
var loc_buf: [2]link.File.Dwarf.Loc = undefined;
- const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {
+ const loc: link.File.Dwarf.Loc = loc: switch (mir_inst.ops) {
else => unreachable,
- .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },
- .pseudo_dbg_local_ai_s,
- .pseudo_dbg_local_ai_u,
- .pseudo_dbg_local_ai_64,
- => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {
- loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {
+ .pseudo_dbg_arg_none, .pseudo_dbg_var_none => .empty,
+ .pseudo_dbg_arg_i_s,
+ .pseudo_dbg_arg_i_u,
+ .pseudo_dbg_var_i_s,
+ .pseudo_dbg_var_i_u,
+ => .{ .stack_value = stack_value: {
+ loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.i.i)) {
.signed => |s| .{ .consts = s },
.unsigned => |u| .{ .constu = u },
};
break :stack_value &loc_buf[0];
- } } },
- .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{
- .addr_reloc = mir_inst.data.as.sym_index,
} },
- .pseudo_dbg_local_aso => loc: {
- const sym_off = emit.lower.mir.extraData(
- bits.SymbolOffset,
- mir_inst.data.ax.payload,
- ).data;
- break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
- sym: {
- loc_buf[0] = .{ .addr_reloc = sym_off.sym_index };
- break :sym &loc_buf[0];
- },
- off: {
- loc_buf[1] = .{ .consts = sym_off.off };
- break :off &loc_buf[1];
- },
- } } };
- },
- .pseudo_dbg_local_aro => loc: {
- const air_off = emit.lower.mir.extraData(
- Mir.AirOffset,
- mir_inst.data.rx.payload,
- ).data;
- break :loc .{ air_off.air_inst, .{ .plus = .{
- reg: {
- loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
- break :reg &loc_buf[0];
- },
- off: {
- loc_buf[1] = .{ .consts = air_off.off };
- break :off &loc_buf[1];
- },
- } } };
- },
- .pseudo_dbg_local_af => loc: {
- const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
- bits.FrameAddr,
- mir_inst.data.ax.payload,
- ).data);
- break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
+ .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => .{ .stack_value = stack_value: {
+ loc_buf[0] = .{ .constu = mir_inst.data.i64 };
+ break :stack_value &loc_buf[0];
+ } },
+ .pseudo_dbg_arg_reloc, .pseudo_dbg_var_reloc => .{ .plus = .{
+ sym: {
+ loc_buf[0] = .{ .addr_reloc = mir_inst.data.reloc.sym_index };
+ break :sym &loc_buf[0];
+ },
+ off: {
+ loc_buf[1] = .{ .consts = mir_inst.data.reloc.off };
+ break :off &loc_buf[1];
+ },
+ } },
+ .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
+ const reg_off = emit.lower.mir.resolveFrameAddr(mir_inst.data.fa);
+ break :loc .{ .plus = .{
reg: {
loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
break :reg &loc_buf[0];
@@ -427,11 +412,11 @@ pub fn emitMir(emit: *Emit) Error!void {
loc_buf[1] = .{ .consts = reg_off.off };
break :off &loc_buf[1];
},
- } } };
+ } };
},
- .pseudo_dbg_local_am => loc: {
- const mem = emit.lower.mem(undefined, mir_inst.data.ax.payload);
- break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
+ .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
+ const mem = emit.lower.mem(undefined, mir_inst.data.x.payload);
+ break :loc .{ .plus = .{
base: {
loc_buf[0] = switch (mem.base()) {
.none => .{ .constu = 0 },
@@ -449,30 +434,64 @@ pub fn emitMir(emit: *Emit) Error!void {
};
break :disp &loc_buf[1];
},
- } } };
+ } };
},
};
- const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;
- const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));
- const name: Air.NullTerminatedString = switch (air_inst.tag) {
- else => unreachable,
- .arg => air_inst.data.arg.name,
- .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
- };
- try dwarf.genLocalDebugInfo(
- switch (air_inst.tag) {
+
+ const local_name_bytes = emit.lower.mir.local_name_bytes[local_name_index..];
+ const local_name = local_name_bytes[0..std.mem.indexOfScalar(u8, local_name_bytes, 0).? :0];
+ local_name_index += local_name.len + 1;
+
+ const local_type = emit.lower.mir.local_types[local_index];
+ local_index += 1;
+
+ try dwarf.genLocalVarDebugInfo(
+ switch (mir_inst.ops) {
else => unreachable,
- .arg, .dbg_arg_inline => .local_arg,
- .dbg_var_ptr, .dbg_var_val => .local_var,
+ .pseudo_dbg_arg_none,
+ .pseudo_dbg_arg_i_s,
+ .pseudo_dbg_arg_i_u,
+ .pseudo_dbg_arg_i_64,
+ .pseudo_dbg_arg_reloc,
+ .pseudo_dbg_arg_ro,
+ .pseudo_dbg_arg_fa,
+ .pseudo_dbg_arg_m,
+ .pseudo_dbg_arg_val,
+ => .arg,
+ .pseudo_dbg_var_none,
+ .pseudo_dbg_var_i_s,
+ .pseudo_dbg_var_i_u,
+ .pseudo_dbg_var_i_64,
+ .pseudo_dbg_var_reloc,
+ .pseudo_dbg_var_ro,
+ .pseudo_dbg_var_fa,
+ .pseudo_dbg_var_m,
+ .pseudo_dbg_var_val,
+ => .local_var,
},
- name.toSlice(emit.air),
- switch (air_inst.tag) {
+ local_name,
+ .fromInterned(local_type),
+ loc,
+ );
+ },
+ .plan9 => {},
+ .none => {},
+ },
+ .pseudo_dbg_arg_val, .pseudo_dbg_var_val => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ const local_name_bytes = emit.lower.mir.local_name_bytes[local_name_index..];
+ const local_name = local_name_bytes[0..std.mem.indexOfScalar(u8, local_name_bytes, 0).? :0];
+ local_name_index += local_name.len + 1;
+
+ try dwarf.genLocalConstDebugInfo(
+ emit.lower.src_loc,
+ switch (mir_inst.ops) {
else => unreachable,
- .arg => emit.air.typeOfIndex(air_inst_index, ip),
- .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),
- .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
+ .pseudo_dbg_arg_val => .comptime_arg,
+ .pseudo_dbg_var_val => .local_const,
},
- loc,
+ local_name,
+ .fromInterned(mir_inst.data.ip_index),
);
},
.plan9 => {},
@@ -611,11 +630,10 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
}
const bits = @import("bits.zig");
+const Emit = @This();
+const InternPool = @import("../../InternPool.zig");
const link = @import("../../link.zig");
const log = std.log.scoped(.emit);
-const std = @import("std");
-
-const Air = @import("../../Air.zig");
-const Emit = @This();
const Lower = @import("Lower.zig");
const Mir = @import("Mir.zig");
+const std = @import("std");
src/arch/x86_64/Lower.zig
@@ -327,16 +327,25 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.pseudo_dbg_leave_block_none,
.pseudo_dbg_enter_inline_func,
.pseudo_dbg_leave_inline_func,
- .pseudo_dbg_local_a,
- .pseudo_dbg_local_ai_s,
- .pseudo_dbg_local_ai_u,
- .pseudo_dbg_local_ai_64,
- .pseudo_dbg_local_as,
- .pseudo_dbg_local_aso,
- .pseudo_dbg_local_aro,
- .pseudo_dbg_local_af,
- .pseudo_dbg_local_am,
+ .pseudo_dbg_arg_none,
+ .pseudo_dbg_arg_i_s,
+ .pseudo_dbg_arg_i_u,
+ .pseudo_dbg_arg_i_64,
+ .pseudo_dbg_arg_reloc,
+ .pseudo_dbg_arg_ro,
+ .pseudo_dbg_arg_fa,
+ .pseudo_dbg_arg_m,
+ .pseudo_dbg_arg_val,
.pseudo_dbg_var_args_none,
+ .pseudo_dbg_var_none,
+ .pseudo_dbg_var_i_s,
+ .pseudo_dbg_var_i_u,
+ .pseudo_dbg_var_i_64,
+ .pseudo_dbg_var_reloc,
+ .pseudo_dbg_var_ro,
+ .pseudo_dbg_var_fa,
+ .pseudo_dbg_var_m,
+ .pseudo_dbg_var_val,
.pseudo_dead_none,
=> {},
@@ -364,7 +373,8 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
.i_s,
.mi_s,
.rmi_s,
- .pseudo_dbg_local_ai_s,
+ .pseudo_dbg_arg_i_s,
+ .pseudo_dbg_var_i_s,
=> .s(@bitCast(i)),
.ii,
@@ -379,13 +389,17 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
.mri,
.rrm,
.rrmi,
- .pseudo_dbg_local_ai_u,
+ .pseudo_dbg_arg_i_u,
+ .pseudo_dbg_var_i_u,
=> .u(i),
.ri_64,
- .pseudo_dbg_local_ai_64,
=> .u(lower.mir.extraData(Mir.Imm64, i).data.decode()),
+ .pseudo_dbg_arg_i_64,
+ .pseudo_dbg_var_i_64,
+ => unreachable,
+
else => unreachable,
};
}
src/arch/x86_64/Mir.zig
@@ -9,6 +9,8 @@
instructions: std.MultiArrayList(Inst).Slice,
/// The meaning of this data is determined by `Inst.Tag` value.
extra: []const u32,
+local_name_bytes: []const u8,
+local_types: []const InternPool.Index,
table: []const Inst.Index,
frame_locs: std.MultiArrayList(FrameLoc).Slice,
@@ -1522,6 +1524,7 @@ pub const Inst = struct {
pseudo_cfi_escape_bytes,
/// End of prologue
+ /// Uses `none` payload.
pseudo_dbg_prologue_end_none,
/// Update debug line with is_stmt register set
/// Uses `line_column` payload.
@@ -1530,44 +1533,76 @@ pub const Inst = struct {
/// Uses `line_column` payload.
pseudo_dbg_line_line_column,
/// Start of epilogue
+ /// Uses `none` payload.
pseudo_dbg_epilogue_begin_none,
/// Start of lexical block
+ /// Uses `none` payload.
pseudo_dbg_enter_block_none,
/// End of lexical block
+ /// Uses `none` payload.
pseudo_dbg_leave_block_none,
/// Start of inline function
+ /// Uses `ip_index` payload.
pseudo_dbg_enter_inline_func,
/// End of inline function
+ /// Uses `ip_index` payload.
pseudo_dbg_leave_inline_func,
- /// Local argument or variable.
- /// Uses `a` payload.
- pseudo_dbg_local_a,
- /// Local argument or variable.
- /// Uses `ai` payload.
- pseudo_dbg_local_ai_s,
- /// Local argument or variable.
- /// Uses `ai` payload.
- pseudo_dbg_local_ai_u,
- /// Local argument or variable.
- /// Uses `ai` payload with extra data of type `Imm64`.
- pseudo_dbg_local_ai_64,
- /// Local argument or variable.
- /// Uses `as` payload.
- pseudo_dbg_local_as,
- /// Local argument or variable.
- /// Uses `ax` payload with extra data of type `bits.SymbolOffset`.
- pseudo_dbg_local_aso,
- /// Local argument or variable.
- /// Uses `rx` payload with extra data of type `AirOffset`.
- pseudo_dbg_local_aro,
- /// Local argument or variable.
- /// Uses `ax` payload with extra data of type `bits.FrameAddr`.
- pseudo_dbg_local_af,
- /// Local argument or variable.
- /// Uses `ax` payload with extra data of type `Memory`.
- pseudo_dbg_local_am,
+ /// Local argument.
+ /// Uses `none` payload.
+ pseudo_dbg_arg_none,
+ /// Local argument.
+ /// Uses `i` payload.
+ pseudo_dbg_arg_i_s,
+ /// Local argument.
+ /// Uses `i` payload.
+ pseudo_dbg_arg_i_u,
+ /// Local argument.
+ /// Uses `i64` payload.
+ pseudo_dbg_arg_i_64,
+ /// Local argument.
+ /// Uses `reloc` payload.
+ pseudo_dbg_arg_reloc,
+ /// Local argument.
+ /// Uses `ro` payload.
+ pseudo_dbg_arg_ro,
+ /// Local argument.
+ /// Uses `fa` payload.
+ pseudo_dbg_arg_fa,
+ /// Local argument.
+ /// Uses `x` payload with extra data of type `Memory`.
+ pseudo_dbg_arg_m,
+ /// Local argument.
+ /// Uses `ip_index` payload.
+ pseudo_dbg_arg_val,
/// Remaining arguments are varargs.
pseudo_dbg_var_args_none,
+ /// Local variable.
+ /// Uses `none` payload.
+ pseudo_dbg_var_none,
+ /// Local variable.
+ /// Uses `i` payload.
+ pseudo_dbg_var_i_s,
+ /// Local variable.
+ /// Uses `i` payload.
+ pseudo_dbg_var_i_u,
+ /// Local variable.
+ /// Uses `i64` payload.
+ pseudo_dbg_var_i_64,
+ /// Local variable.
+ /// Uses `reloc` payload.
+ pseudo_dbg_var_reloc,
+ /// Local variable.
+ /// Uses `ro` payload.
+ pseudo_dbg_var_ro,
+ /// Local variable.
+ /// Uses `fa` payload.
+ pseudo_dbg_var_fa,
+ /// Local variable.
+ /// Uses `x` payload with extra data of type `Memory`.
+ pseudo_dbg_var_m,
+ /// Local variable.
+ /// Uses `ip_index` payload.
+ pseudo_dbg_var_val,
/// Tombstone
/// Emitter should skip this instruction.
@@ -1584,6 +1619,7 @@ pub const Inst = struct {
inst: Index,
},
/// A 32-bit immediate value.
+ i64: u64,
i: struct {
fixes: Fixes = ._,
i: u32,
@@ -1683,31 +1719,18 @@ pub const Inst = struct {
return std.mem.sliceAsBytes(mir.extra[bytes.payload..])[0..bytes.len];
}
},
- a: struct {
- air_inst: Air.Inst.Index,
- },
- ai: struct {
- air_inst: Air.Inst.Index,
- i: u32,
- },
- as: struct {
- air_inst: Air.Inst.Index,
- sym_index: u32,
- },
- ax: struct {
- air_inst: Air.Inst.Index,
- payload: u32,
- },
/// Relocation for the linker where:
/// * `sym_index` is the index of the target
/// * `off` is the offset from the target
reloc: bits.SymbolOffset,
+ fa: bits.FrameAddr,
+ ro: bits.RegisterOffset,
/// Debug line and column position
line_column: struct {
line: u32,
column: u32,
},
- func: InternPool.Index,
+ ip_index: InternPool.Index,
/// Register list
reg_list: RegisterList,
};
@@ -1760,8 +1783,6 @@ pub const Inst = struct {
}
};
-pub const AirOffset = struct { air_inst: Air.Inst.Index, off: i32 };
-
/// Used in conjunction with payload to transfer a list of used registers in a compact manner.
pub const RegisterList = struct {
bitset: BitSet,
@@ -1924,6 +1945,8 @@ pub const Memory = struct {
pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
mir.instructions.deinit(gpa);
gpa.free(mir.extra);
+ gpa.free(mir.local_name_bytes);
+ gpa.free(mir.local_types);
gpa.free(mir.table);
mir.frame_locs.deinit(gpa);
mir.* = undefined;
@@ -1937,8 +1960,6 @@ pub fn emit(
func_index: InternPool.Index,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
- /// TODO: remove dependency on this argument. This blocks enabling `Zcu.Feature.separate_thread`.
- air: *const Air,
) codegen.CodeGenError!void {
const zcu = pt.zcu;
const comp = zcu.comp;
@@ -1948,7 +1969,6 @@ pub fn emit(
const nav = func.owner_nav;
const mod = zcu.navFileScope(nav).mod.?;
var e: Emit = .{
- .air = air.*,
.lower = .{
.bin_file = lf,
.target = &mod.resolved_target.result,
@@ -1998,7 +2018,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end:
@field(result, field.name) = switch (field.type) {
u32 => mir.extra[i],
i32, Memory.Info => @bitCast(mir.extra[i]),
- bits.FrameIndex, Air.Inst.Index => @enumFromInt(mir.extra[i]),
+ bits.FrameIndex => @enumFromInt(mir.extra[i]),
else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
};
i += 1;
@@ -2043,7 +2063,6 @@ const builtin = @import("builtin");
const encoder = @import("encoder.zig");
const std = @import("std");
-const Air = @import("../../Air.zig");
const IntegerBitSet = std.bit_set.IntegerBitSet;
const InternPool = @import("../../InternPool.zig");
const Mir = @This();
src/codegen/llvm.zig
@@ -9509,15 +9509,21 @@ pub const FuncGen = struct {
const inst_ty = self.typeOfIndex(inst);
- const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
- if (name == .none) return arg_val;
-
const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());
+ const func_zir = func.zir_body_inst.resolveFull(&zcu.intern_pool).?;
+ const file = zcu.fileByIndex(func_zir.file);
+
+ const mod = file.mod.?;
+ if (mod.strip) return arg_val;
+ const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
+ const zir = &file.zir.?;
+ const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
+
const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;
const lbrace_col = func.lbrace_column + 1;
const debug_parameter = try o.builder.debugParameter(
- try o.builder.metadataString(name.toSlice(self.air)),
+ try o.builder.metadataString(name),
self.file,
self.scope,
lbrace_line,
@@ -9535,7 +9541,6 @@ pub const FuncGen = struct {
},
};
- const mod = self.ng.ownerModule();
if (isByRef(inst_ty, zcu)) {
_ = try self.wip.callIntrinsic(
.normal,
src/link/Elf/ZigObject.zig
@@ -1417,9 +1417,6 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- /// This may be `undefined`; only pass it to `emitFunction`.
- /// This parameter will eventually be removed.
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
const tracy = trace(@src());
defer tracy.end();
@@ -1448,7 +1445,6 @@ pub fn updateFunc(
mir,
&code_buffer,
if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
- maybe_undef_air,
);
const code = code_buffer.items;
@@ -2363,7 +2359,6 @@ const trace = @import("../../tracy.zig").trace;
const std = @import("std");
const Allocator = std.mem.Allocator;
-const Air = @import("../../Air.zig");
const Archive = @import("Archive.zig");
const Atom = @import("Atom.zig");
const Dwarf = @import("../Dwarf.zig");
src/link/MachO/ZigObject.zig
@@ -778,9 +778,6 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- /// This may be `undefined`; only pass it to `emitFunction`.
- /// This parameter will eventually be removed.
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
const tracy = trace(@src());
defer tracy.end();
@@ -806,7 +803,6 @@ pub fn updateFunc(
mir,
&code_buffer,
if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
- maybe_undef_air,
);
const code = code_buffer.items;
@@ -1815,7 +1811,6 @@ const target_util = @import("../../target.zig");
const trace = @import("../../tracy.zig").trace;
const std = @import("std");
-const Air = @import("../../Air.zig");
const Allocator = std.mem.Allocator;
const Archive = @import("Archive.zig");
const Atom = @import("Atom.zig");
src/link/C.zig
@@ -17,7 +17,6 @@ const link = @import("../link.zig");
const trace = @import("../tracy.zig").trace;
const Type = @import("../Type.zig");
const Value = @import("../Value.zig");
-const Air = @import("../Air.zig");
const AnyMir = @import("../codegen.zig").AnyMir;
pub const zig_h = "#include \"zig.h\"\n";
@@ -182,12 +181,7 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *AnyMir,
- /// This may be `undefined`; only pass it to `emitFunction`.
- /// This parameter will eventually be removed.
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
- _ = maybe_undef_air; // It would be a bug to use this argument.
-
const zcu = pt.zcu;
const gpa = zcu.gpa;
const func = zcu.funcInfo(func_index);
src/link/Coff.zig
@@ -1053,9 +1053,6 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- /// This may be `undefined`; only pass it to `emitFunction`.
- /// This parameter will eventually be removed.
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
if (build_options.skip_non_native and builtin.object_format != .coff) {
@panic("Attempted to compile for object format that was disabled by build configuration");
@@ -1084,7 +1081,6 @@ pub fn updateFunc(
mir,
&code_buffer,
.none,
- maybe_undef_air,
);
try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);
@@ -3123,7 +3119,6 @@ const link = @import("../link.zig");
const target_util = @import("../target.zig");
const trace = @import("../tracy.zig").trace;
-const Air = @import("../Air.zig");
const Compilation = @import("../Compilation.zig");
const Zcu = @import("../Zcu.zig");
const InternPool = @import("../InternPool.zig");
src/link/Dwarf.zig
@@ -1474,17 +1474,18 @@ pub const WipNav = struct {
try cfa.write(wip_nav);
}
- pub const LocalTag = enum { local_arg, local_var };
- pub fn genLocalDebugInfo(
+ pub const LocalVarTag = enum { arg, local_var };
+ pub fn genLocalVarDebugInfo(
wip_nav: *WipNav,
- tag: LocalTag,
+ tag: LocalVarTag,
name: []const u8,
ty: Type,
loc: Loc,
) UpdateError!void {
assert(wip_nav.func != .none);
try wip_nav.abbrevCode(switch (tag) {
- inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),
+ .arg => .arg,
+ .local_var => .local_var,
});
try wip_nav.strp(name);
try wip_nav.refType(ty);
@@ -1492,6 +1493,40 @@ pub const WipNav = struct {
wip_nav.any_children = true;
}
+ pub const LocalConstTag = enum { comptime_arg, local_const };
+ pub fn genLocalConstDebugInfo(
+ wip_nav: *WipNav,
+ src_loc: Zcu.LazySrcLoc,
+ tag: LocalConstTag,
+ name: []const u8,
+ val: Value,
+ ) UpdateError!void {
+ assert(wip_nav.func != .none);
+ const pt = wip_nav.pt;
+ const zcu = pt.zcu;
+ const ty = val.typeOf(zcu);
+ const has_runtime_bits = ty.hasRuntimeBits(zcu);
+ const has_comptime_state = ty.comptimeOnly(zcu) and try ty.onePossibleValue(pt) == null;
+ try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state) switch (tag) {
+ .comptime_arg => .comptime_arg_runtime_bits_comptime_state,
+ .local_const => .local_const_runtime_bits_comptime_state,
+ } else if (has_comptime_state) switch (tag) {
+ .comptime_arg => .comptime_arg_comptime_state,
+ .local_const => .local_const_comptime_state,
+ } else if (has_runtime_bits) switch (tag) {
+ .comptime_arg => .comptime_arg_runtime_bits,
+ .local_const => .local_const_runtime_bits,
+ } else switch (tag) {
+ .comptime_arg => .comptime_arg,
+ .local_const => .local_const,
+ });
+ try wip_nav.strp(name);
+ try wip_nav.refType(ty);
+ if (has_runtime_bits) try wip_nav.blockValue(src_loc, val);
+ if (has_comptime_state) try wip_nav.refValue(val);
+ wip_nav.any_children = true;
+ }
+
pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void {
assert(wip_nav.func != .none);
try wip_nav.abbrevCode(.is_var_args);
@@ -1825,7 +1860,8 @@ pub const WipNav = struct {
fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {
const zcu = wip_nav.pt.zcu;
const ip = &zcu.intern_pool;
- const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod.?);
+ const nav = ip.getNav(nav_index);
+ const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?);
const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);
if (gop.found_existing) return .{ unit, gop.value_ptr.* };
const entry = try wip_nav.dwarf.addCommonEntry(unit);
@@ -1842,10 +1878,16 @@ pub const WipNav = struct {
const zcu = wip_nav.pt.zcu;
const ip = &zcu.intern_pool;
const maybe_inst_index = ty.typeDeclInst(zcu);
- const unit = if (maybe_inst_index) |inst_index|
- try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?)
- else
- .main;
+ const unit = if (maybe_inst_index) |inst_index| switch (switch (ip.indexToKey(ty.toIntern())) {
+ else => unreachable,
+ .struct_type => ip.loadStructType(ty.toIntern()).name_nav,
+ .union_type => ip.loadUnionType(ty.toIntern()).name_nav,
+ .enum_type => ip.loadEnumType(ty.toIntern()).name_nav,
+ .opaque_type => ip.loadOpaqueType(ty.toIntern()).name_nav,
+ }) {
+ .none => try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?),
+ else => |name_nav| return wip_nav.getNavEntry(name_nav.unwrap().?),
+ } else .main;
const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());
if (gop.found_existing) return .{ unit, gop.value_ptr.* };
const entry = try wip_nav.dwarf.addCommonEntry(unit);
@@ -1864,10 +1906,8 @@ pub const WipNav = struct {
const ip = &zcu.intern_pool;
const ty = value.typeOf(zcu);
if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
- if (!value.isUndef(zcu)) {
- if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
- if (ip.isFunctionType(ty.toIntern())) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
- }
+ if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
+ if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
const unit: Unit.Index = .main;
if (gop.found_existing) return .{ unit, gop.value_ptr.* };
@@ -1916,7 +1956,10 @@ pub const WipNav = struct {
&wip_nav.debug_info,
.{ .debug_output = .{ .dwarf = wip_nav } },
);
- assert(old_len + bytes == wip_nav.debug_info.items.len);
+ if (old_len + bytes != wip_nav.debug_info.items.len) {
+ std.debug.print("{} [{}]: {} != {}\n", .{ ty.fmt(wip_nav.pt), ty.toIntern(), bytes, wip_nav.debug_info.items.len - old_len });
+ unreachable;
+ }
}
const AbbrevCodeForForm = struct {
@@ -2788,6 +2831,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
if (type_gop.found_existing) {
if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
+ assert(!nav_gop.found_existing);
nav_gop.value_ptr.* = type_gop.value_ptr.*;
} else {
if (nav_gop.found_existing)
@@ -2890,6 +2934,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
if (type_gop.found_existing) {
if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
+ assert(!nav_gop.found_existing);
nav_gop.value_ptr.* = type_gop.value_ptr.*;
} else {
if (nav_gop.found_existing)
@@ -2928,6 +2973,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
if (type_gop.found_existing) {
if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
+ assert(!nav_gop.found_existing);
nav_gop.value_ptr.* = type_gop.value_ptr.*;
} else {
if (nav_gop.found_existing)
@@ -2998,6 +3044,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
if (type_gop.found_existing) {
if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
+ assert(!nav_gop.found_existing);
nav_gop.value_ptr.* = type_gop.value_ptr.*;
} else {
if (nav_gop.found_existing)
@@ -3164,6 +3211,7 @@ fn updateLazyType(
) UpdateError!void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
+ assert(ip.typeOf(type_index) == .type_type);
const ty: Type = .fromInterned(type_index);
switch (type_index) {
.generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),
@@ -3200,6 +3248,10 @@ fn updateLazyType(
defer dwarf.gpa.free(name);
switch (ip.indexToKey(type_index)) {
+ .undef => {
+ try wip_nav.abbrevCode(.undefined_comptime_value);
+ try wip_nav.refType(.type);
+ },
.int_type => |int_type| {
try wip_nav.abbrevCode(.numeric_type);
try wip_nav.strp(name);
@@ -3633,7 +3685,6 @@ fn updateLazyType(
},
// values, not types
- .undef,
.simple_value,
.variable,
.@"extern",
@@ -3666,7 +3717,11 @@ fn updateLazyValue(
) UpdateError!void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
- log.debug("updateLazyValue({})", .{Value.fromInterned(value_index).fmtValue(pt)});
+ assert(ip.typeOf(value_index) != .type_type);
+ log.debug("updateLazyValue(@as({}, {}))", .{
+ Value.fromInterned(value_index).typeOf(zcu).fmt(pt),
+ Value.fromInterned(value_index).fmtValue(pt),
+ });
var wip_nav: WipNav = .{
.dwarf = dwarf,
.pt = pt,
@@ -3710,9 +3765,8 @@ fn updateLazyValue(
.inferred_error_set_type,
=> unreachable, // already handled
.undef => |ty| {
- try wip_nav.abbrevCode(.aggregate_comptime_value);
+ try wip_nav.abbrevCode(.undefined_comptime_value);
try wip_nav.refType(.fromInterned(ty));
- try uleb128(diw, @intFromEnum(AbbrevCode.null));
},
.simple_value => unreachable, // opv state
.variable, .@"extern" => unreachable, // not a value
@@ -4890,8 +4944,17 @@ const AbbrevCode = enum {
block,
empty_inlined_func,
inlined_func,
- local_arg,
+ arg,
+ comptime_arg,
+ comptime_arg_runtime_bits,
+ comptime_arg_comptime_state,
+ comptime_arg_runtime_bits_comptime_state,
local_var,
+ local_const,
+ local_const_runtime_bits,
+ local_const_comptime_state,
+ local_const_runtime_bits_comptime_state,
+ undefined_comptime_value,
data2_comptime_value,
data4_comptime_value,
data8_comptime_value,
@@ -5663,7 +5726,7 @@ const AbbrevCode = enum {
.{ .high_pc, .data4 },
},
},
- .local_arg = .{
+ .arg = .{
.tag = .formal_parameter,
.attrs = &.{
.{ .name, .strp },
@@ -5671,6 +5734,42 @@ const AbbrevCode = enum {
.{ .location, .exprloc },
},
},
+ .comptime_arg = .{
+ .tag = .formal_parameter,
+ .attrs = &.{
+ .{ .const_expr, .flag_present },
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ },
+ },
+ .comptime_arg_runtime_bits = .{
+ .tag = .formal_parameter,
+ .attrs = &.{
+ .{ .const_expr, .flag_present },
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .const_value, .block },
+ },
+ },
+ .comptime_arg_comptime_state = .{
+ .tag = .formal_parameter,
+ .attrs = &.{
+ .{ .const_expr, .flag_present },
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .ZIG_comptime_value, .ref_addr },
+ },
+ },
+ .comptime_arg_runtime_bits_comptime_state = .{
+ .tag = .formal_parameter,
+ .attrs = &.{
+ .{ .const_expr, .flag_present },
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .const_value, .block },
+ .{ .ZIG_comptime_value, .ref_addr },
+ },
+ },
.local_var = .{
.tag = .variable,
.attrs = &.{
@@ -5679,6 +5778,44 @@ const AbbrevCode = enum {
.{ .location, .exprloc },
},
},
+ .local_const = .{
+ .tag = .constant,
+ .attrs = &.{
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ },
+ },
+ .local_const_runtime_bits = .{
+ .tag = .constant,
+ .attrs = &.{
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .const_value, .block },
+ },
+ },
+ .local_const_comptime_state = .{
+ .tag = .constant,
+ .attrs = &.{
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .ZIG_comptime_value, .ref_addr },
+ },
+ },
+ .local_const_runtime_bits_comptime_state = .{
+ .tag = .constant,
+ .attrs = &.{
+ .{ .name, .strp },
+ .{ .type, .ref_addr },
+ .{ .const_value, .block },
+ .{ .ZIG_comptime_value, .ref_addr },
+ },
+ },
+ .undefined_comptime_value = .{
+ .tag = .ZIG_comptime_value,
+ .attrs = &.{
+ .{ .type, .ref_addr },
+ },
+ },
.data2_comptime_value = .{
.tag = .ZIG_comptime_value,
.attrs = &.{
src/link/Elf.zig
@@ -1683,12 +1683,11 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
if (build_options.skip_non_native and builtin.object_format != .elf) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
- return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir, maybe_undef_air);
+ return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir);
}
pub fn updateNav(
@@ -4516,7 +4515,6 @@ const trace = @import("../tracy.zig").trace;
const synthetic_sections = @import("Elf/synthetic_sections.zig");
const Merge = @import("Elf/Merge.zig");
-const Air = @import("../Air.zig");
const Archive = @import("Elf/Archive.zig");
const AtomList = @import("Elf/AtomList.zig");
const Compilation = @import("../Compilation.zig");
src/link/Goff.zig
@@ -17,7 +17,6 @@ const codegen = @import("../codegen.zig");
const link = @import("../link.zig");
const trace = @import("../tracy.zig").trace;
const build_options = @import("build_options");
-const Air = @import("../Air.zig");
base: link.File,
@@ -74,13 +73,11 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
_ = self;
_ = pt;
_ = func_index;
_ = mir;
- _ = maybe_undef_air;
unreachable; // we always use llvm
}
src/link/MachO.zig
@@ -3040,12 +3040,11 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
if (build_options.skip_non_native and builtin.object_format != .macho) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
- return self.getZigObject().?.updateFunc(self, pt, func_index, mir, maybe_undef_air);
+ return self.getZigObject().?.updateFunc(self, pt, func_index, mir);
}
pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
@@ -5431,7 +5430,6 @@ const target_util = @import("../target.zig");
const trace = @import("../tracy.zig").trace;
const synthetic = @import("MachO/synthetic.zig");
-const Air = @import("../Air.zig");
const Alignment = Atom.Alignment;
const Allocator = mem.Allocator;
const Archive = @import("MachO/Archive.zig");
src/link/Plan9.zig
@@ -387,9 +387,6 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- /// This may be `undefined`; only pass it to `emitFunction`.
- /// This parameter will eventually be removed.
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
if (build_options.skip_non_native and builtin.object_format != .plan9) {
@panic("Attempted to compile for object format that was disabled by build configuration");
@@ -422,7 +419,6 @@ pub fn updateFunc(
mir,
&code_buffer,
.{ .plan9 = &dbg_info_output },
- maybe_undef_air,
);
const code = try code_buffer.toOwnedSlice(gpa);
self.getAtomPtr(atom_idx).code = .{
src/link/Wasm.zig
@@ -29,7 +29,6 @@ const leb = std.leb;
const log = std.log.scoped(.link);
const mem = std.mem;
-const Air = @import("../Air.zig");
const Mir = @import("../arch/wasm/Mir.zig");
const CodeGen = @import("../arch/wasm/CodeGen.zig");
const abi = @import("../arch/wasm/abi.zig");
@@ -3182,14 +3181,12 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
any_mir: *const codegen.AnyMir,
- maybe_undef_air: *const Air,
) !void {
if (build_options.skip_non_native and builtin.object_format != .wasm) {
@panic("Attempted to compile for object format that was disabled by build configuration");
}
dev.check(.wasm_backend);
- _ = maybe_undef_air; // we (correctly) do not need this
// This linker implementation only works with codegen backend `.stage2_wasm`.
const mir = &any_mir.wasm;
src/link/Xcoff.zig
@@ -17,7 +17,6 @@ const codegen = @import("../codegen.zig");
const link = @import("../link.zig");
const trace = @import("../tracy.zig").trace;
const build_options = @import("build_options");
-const Air = @import("../Air.zig");
base: link.File,
@@ -74,13 +73,11 @@ pub fn updateFunc(
pt: Zcu.PerThread,
func_index: InternPool.Index,
mir: *const codegen.AnyMir,
- maybe_undef_air: *const Air,
) link.File.UpdateNavError!void {
_ = self;
_ = pt;
_ = func_index;
_ = mir;
- _ = maybe_undef_air;
unreachable; // we always use llvm
}
src/Zcu/PerThread.zig
@@ -2893,17 +2893,10 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
runtime_params_len;
var runtime_param_index: usize = 0;
- for (fn_info.param_body[0..src_params_len]) |inst| {
+ for (fn_info.param_body[0..src_params_len], 0..) |inst, zir_param_index| {
const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
if (gop.found_existing) continue; // provided above by comptime arg
- const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
- const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
- .param_anytype => param_inst_info.data.str_tok.start,
- .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
- else => unreachable,
- };
-
const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
runtime_param_index += 1;
@@ -2923,10 +2916,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
.tag = .arg,
.data = .{ .arg = .{
.ty = Air.internedToRef(param_ty),
- .name = if (inner_block.ownerModule().strip)
- .none
- else
- try sema.appendAirString(sema.code.nullTerminatedString(param_name)),
+ .zir_param_index = @intCast(zir_param_index),
} },
});
}
src/Air.zig
@@ -1153,9 +1153,7 @@ pub const Inst = struct {
ty: Type,
arg: struct {
ty: Ref,
- /// Index into `extra` of a null-terminated string representing the parameter name.
- /// This is `.none` if debug info is stripped.
- name: NullTerminatedString,
+ zir_param_index: u32,
},
ty_op: struct {
ty: Ref,
src/codegen.zig
@@ -180,10 +180,6 @@ pub fn emitFunction(
any_mir: *const AnyMir,
code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
- /// TODO: this parameter needs to be removed. We should not still hold AIR this late
- /// in the pipeline. Any information needed to call emit must be stored in MIR.
- /// This is `undefined` if the backend supports the `separate_thread` feature.
- air: *const Air,
) CodeGenError!void {
const zcu = pt.zcu;
const func = zcu.funcInfo(func_index);
@@ -199,7 +195,7 @@ pub fn emitFunction(
=> |backend| {
dev.check(devFeatureForBackend(backend));
const mir = &@field(any_mir, AnyMir.tag(backend));
- return mir.emit(lf, pt, src_loc, func_index, code, debug_output, air);
+ return mir.emit(lf, pt, src_loc, func_index, code, debug_output);
},
}
}
src/Compilation.zig
@@ -4589,10 +4589,8 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
comp.dispatchZcuLinkTask(tid, .{ .link_func = .{
.func = func.func,
.mir = shared_mir,
- .air = undefined,
} });
} else {
- const emit_needs_air = !zcu.backendSupportsFeature(.separate_thread);
{
const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
defer pt.deactivate();
@@ -4602,7 +4600,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
comp.dispatchZcuLinkTask(tid, .{ .link_func = .{
.func = func.func,
.mir = shared_mir,
- .air = if (emit_needs_air) &air else undefined,
} });
air.deinit(gpa);
}
src/link.zig
@@ -8,7 +8,6 @@ const log = std.log.scoped(.link);
const trace = @import("tracy.zig").trace;
const wasi_libc = @import("libs/wasi_libc.zig");
-const Air = @import("Air.zig");
const Allocator = std.mem.Allocator;
const Cache = std.Build.Cache;
const Path = std.Build.Cache.Path;
@@ -752,9 +751,6 @@ pub const File = struct {
/// that `mir.deinit` remains legal for the caller. For instance, the callee can
/// take ownership of an embedded slice and replace it with `&.{}` in `mir`.
mir: *codegen.AnyMir,
- /// This may be `undefined`; only pass it to `emitFunction`.
- /// This parameter will eventually be removed.
- maybe_undef_air: *const Air,
) UpdateNavError!void {
assert(base.comp.zcu.?.llvm_object == null);
switch (base.tag) {
@@ -762,7 +758,7 @@ pub const File = struct {
.spirv => unreachable, // see corresponding special case in `Zcu.PerThread.runCodegenInner`
inline else => |tag| {
dev.check(tag.devFeature());
- return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir, maybe_undef_air);
+ return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir);
},
}
}
@@ -1271,11 +1267,6 @@ pub const ZcuTask = union(enum) {
/// the codegen job to ensure that the linker receives functions in a deterministic order,
/// allowing reproducible builds.
mir: *SharedMir,
- /// This field exists only due to deficiencies in some codegen implementations; it should
- /// be removed when the corresponding parameter of `CodeGen.emitFunction` can be removed.
- /// This is `undefined` if `Zcu.Feature.separate_thread` is supported.
- /// If this is defined, its memory is owned externally; do not `deinit` this `air`.
- air: *const Air,
pub const SharedMir = struct {
/// This is initially `.pending`. When `value` is populated, the codegen thread will set
@@ -1458,7 +1449,7 @@ pub fn doZcuTask(comp: *Compilation, tid: usize, task: ZcuTask) void {
assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR
const mir = &func.mir.value;
if (comp.bin_file) |lf| {
- lf.updateFunc(pt, func.func, mir, func.air) catch |err| switch (err) {
+ lf.updateFunc(pt, func.func, mir) catch |err| switch (err) {
error.OutOfMemory => return diags.setAllocFailure(),
error.CodegenFail => return zcu.assertCodegenFailed(nav),
error.Overflow, error.RelocationNotByteAligned => {
src/Sema.zig
@@ -35088,24 +35088,24 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
var max_align: Alignment = .@"1";
for (0..union_type.field_types.len) |field_index| {
const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);
+ if (field_ty.isNoReturn(pt.zcu)) continue;
- if (try field_ty.comptimeOnlySema(pt) or field_ty.zigTypeTag(pt.zcu) == .noreturn) continue; // TODO: should this affect alignment?
-
- max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {
- error.AnalysisFail => {
- const msg = sema.err orelse return err;
- try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});
- return err;
- },
- else => return err,
- });
+ if (try field_ty.hasRuntimeBitsSema(pt)) {
+ max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {
+ error.AnalysisFail => {
+ const msg = sema.err orelse return err;
+ try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});
+ return err;
+ },
+ else => return err,
+ });
+ }
const explicit_align = union_type.fieldAlign(ip, field_index);
const field_align = if (explicit_align != .none)
explicit_align
else
try field_ty.abiAlignmentSema(pt);
-
max_align = max_align.max(field_align);
}
src/Type.zig
@@ -177,6 +177,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
switch (ip.indexToKey(ty.toIntern())) {
+ .undef => return writer.writeAll("@as(type, undefined)"),
.int_type => |int_type| {
const sign_char: u8 = switch (int_type.signedness) {
.signed => 'i',
@@ -398,7 +399,6 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
},
// values, not types
- .undef,
.simple_value,
.variable,
.@"extern",
@@ -3921,23 +3921,25 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
var payload_size: u64 = 0;
var payload_align: InternPool.Alignment = .@"1";
for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
- if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;
+ if (Type.fromInterned(field_ty).isNoReturn(zcu)) continue;
const explicit_align = loaded_union.fieldAlign(ip, field_index);
const field_align = if (explicit_align != .none)
explicit_align
else
Type.fromInterned(field_ty).abiAlignment(zcu);
- const field_size = Type.fromInterned(field_ty).abiSize(zcu);
- if (field_size > payload_size) {
- payload_size = field_size;
- biggest_field = @intCast(field_index);
- }
- if (field_align.compare(.gte, payload_align)) {
- payload_align = field_align;
- most_aligned_field = @intCast(field_index);
- most_aligned_field_size = field_size;
+ if (Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {
+ const field_size = Type.fromInterned(field_ty).abiSize(zcu);
+ if (field_size > payload_size) {
+ payload_size = field_size;
+ biggest_field = @intCast(field_index);
+ }
+ if (field_align.compare(.gte, payload_align)) {
+ most_aligned_field = @intCast(field_index);
+ most_aligned_field_size = field_size;
+ }
}
+ payload_align = payload_align.max(field_align);
}
const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();
if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {