x86_64: remove air references from mir

This commit is contained in:
Jacob Young 2025-06-07 04:51:26 -04:00 committed by mlugg
parent c4ec382fc8
commit c95b1bf2d3
No known key found for this signature in database
GPG Key ID: 3F5B7DCCBF4AF02E
34 changed files with 745 additions and 617 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)) {

View File

@ -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),
} },
});
}

View File

@ -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 });

View File

@ -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;

View File

@ -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 });

View File

@ -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;

View File

@ -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;
};

View File

@ -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;

View File

@ -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() },
),

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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,35 +434,69 @@ 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,
},
name.toSlice(emit.air),
switch (air_inst.tag) {
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_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,
},
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,
.pseudo_dbg_arg_val => .comptime_arg,
.pseudo_dbg_var_val => .local_const,
},
local_name,
.fromInterned(mir_inst.data.ip_index),
);
},
.plan9 => {},
.none => {},
},
.pseudo_dbg_var_args_none => switch (emit.debug_output) {
.dwarf => |dwarf| try dwarf.genVarArgsDebugInfo(),
.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");

View File

@ -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,
};
}

View File

@ -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();

View File

@ -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);
},
}
}

View File

@ -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,

View File

@ -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 => {

View File

@ -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);

View File

@ -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");

View File

@ -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 = &.{

View File

@ -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");

View File

@ -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");

View File

@ -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
}

View File

@ -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");

View File

@ -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");

View File

@ -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 = .{

View File

@ -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;

View File

@ -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
}