mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
x86_64: remove air references from mir
This commit is contained in:
parent
c4ec382fc8
commit
c95b1bf2d3
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
22
src/Sema.zig
22
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);
|
||||
}
|
||||
|
||||
|
||||
24
src/Type.zig
24
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)) {
|
||||
|
||||
@ -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),
|
||||
} },
|
||||
});
|
||||
}
|
||||
|
||||
@ -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 });
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 });
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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() },
|
||||
),
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
13
src/link.zig
13
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 => {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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 = &.{
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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 = .{
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user