authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-07 04:51:26-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-12 13:55:41+01:00
logc95b1bf2d3c3ae7595e15ad521952b77d5063801
treea1260ddf1454688e6732a22a6e3c4cc60bd81986
parentc4ec382fc806e0cb4484c1cb2edcc5fc40c3c9d8
signaturelock-open Commit is signed but in an unrecognized format.

x86_64: remove air references from mir


34 files changed, 744 insertions(+), 616 deletions(-)

lib/std/zig/Zir.zig+9
...@@ -4861,6 +4861,15 @@ pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const Zir.Inst.Index {...@@ -4861,6 +4861,15 @@ pub fn getParamBody(zir: Zir, fn_inst: Inst.Index) []const Zir.Inst.Index {
4861 }4861 }
4862}4862}
48634863
4864pub fn getParamName(zir: Zir, param_inst: Inst.Index) ?NullTerminatedString {
4865 const inst = zir.instructions.get(@intFromEnum(param_inst));
4866 return switch (inst.tag) {
4867 .param, .param_comptime => zir.extraData(Inst.Param, inst.data.pl_tok.payload_index).data.name,
4868 .param_anytype, .param_anytype_comptime => inst.data.str_tok.start,
4869 else => null,
4870 };
4871}
4872
4864pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {4873pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
4865 const tags = zir.instructions.items(.tag);4874 const tags = zir.instructions.items(.tag);
4866 const datas = zir.instructions.items(.data);4875 const datas = zir.instructions.items(.data);
src/Air.zig+1-3
...@@ -1153,9 +1153,7 @@ pub const Inst = struct {...@@ -1153,9 +1153,7 @@ pub const Inst = struct {
1153 ty: Type,1153 ty: Type,
1154 arg: struct {1154 arg: struct {
1155 ty: Ref,1155 ty: Ref,
1156 /// Index into `extra` of a null-terminated string representing the parameter name.1156 zir_param_index: u32,
1157 /// This is `.none` if debug info is stripped.
1158 name: NullTerminatedString,
1159 },1157 },
1160 ty_op: struct {1158 ty_op: struct {
1161 ty: Ref,1159 ty: Ref,
src/Air/print.zig+1-4
...@@ -363,10 +363,7 @@ const Writer = struct {...@@ -363,10 +363,7 @@ const Writer = struct {
363 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {363 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
364 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;364 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
365 try w.writeType(s, arg.ty.toType());365 try w.writeType(s, arg.ty.toType());
366 switch (arg.name) {366 try s.print(", {d}", .{arg.zir_param_index});
367 .none => {},
368 _ => try s.print(", \"{}\"", .{std.zig.fmtEscapes(arg.name.toSlice(w.air))}),
369 }
370 }367 }
371368
372 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {369 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/Compilation.zig-3
...@@ -4589,10 +4589,8 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {...@@ -4589,10 +4589,8 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
4589 comp.dispatchZcuLinkTask(tid, .{ .link_func = .{4589 comp.dispatchZcuLinkTask(tid, .{ .link_func = .{
4590 .func = func.func,4590 .func = func.func,
4591 .mir = shared_mir,4591 .mir = shared_mir,
4592 .air = undefined,
4593 } });4592 } });
4594 } else {4593 } else {
4595 const emit_needs_air = !zcu.backendSupportsFeature(.separate_thread);
4596 {4594 {
4597 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));4595 const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
4598 defer pt.deactivate();4596 defer pt.deactivate();
...@@ -4602,7 +4600,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {...@@ -4602,7 +4600,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void {
4602 comp.dispatchZcuLinkTask(tid, .{ .link_func = .{4600 comp.dispatchZcuLinkTask(tid, .{ .link_func = .{
4603 .func = func.func,4601 .func = func.func,
4604 .mir = shared_mir,4602 .mir = shared_mir,
4605 .air = if (emit_needs_air) &air else undefined,
4606 } });4603 } });
4607 air.deinit(gpa);4604 air.deinit(gpa);
4608 }4605 }
src/Sema.zig+11-11
...@@ -35088,24 +35088,24 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35088,24 +35088,24 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35088 var max_align: Alignment = .@"1";35088 var max_align: Alignment = .@"1";
35089 for (0..union_type.field_types.len) |field_index| {35089 for (0..union_type.field_types.len) |field_index| {
35090 const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);35090 const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);
35091 if (field_ty.isNoReturn(pt.zcu)) continue;
3509135092
35092 if (try field_ty.comptimeOnlySema(pt) or field_ty.zigTypeTag(pt.zcu) == .noreturn) continue; // TODO: should this affect alignment?35093 if (try field_ty.hasRuntimeBitsSema(pt)) {
3509335094 max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {
35094 max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {35095 error.AnalysisFail => {
35095 error.AnalysisFail => {35096 const msg = sema.err orelse return err;
35096 const msg = sema.err orelse return err;35097 try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});
35097 try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});35098 return err;
35098 return err;35099 },
35099 },35100 else => return err,
35100 else => return err,35101 });
35101 });35102 }
3510235103
35103 const explicit_align = union_type.fieldAlign(ip, field_index);35104 const explicit_align = union_type.fieldAlign(ip, field_index);
35104 const field_align = if (explicit_align != .none)35105 const field_align = if (explicit_align != .none)
35105 explicit_align35106 explicit_align
35106 else35107 else
35107 try field_ty.abiAlignmentSema(pt);35108 try field_ty.abiAlignmentSema(pt);
35108
35109 max_align = max_align.max(field_align);35109 max_align = max_align.max(field_align);
35110 }35110 }
3511135111
src/Type.zig+13-11
...@@ -177,6 +177,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -177,6 +177,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
177 const zcu = pt.zcu;177 const zcu = pt.zcu;
178 const ip = &zcu.intern_pool;178 const ip = &zcu.intern_pool;
179 switch (ip.indexToKey(ty.toIntern())) {179 switch (ip.indexToKey(ty.toIntern())) {
180 .undef => return writer.writeAll("@as(type, undefined)"),
180 .int_type => |int_type| {181 .int_type => |int_type| {
181 const sign_char: u8 = switch (int_type.signedness) {182 const sign_char: u8 = switch (int_type.signedness) {
182 .signed => 'i',183 .signed => 'i',
...@@ -398,7 +399,6 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -398,7 +399,6 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
398 },399 },
399400
400 // values, not types401 // values, not types
401 .undef,
402 .simple_value,402 .simple_value,
403 .variable,403 .variable,
404 .@"extern",404 .@"extern",
...@@ -3921,23 +3921,25 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -3921,23 +3921,25 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
3921 var payload_size: u64 = 0;3921 var payload_size: u64 = 0;
3922 var payload_align: InternPool.Alignment = .@"1";3922 var payload_align: InternPool.Alignment = .@"1";
3923 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {3923 for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| {
3924 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;3924 if (Type.fromInterned(field_ty).isNoReturn(zcu)) continue;
39253925
3926 const explicit_align = loaded_union.fieldAlign(ip, field_index);3926 const explicit_align = loaded_union.fieldAlign(ip, field_index);
3927 const field_align = if (explicit_align != .none)3927 const field_align = if (explicit_align != .none)
3928 explicit_align3928 explicit_align
3929 else3929 else
3930 Type.fromInterned(field_ty).abiAlignment(zcu);3930 Type.fromInterned(field_ty).abiAlignment(zcu);
3931 const field_size = Type.fromInterned(field_ty).abiSize(zcu);3931 if (Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {
3932 if (field_size > payload_size) {3932 const field_size = Type.fromInterned(field_ty).abiSize(zcu);
3933 payload_size = field_size;3933 if (field_size > payload_size) {
3934 biggest_field = @intCast(field_index);3934 payload_size = field_size;
3935 }3935 biggest_field = @intCast(field_index);
3936 if (field_align.compare(.gte, payload_align)) {3936 }
3937 payload_align = field_align;3937 if (field_align.compare(.gte, payload_align)) {
3938 most_aligned_field = @intCast(field_index);3938 most_aligned_field = @intCast(field_index);
3939 most_aligned_field_size = field_size;3939 most_aligned_field_size = field_size;
3940 }
3940 }3941 }
3942 payload_align = payload_align.max(field_align);
3941 }3943 }
3942 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();3944 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();
3943 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {3945 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {
src/Zcu/PerThread.zig+2-12
...@@ -2893,17 +2893,10 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2893,17 +2893,10 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2893 runtime_params_len;2893 runtime_params_len;
28942894
2895 var runtime_param_index: usize = 0;2895 var runtime_param_index: usize = 0;
2896 for (fn_info.param_body[0..src_params_len]) |inst| {2896 for (fn_info.param_body[0..src_params_len], 0..) |inst, zir_param_index| {
2897 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);2897 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
2898 if (gop.found_existing) continue; // provided above by comptime arg2898 if (gop.found_existing) continue; // provided above by comptime arg
28992899
2900 const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
2901 const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
2902 .param_anytype => param_inst_info.data.str_tok.start,
2903 .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
2904 else => unreachable,
2905 };
2906
2907 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];2900 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
2908 runtime_param_index += 1;2901 runtime_param_index += 1;
29092902
...@@ -2923,10 +2916,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE...@@ -2923,10 +2916,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
2923 .tag = .arg,2916 .tag = .arg,
2924 .data = .{ .arg = .{2917 .data = .{ .arg = .{
2925 .ty = Air.internedToRef(param_ty),2918 .ty = Air.internedToRef(param_ty),
2926 .name = if (inner_block.ownerModule().strip)2919 .zir_param_index = @intCast(zir_param_index),
2927 .none
2928 else
2929 try sema.appendAirString(sema.code.nullTerminatedString(param_name)),
2930 } },2920 } },
2931 });2921 });
2932 }2922 }
src/arch/aarch64/CodeGen.zig+16-9
...@@ -4208,15 +4208,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {...@@ -4208,15 +4208,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
4208 while (self.args[arg_index] == .none) arg_index += 1;4208 while (self.args[arg_index] == .none) arg_index += 1;
4209 self.arg_index = arg_index + 1;4209 self.arg_index = arg_index + 1;
42104210
4211 const ty = self.typeOfIndex(inst);4211 const zcu = self.pt.zcu;
4212 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4212 const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
4213 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;4213 const file = zcu.fileByIndex(func_zir.file);
4214 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{4214 if (!file.mod.?.strip) {
4215 .tag = tag,4215 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4216 .ty = ty,4216 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4217 .name = name.toSlice(self.air),4217 const ty = self.typeOfIndex(inst);
4218 .mcv = self.args[arg_index],4218 const zir = &file.zir.?;
4219 });4219 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
4220 try self.dbg_info_relocs.append(self.gpa, .{
4221 .tag = tag,
4222 .ty = ty,
4223 .name = name,
4224 .mcv = self.args[arg_index],
4225 });
4226 }
42204227
4221 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4228 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4222 return self.finishAir(inst, result, .{ .none, .none, .none });4229 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/aarch64/Mir.zig-2
...@@ -514,9 +514,7 @@ pub fn emit(...@@ -514,9 +514,7 @@ pub fn emit(
514 func_index: InternPool.Index,514 func_index: InternPool.Index,
515 code: *std.ArrayListUnmanaged(u8),515 code: *std.ArrayListUnmanaged(u8),
516 debug_output: link.File.DebugInfoOutput,516 debug_output: link.File.DebugInfoOutput,
517 air: *const @import("../../Air.zig"),
518) codegen.CodeGenError!void {517) codegen.CodeGenError!void {
519 _ = air; // using this would be a bug
520 const zcu = pt.zcu;518 const zcu = pt.zcu;
521 const func = zcu.funcInfo(func_index);519 const func = zcu.funcInfo(func_index);
522 const nav = func.owner_nav;520 const nav = func.owner_nav;
src/arch/arm/CodeGen.zig+16-10
...@@ -4191,16 +4191,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4191,16 +4191,22 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4191 while (self.args[arg_index] == .none) arg_index += 1;4191 while (self.args[arg_index] == .none) arg_index += 1;
4192 self.arg_index = arg_index + 1;4192 self.arg_index = arg_index + 1;
41934193
4194 const ty = self.typeOfIndex(inst);4194 const zcu = self.pt.zcu;
4195 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4195 const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
41964196 const file = zcu.fileByIndex(func_zir.file);
4197 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;4197 if (!file.mod.?.strip) {
4198 if (name != .none) try self.dbg_info_relocs.append(self.gpa, .{4198 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4199 .tag = tag,4199 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4200 .ty = ty,4200 const ty = self.typeOfIndex(inst);
4201 .name = name.toSlice(self.air),4201 const zir = &file.zir.?;
4202 .mcv = self.args[arg_index],4202 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
4203 });4203 try self.dbg_info_relocs.append(self.gpa, .{
4204 .tag = tag,
4205 .ty = ty,
4206 .name = name,
4207 .mcv = self.args[arg_index],
4208 });
4209 }
42044210
4205 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4211 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4206 return self.finishAir(inst, result, .{ .none, .none, .none });4212 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/arm/Mir.zig-2
...@@ -294,9 +294,7 @@ pub fn emit(...@@ -294,9 +294,7 @@ pub fn emit(
294 func_index: InternPool.Index,294 func_index: InternPool.Index,
295 code: *std.ArrayListUnmanaged(u8),295 code: *std.ArrayListUnmanaged(u8),
296 debug_output: link.File.DebugInfoOutput,296 debug_output: link.File.DebugInfoOutput,
297 air: *const @import("../../Air.zig"),
298) codegen.CodeGenError!void {297) codegen.CodeGenError!void {
299 _ = air; // using this would be a bug
300 const zcu = pt.zcu;298 const zcu = pt.zcu;
301 const func = zcu.funcInfo(func_index);299 const func = zcu.funcInfo(func_index);
302 const nav = func.owner_nav;300 const nav = func.owner_nav;
src/arch/riscv64/CodeGen.zig+16-6
...@@ -70,6 +70,7 @@ mod: *Package.Module,...@@ -70,6 +70,7 @@ mod: *Package.Module,
70target: *const std.Target,70target: *const std.Target,
71args: []MCValue,71args: []MCValue,
72ret_mcv: InstTracking,72ret_mcv: InstTracking,
73func_index: InternPool.Index,
73fn_type: Type,74fn_type: Type,
74arg_index: usize,75arg_index: usize,
75src_loc: Zcu.LazySrcLoc,76src_loc: Zcu.LazySrcLoc,
...@@ -774,6 +775,7 @@ pub fn generate(...@@ -774,6 +775,7 @@ pub fn generate(
774 .owner = .{ .nav_index = func.owner_nav },775 .owner = .{ .nav_index = func.owner_nav },
775 .args = undefined, // populated after `resolveCallingConventionValues`776 .args = undefined, // populated after `resolveCallingConventionValues`
776 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`777 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
778 .func_index = func_index,
777 .fn_type = fn_type,779 .fn_type = fn_type,
778 .arg_index = 0,780 .arg_index = 0,
779 .branch_stack = &branch_stack,781 .branch_stack = &branch_stack,
...@@ -877,6 +879,7 @@ pub fn generateLazy(...@@ -877,6 +879,7 @@ pub fn generateLazy(
877 .owner = .{ .lazy_sym = lazy_sym },879 .owner = .{ .lazy_sym = lazy_sym },
878 .args = undefined, // populated after `resolveCallingConventionValues`880 .args = undefined, // populated after `resolveCallingConventionValues`
879 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`881 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
882 .func_index = undefined,
880 .fn_type = undefined,883 .fn_type = undefined,
881 .arg_index = 0,884 .arg_index = 0,
882 .branch_stack = undefined,885 .branch_stack = undefined,
...@@ -4724,10 +4727,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4724,10 +4727,8 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
4724 return func.fail("TODO implement codegen airFieldParentPtr", .{});4727 return func.fail("TODO implement codegen airFieldParentPtr", .{});
4725}4728}
47264729
4727fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerError!void {4730fn genArgDbgInfo(func: *const Func, name: []const u8, ty: Type, mcv: MCValue) InnerError!void {
4728 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4731 assert(!func.mod.strip);
4729 const ty = arg.ty.toType();
4730 if (arg.name == .none) return;
47314732
4732 // TODO: Add a pseudo-instruction or something to defer this work until Emit.4733 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
4733 // We aren't allowed to interact with linker state here.4734 // 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...@@ -4736,7 +4737,7 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr
4736 .dwarf => |dw| switch (mcv) {4737 .dwarf => |dw| switch (mcv) {
4737 .register => |reg| dw.genLocalDebugInfo(4738 .register => |reg| dw.genLocalDebugInfo(
4738 .local_arg,4739 .local_arg,
4739 arg.name.toSlice(func.air),4740 name,
4740 ty,4741 ty,
4741 .{ .reg = reg.dwarfNum() },4742 .{ .reg = reg.dwarfNum() },
4742 ) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),4743 ) 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...@@ -4749,6 +4750,8 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr
4749}4750}
47504751
4751fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {4752fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
4753 const zcu = func.pt.zcu;
4754
4752 var arg_index = func.arg_index;4755 var arg_index = func.arg_index;
47534756
4754 // we skip over args that have no bits4757 // we skip over args that have no bits
...@@ -4765,7 +4768,14 @@ fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {...@@ -4765,7 +4768,14 @@ fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
47654768
4766 try func.genCopy(arg_ty, dst_mcv, src_mcv);4769 try func.genCopy(arg_ty, dst_mcv, src_mcv);
47674770
4768 try func.genArgDbgInfo(inst, src_mcv);4771 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4772 // can delete `func.func_index` if this logic is moved to emit
4773 const func_zir = zcu.funcInfo(func.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
4774 const file = zcu.fileByIndex(func_zir.file);
4775 const zir = &file.zir.?;
4776 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
4777
4778 try func.genArgDbgInfo(name, arg_ty, src_mcv);
4769 break :result dst_mcv;4779 break :result dst_mcv;
4770 };4780 };
47714781
src/arch/riscv64/Mir.zig-2
...@@ -117,9 +117,7 @@ pub fn emit(...@@ -117,9 +117,7 @@ pub fn emit(
117 func_index: InternPool.Index,117 func_index: InternPool.Index,
118 code: *std.ArrayListUnmanaged(u8),118 code: *std.ArrayListUnmanaged(u8),
119 debug_output: link.File.DebugInfoOutput,119 debug_output: link.File.DebugInfoOutput,
120 air: *const @import("../../Air.zig"),
121) codegen.CodeGenError!void {120) codegen.CodeGenError!void {
122 _ = air; // using this would be a bug
123 const zcu = pt.zcu;121 const zcu = pt.zcu;
124 const comp = zcu.comp;122 const comp = zcu.comp;
125 const gpa = comp.gpa;123 const gpa = comp.gpa;
src/arch/sparc64/CodeGen.zig+16-14
...@@ -995,23 +995,29 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {...@@ -995,23 +995,29 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
995 self.arg_index += 1;995 self.arg_index += 1;
996996
997 const ty = self.typeOfIndex(inst);997 const ty = self.typeOfIndex(inst);
998998 const mcv: MCValue = blk: {
999 const arg = self.args[arg_index];999 switch (self.args[arg_index]) {
1000 const mcv = blk: {
1001 switch (arg) {
1002 .stack_offset => |off| {1000 .stack_offset => |off| {
1003 const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse {1001 const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse {
1004 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});1002 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
1005 };1003 };
1006 const offset = off + abi_size;1004 const offset = off + abi_size;
1007 break :blk MCValue{ .stack_offset = offset };1005 break :blk .{ .stack_offset = offset };
1008 },1006 },
1009 else => break :blk arg,1007 else => |mcv| break :blk mcv,
1010 }1008 }
1011 };1009 };
10121010
1013 self.genArgDbgInfo(inst, mcv) catch |err|1011 const func_zir = zcu.funcInfo(self.func_index).zir_body_inst.resolveFull(&zcu.intern_pool).?;
1014 return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});1012 const file = zcu.fileByIndex(func_zir.file);
1013 if (!file.mod.?.strip) {
1014 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
1015 const zir = &file.zir.?;
1016 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
1017
1018 self.genArgDbgInfo(name, ty, mcv) catch |err|
1019 return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});
1020 }
10151021
1016 if (self.liveness.isUnused(inst))1022 if (self.liveness.isUnused(inst))
1017 return self.finishAirBookkeeping();1023 return self.finishAirBookkeeping();
...@@ -3539,11 +3545,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Air....@@ -3539,11 +3545,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Air.
3539 self.finishAirBookkeeping();3545 self.finishAirBookkeeping();
3540}3546}
35413547
3542fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {3548fn genArgDbgInfo(self: Self, name: []const u8, ty: Type, mcv: MCValue) !void {
3543 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
3544 const ty = arg.ty.toType();
3545 if (arg.name == .none) return;
3546
3547 // TODO: Add a pseudo-instruction or something to defer this work until Emit.3549 // TODO: Add a pseudo-instruction or something to defer this work until Emit.
3548 // We aren't allowed to interact with linker state here.3550 // We aren't allowed to interact with linker state here.
3549 if (true) return;3551 if (true) return;
...@@ -3551,7 +3553,7 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -3551,7 +3553,7 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3551 .dwarf => |dw| switch (mcv) {3553 .dwarf => |dw| switch (mcv) {
3552 .register => |reg| try dw.genLocalDebugInfo(3554 .register => |reg| try dw.genLocalDebugInfo(
3553 .local_arg,3555 .local_arg,
3554 arg.name.toSlice(self.air),3556 name,
3555 ty,3557 ty,
3556 .{ .reg = reg.dwarfNum() },3558 .{ .reg = reg.dwarfNum() },
3557 ),3559 ),
src/arch/sparc64/Mir.zig-2
...@@ -382,9 +382,7 @@ pub fn emit(...@@ -382,9 +382,7 @@ pub fn emit(
382 func_index: InternPool.Index,382 func_index: InternPool.Index,
383 code: *std.ArrayListUnmanaged(u8),383 code: *std.ArrayListUnmanaged(u8),
384 debug_output: link.File.DebugInfoOutput,384 debug_output: link.File.DebugInfoOutput,
385 air: *const @import("../../Air.zig"),
386) codegen.CodeGenError!void {385) codegen.CodeGenError!void {
387 _ = air; // using this would be a bug
388 const zcu = pt.zcu;386 const zcu = pt.zcu;
389 const func = zcu.funcInfo(func_index);387 const func = zcu.funcInfo(func_index);
390 const nav = func.owner_nav;388 const nav = func.owner_nav;
src/arch/wasm/CodeGen.zig+2-2
...@@ -1877,7 +1877,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1877,7 +1877,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1877 .dbg_inline_block => cg.airDbgInlineBlock(inst),1877 .dbg_inline_block => cg.airDbgInlineBlock(inst),
1878 .dbg_var_ptr => cg.airDbgVar(inst, .local_var, true),1878 .dbg_var_ptr => cg.airDbgVar(inst, .local_var, true),
1879 .dbg_var_val => cg.airDbgVar(inst, .local_var, false),1879 .dbg_var_val => cg.airDbgVar(inst, .local_var, false),
1880 .dbg_arg_inline => cg.airDbgVar(inst, .local_arg, false),1880 .dbg_arg_inline => cg.airDbgVar(inst, .arg, false),
18811881
1882 .call => cg.airCall(inst, .auto),1882 .call => cg.airCall(inst, .auto),
1883 .call_always_tail => cg.airCall(inst, .always_tail),1883 .call_always_tail => cg.airCall(inst, .always_tail),
...@@ -6427,7 +6427,7 @@ fn airDbgInlineBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6427,7 +6427,7 @@ fn airDbgInlineBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6427fn airDbgVar(6427fn airDbgVar(
6428 cg: *CodeGen,6428 cg: *CodeGen,
6429 inst: Air.Inst.Index,6429 inst: Air.Inst.Index,
6430 local_tag: link.File.Dwarf.WipNav.LocalTag,6430 local_tag: link.File.Dwarf.WipNav.LocalVarTag,
6431 is_ptr: bool,6431 is_ptr: bool,
6432) InnerError!void {6432) InnerError!void {
6433 _ = is_ptr;6433 _ = is_ptr;
src/arch/x86_64/CodeGen.zig+270-294
...@@ -129,7 +129,6 @@ target: *const std.Target,...@@ -129,7 +129,6 @@ target: *const std.Target,
129owner: Owner,129owner: Owner,
130inline_func: InternPool.Index,130inline_func: InternPool.Index,
131mod: *Module,131mod: *Module,
132arg_index: u32,
133args: []MCValue,132args: []MCValue,
134va_info: union {133va_info: union {
135 sysv: struct {134 sysv: struct {
...@@ -151,6 +150,8 @@ eflags_inst: ?Air.Inst.Index = null,...@@ -151,6 +150,8 @@ eflags_inst: ?Air.Inst.Index = null,
151mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,150mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,
152/// MIR extra data151/// MIR extra data
153mir_extra: std.ArrayListUnmanaged(u32) = .empty,152mir_extra: std.ArrayListUnmanaged(u32) = .empty,
153mir_local_name_bytes: std.ArrayListUnmanaged(u8) = .empty,
154mir_local_types: std.ArrayListUnmanaged(InternPool.Index) = .empty,
154mir_table: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,155mir_table: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,
155156
156/// The value is an offset into the `Function` `code` from the beginning.157/// The value is an offset into the `Function` `code` from the beginning.
...@@ -978,8 +979,10 @@ pub fn generate(...@@ -978,8 +979,10 @@ pub fn generate(
978 const gpa = zcu.gpa;979 const gpa = zcu.gpa;
979 const ip = &zcu.intern_pool;980 const ip = &zcu.intern_pool;
980 const func = zcu.funcInfo(func_index);981 const func = zcu.funcInfo(func_index);
982 const func_zir = func.zir_body_inst.resolveFull(ip).?;
983 const file = zcu.fileByIndex(func_zir.file);
981 const fn_type: Type = .fromInterned(func.ty);984 const fn_type: Type = .fromInterned(func.ty);
982 const mod = zcu.navFileScope(func.owner_nav).mod.?;985 const mod = file.mod.?;
983986
984 var function: CodeGen = .{987 var function: CodeGen = .{
985 .gpa = gpa,988 .gpa = gpa,
...@@ -991,7 +994,6 @@ pub fn generate(...@@ -991,7 +994,6 @@ pub fn generate(
991 .bin_file = bin_file,994 .bin_file = bin_file,
992 .owner = .{ .nav_index = func.owner_nav },995 .owner = .{ .nav_index = func.owner_nav },
993 .inline_func = func_index,996 .inline_func = func_index,
994 .arg_index = undefined,
995 .args = undefined, // populated after `resolveCallingConventionValues`997 .args = undefined, // populated after `resolveCallingConventionValues`
996 .va_info = undefined, // populated after `resolveCallingConventionValues`998 .va_info = undefined, // populated after `resolveCallingConventionValues`
997 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`999 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
...@@ -1011,6 +1013,8 @@ pub fn generate(...@@ -1011,6 +1013,8 @@ pub fn generate(
1011 function.inst_tracking.deinit(gpa);1013 function.inst_tracking.deinit(gpa);
1012 function.epilogue_relocs.deinit(gpa);1014 function.epilogue_relocs.deinit(gpa);
1013 function.mir_instructions.deinit(gpa);1015 function.mir_instructions.deinit(gpa);
1016 function.mir_local_name_bytes.deinit(gpa);
1017 function.mir_local_types.deinit(gpa);
1014 function.mir_extra.deinit(gpa);1018 function.mir_extra.deinit(gpa);
1015 function.mir_table.deinit(gpa);1019 function.mir_table.deinit(gpa);
1016 }1020 }
...@@ -1078,7 +1082,7 @@ pub fn generate(...@@ -1078,7 +1082,7 @@ pub fn generate(
1078 );1082 );
1079 }1083 }
10801084
1081 function.gen() catch |err| switch (err) {1085 function.gen(&file.zir.?, func_zir.inst, func.comptime_args, call_info.air_arg_count) catch |err| switch (err) {
1082 error.CodegenFail => return error.CodegenFail,1086 error.CodegenFail => return error.CodegenFail,
1083 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),1087 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
1084 else => |e| return e,1088 else => |e| return e,
...@@ -1097,17 +1101,32 @@ pub fn generate(...@@ -1097,17 +1101,32 @@ pub fn generate(
1097 var mir: Mir = .{1101 var mir: Mir = .{
1098 .instructions = .empty,1102 .instructions = .empty,
1099 .extra = &.{},1103 .extra = &.{},
1104 .local_name_bytes = &.{},
1105 .local_types = &.{},
1100 .table = &.{},1106 .table = &.{},
1101 .frame_locs = .empty,1107 .frame_locs = .empty,
1102 };1108 };
1103 errdefer mir.deinit(gpa);1109 errdefer mir.deinit(gpa);
1104 mir.instructions = function.mir_instructions.toOwnedSlice();1110 mir.instructions = function.mir_instructions.toOwnedSlice();
1105 mir.extra = try function.mir_extra.toOwnedSlice(gpa);1111 mir.extra = try function.mir_extra.toOwnedSlice(gpa);
1112 mir.local_name_bytes = try function.mir_local_name_bytes.toOwnedSlice(gpa);
1113 mir.local_types = try function.mir_local_types.toOwnedSlice(gpa);
1106 mir.table = try function.mir_table.toOwnedSlice(gpa);1114 mir.table = try function.mir_table.toOwnedSlice(gpa);
1107 mir.frame_locs = function.frame_locs.toOwnedSlice();1115 mir.frame_locs = function.frame_locs.toOwnedSlice();
1108 return mir;1116 return mir;
1109}1117}
11101118
1119pub fn toTmpMir(cg: *CodeGen) Mir {
1120 return .{
1121 .instructions = cg.mir_instructions.slice(),
1122 .extra = cg.mir_extra.items,
1123 .local_name_bytes = cg.mir_local_name_bytes.items,
1124 .local_types = cg.mir_local_types.items,
1125 .table = cg.mir_table.items,
1126 .frame_locs = cg.frame_locs.slice(),
1127 };
1128}
1129
1111pub fn generateLazy(1130pub fn generateLazy(
1112 bin_file: *link.File,1131 bin_file: *link.File,
1113 pt: Zcu.PerThread,1132 pt: Zcu.PerThread,
...@@ -1130,7 +1149,6 @@ pub fn generateLazy(...@@ -1130,7 +1149,6 @@ pub fn generateLazy(
1130 .bin_file = bin_file,1149 .bin_file = bin_file,
1131 .owner = .{ .lazy_sym = lazy_sym },1150 .owner = .{ .lazy_sym = lazy_sym },
1132 .inline_func = undefined,1151 .inline_func = undefined,
1133 .arg_index = undefined,
1134 .args = undefined,1152 .args = undefined,
1135 .va_info = undefined,1153 .va_info = undefined,
1136 .ret_mcv = undefined,1154 .ret_mcv = undefined,
...@@ -1141,6 +1159,8 @@ pub fn generateLazy(...@@ -1141,6 +1159,8 @@ pub fn generateLazy(
1141 defer {1159 defer {
1142 function.inst_tracking.deinit(gpa);1160 function.inst_tracking.deinit(gpa);
1143 function.mir_instructions.deinit(gpa);1161 function.mir_instructions.deinit(gpa);
1162 function.mir_local_name_bytes.deinit(gpa);
1163 function.mir_local_types.deinit(gpa);
1144 function.mir_extra.deinit(gpa);1164 function.mir_extra.deinit(gpa);
1145 function.mir_table.deinit(gpa);1165 function.mir_table.deinit(gpa);
1146 }1166 }
...@@ -1156,21 +1176,12 @@ pub fn generateLazy(...@@ -1156,21 +1176,12 @@ pub fn generateLazy(
1156 else => |e| return e,1176 else => |e| return e,
1157 };1177 };
11581178
1159 var mir: Mir = .{
1160 .instructions = function.mir_instructions.toOwnedSlice(),
1161 .extra = try function.mir_extra.toOwnedSlice(gpa),
1162 .table = try function.mir_table.toOwnedSlice(gpa),
1163 .frame_locs = function.frame_locs.toOwnedSlice(),
1164 };
1165 defer mir.deinit(gpa);
1166
1167 var emit: Emit = .{1179 var emit: Emit = .{
1168 .air = function.air,
1169 .lower = .{1180 .lower = .{
1170 .bin_file = bin_file,1181 .bin_file = bin_file,
1171 .target = function.target,1182 .target = function.target,
1172 .allocator = gpa,1183 .allocator = gpa,
1173 .mir = mir,1184 .mir = function.toTmpMir(),
1174 .cc = .auto,1185 .cc = .auto,
1175 .src_loc = src_loc,1186 .src_loc = src_loc,
1176 .output_mode = comp.config.output_mode,1187 .output_mode = comp.config.output_mode,
...@@ -1240,22 +1251,16 @@ fn formatWipMir(...@@ -1240,22 +1251,16 @@ fn formatWipMir(
1240 writer: anytype,1251 writer: anytype,
1241) @TypeOf(writer).Error!void {1252) @TypeOf(writer).Error!void {
1242 const comp = data.self.bin_file.comp;1253 const comp = data.self.bin_file.comp;
1243 const mod = comp.root_mod;
1244 var lower: Lower = .{1254 var lower: Lower = .{
1245 .bin_file = data.self.bin_file,1255 .bin_file = data.self.bin_file,
1246 .target = data.self.target,1256 .target = data.self.target,
1247 .allocator = data.self.gpa,1257 .allocator = data.self.gpa,
1248 .mir = .{1258 .mir = data.self.toTmpMir(),
1249 .instructions = data.self.mir_instructions.slice(),
1250 .extra = data.self.mir_extra.items,
1251 .table = data.self.mir_table.items,
1252 .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(),
1253 },
1254 .cc = .auto,1259 .cc = .auto,
1255 .src_loc = data.self.src_loc,1260 .src_loc = data.self.src_loc,
1256 .output_mode = comp.config.output_mode,1261 .output_mode = comp.config.output_mode,
1257 .link_mode = comp.config.link_mode,1262 .link_mode = comp.config.link_mode,
1258 .pic = mod.pic,1263 .pic = data.self.mod.pic,
1259 };1264 };
1260 var first = true;1265 var first = true;
1261 for ((lower.lowerMir(data.inst) catch |err| switch (err) {1266 for ((lower.lowerMir(data.inst) catch |err| switch (err) {
...@@ -1291,7 +1296,9 @@ fn formatWipMir(...@@ -1291,7 +1296,9 @@ fn formatWipMir(
1291 .pseudo_dbg_epilogue_begin_none,1296 .pseudo_dbg_epilogue_begin_none,
1292 .pseudo_dbg_enter_block_none,1297 .pseudo_dbg_enter_block_none,
1293 .pseudo_dbg_leave_block_none,1298 .pseudo_dbg_leave_block_none,
1299 .pseudo_dbg_arg_none,
1294 .pseudo_dbg_var_args_none,1300 .pseudo_dbg_var_args_none,
1301 .pseudo_dbg_var_none,
1295 .pseudo_dead_none,1302 .pseudo_dead_none,
1296 => {},1303 => {},
1297 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(1304 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(
...@@ -1299,57 +1306,47 @@ fn formatWipMir(...@@ -1299,57 +1306,47 @@ fn formatWipMir(
1299 mir_inst.data.line_column,1306 mir_inst.data.line_column,
1300 ),1307 ),
1301 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{1308 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{
1302 ip.getNav(ip.indexToKey(mir_inst.data.func).func.owner_nav).name.fmt(ip),1309 ip.getNav(ip.indexToKey(mir_inst.data.ip_index).func.owner_nav).name.fmt(ip),
1303 }),1310 }),
1304 .pseudo_dbg_local_a => try writer.print(" {}", .{mir_inst.data.a.air_inst}),1311 .pseudo_dbg_arg_i_s, .pseudo_dbg_var_i_s => try writer.print(" {d}", .{
1305 .pseudo_dbg_local_ai_s => try writer.print(" {}, {d}", .{1312 @as(i32, @bitCast(mir_inst.data.i.i)),
1306 mir_inst.data.ai.air_inst,
1307 @as(i32, @bitCast(mir_inst.data.ai.i)),
1308 }),1313 }),
1309 .pseudo_dbg_local_ai_u => try writer.print(" {}, {d}", .{1314 .pseudo_dbg_arg_i_u, .pseudo_dbg_var_i_u => try writer.print(" {d}", .{
1310 mir_inst.data.ai.air_inst,1315 mir_inst.data.i.i,
1311 mir_inst.data.ai.i,
1312 }),1316 }),
1313 .pseudo_dbg_local_ai_64 => try writer.print(" {}, {d}", .{1317 .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => try writer.print(" {d}", .{
1314 mir_inst.data.ai.air_inst,1318 mir_inst.data.i64,
1315 lower.mir.extraData(Mir.Imm64, mir_inst.data.ai.i).data.decode(),
1316 }),1319 }),
1317 .pseudo_dbg_local_as => {1320 .pseudo_dbg_arg_reloc, .pseudo_dbg_var_reloc => {
1318 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{1321 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1319 .base = .{ .reloc = mir_inst.data.as.sym_index },1322 .base = .{ .reloc = mir_inst.data.reloc.sym_index },
1323 .disp = mir_inst.data.reloc.off,
1320 }) };1324 }) };
1321 try writer.print(" {}, {}", .{ mir_inst.data.as.air_inst, mem_op.fmt(.m) });1325 try writer.print(" {}", .{mem_op.fmt(.m)});
1322 },1326 },
1323 .pseudo_dbg_local_aso => {1327 .pseudo_dbg_arg_ro, .pseudo_dbg_var_ro => {
1324 const sym_off = lower.mir.extraData(bits.SymbolOffset, mir_inst.data.ax.payload).data;
1325 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{1328 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1326 .base = .{ .reloc = sym_off.sym_index },1329 .base = .{ .reg = mir_inst.data.ro.reg },
1327 .disp = sym_off.off,1330 .disp = mir_inst.data.ro.off,
1328 }) };1331 }) };
1329 try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });1332 try writer.print(" {}", .{mem_op.fmt(.m)});
1330 },1333 },
1331 .pseudo_dbg_local_aro => {1334 .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
1332 const air_off = lower.mir.extraData(Mir.AirOffset, mir_inst.data.rx.payload).data;
1333 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{1335 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1334 .base = .{ .reg = mir_inst.data.rx.r1 },1336 .base = .{ .frame = mir_inst.data.fa.index },
1335 .disp = air_off.off,1337 .disp = mir_inst.data.fa.off,
1336 }) };1338 }) };
1337 try writer.print(" {}, {}", .{ air_off.air_inst, mem_op.fmt(.m) });1339 try writer.print(" {}", .{mem_op.fmt(.m)});
1338 },1340 },
1339 .pseudo_dbg_local_af => {1341 .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
1340 const frame_addr = lower.mir.extraData(bits.FrameAddr, mir_inst.data.ax.payload).data;
1341 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
1342 .base = .{ .frame = frame_addr.index },
1343 .disp = frame_addr.off,
1344 }) };
1345 try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });
1346 },
1347 .pseudo_dbg_local_am => {
1348 const mem_op: encoder.Instruction.Operand = .{1342 const mem_op: encoder.Instruction.Operand = .{
1349 .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.ax.payload).data.decode(),1343 .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.x.payload).data.decode(),
1350 };1344 };
1351 try writer.print(" {}, {}", .{ mir_inst.data.ax.air_inst, mem_op.fmt(.m) });1345 try writer.print(" {}", .{mem_op.fmt(.m)});
1352 },1346 },
1347 .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try writer.print(" {}", .{
1348 Value.fromInterned(mir_inst.data.ip_index).fmtValue(data.self.pt),
1349 }),
1353 }1350 }
1354 }1351 }
1355}1352}
...@@ -1640,124 +1637,6 @@ fn asmPlaceholder(self: *CodeGen) !Mir.Inst.Index {...@@ -1640,124 +1637,6 @@ fn asmPlaceholder(self: *CodeGen) !Mir.Inst.Index {
1640 });1637 });
1641}1638}
16421639
1643const MirTagAir = enum { dbg_local };
1644
1645fn asmAir(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index) !void {
1646 _ = try self.addInst(.{
1647 .tag = .pseudo,
1648 .ops = switch (tag) {
1649 .dbg_local => .pseudo_dbg_local_a,
1650 },
1651 .data = .{ .a = .{ .air_inst = inst } },
1652 });
1653}
1654
1655fn asmAirImmediate(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index, imm: Immediate) !void {
1656 switch (imm) {
1657 .signed => |s| _ = try self.addInst(.{
1658 .tag = .pseudo,
1659 .ops = switch (tag) {
1660 .dbg_local => .pseudo_dbg_local_ai_s,
1661 },
1662 .data = .{ .ai = .{
1663 .air_inst = inst,
1664 .i = @bitCast(s),
1665 } },
1666 }),
1667 .unsigned => |u| _ = if (std.math.cast(u32, u)) |small| try self.addInst(.{
1668 .tag = .pseudo,
1669 .ops = switch (tag) {
1670 .dbg_local => .pseudo_dbg_local_ai_u,
1671 },
1672 .data = .{ .ai = .{
1673 .air_inst = inst,
1674 .i = small,
1675 } },
1676 }) else try self.addInst(.{
1677 .tag = .pseudo,
1678 .ops = switch (tag) {
1679 .dbg_local => .pseudo_dbg_local_ai_64,
1680 },
1681 .data = .{ .ai = .{
1682 .air_inst = inst,
1683 .i = try self.addExtra(Mir.Imm64.encode(u)),
1684 } },
1685 }),
1686 .reloc => |sym_off| _ = if (sym_off.off == 0) try self.addInst(.{
1687 .tag = .pseudo,
1688 .ops = switch (tag) {
1689 .dbg_local => .pseudo_dbg_local_as,
1690 },
1691 .data = .{ .as = .{
1692 .air_inst = inst,
1693 .sym_index = sym_off.sym_index,
1694 } },
1695 }) else try self.addInst(.{
1696 .tag = .pseudo,
1697 .ops = switch (tag) {
1698 .dbg_local => .pseudo_dbg_local_aso,
1699 },
1700 .data = .{ .ax = .{
1701 .air_inst = inst,
1702 .payload = try self.addExtra(sym_off),
1703 } },
1704 }),
1705 }
1706}
1707
1708fn asmAirRegisterImmediate(
1709 self: *CodeGen,
1710 tag: MirTagAir,
1711 inst: Air.Inst.Index,
1712 reg: Register,
1713 imm: Immediate,
1714) !void {
1715 _ = try self.addInst(.{
1716 .tag = .pseudo,
1717 .ops = switch (tag) {
1718 .dbg_local => .pseudo_dbg_local_aro,
1719 },
1720 .data = .{ .rx = .{
1721 .r1 = reg,
1722 .payload = try self.addExtra(Mir.AirOffset{
1723 .air_inst = inst,
1724 .off = imm.signed,
1725 }),
1726 } },
1727 });
1728}
1729
1730fn asmAirFrameAddress(
1731 self: *CodeGen,
1732 tag: MirTagAir,
1733 inst: Air.Inst.Index,
1734 frame_addr: bits.FrameAddr,
1735) !void {
1736 _ = try self.addInst(.{
1737 .tag = .pseudo,
1738 .ops = switch (tag) {
1739 .dbg_local => .pseudo_dbg_local_af,
1740 },
1741 .data = .{ .ax = .{
1742 .air_inst = inst,
1743 .payload = try self.addExtra(frame_addr),
1744 } },
1745 });
1746}
1747
1748fn asmAirMemory(self: *CodeGen, tag: MirTagAir, inst: Air.Inst.Index, m: Memory) !void {
1749 _ = try self.addInst(.{
1750 .tag = .pseudo,
1751 .ops = switch (tag) {
1752 .dbg_local => .pseudo_dbg_local_am,
1753 },
1754 .data = .{ .ax = .{
1755 .air_inst = inst,
1756 .payload = try self.addExtra(Mir.Memory.encode(m)),
1757 } },
1758 });
1759}
1760
1761fn asmOpOnly(self: *CodeGen, tag: Mir.Inst.FixedTag) !void {1640fn asmOpOnly(self: *CodeGen, tag: Mir.Inst.FixedTag) !void {
1762 _ = try self.addInst(.{1641 _ = try self.addInst(.{
1763 .tag = tag[1],1642 .tag = tag[1],
...@@ -2233,7 +2112,13 @@ fn asmMemoryRegisterImmediate(...@@ -2233,7 +2112,13 @@ fn asmMemoryRegisterImmediate(
2233 });2112 });
2234}2113}
22352114
2236fn gen(self: *CodeGen) InnerError!void {2115fn gen(
2116 self: *CodeGen,
2117 zir: *const std.zig.Zir,
2118 func_zir_inst: std.zig.Zir.Inst.Index,
2119 comptime_args: InternPool.Index.Slice,
2120 air_arg_count: u32,
2121) InnerError!void {
2237 const pt = self.pt;2122 const pt = self.pt;
2238 const zcu = pt.zcu;2123 const zcu = pt.zcu;
2239 const fn_info = zcu.typeToFunc(self.fn_type).?;2124 const fn_info = zcu.typeToFunc(self.fn_type).?;
...@@ -2303,7 +2188,7 @@ fn gen(self: *CodeGen) InnerError!void {...@@ -2303,7 +2188,7 @@ fn gen(self: *CodeGen) InnerError!void {
23032188
2304 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);2189 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
23052190
2306 try self.genBody(self.air.getMainBody());2191 try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
23072192
2308 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {2193 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {
2309 var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);2194 var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);
...@@ -2438,20 +2323,81 @@ fn gen(self: *CodeGen) InnerError!void {...@@ -2438,20 +2323,81 @@ fn gen(self: *CodeGen) InnerError!void {
2438 }2323 }
2439 } else {2324 } else {
2440 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);2325 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
2441 try self.genBody(self.air.getMainBody());2326 try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
2442 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);2327 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2443 }2328 }
2444}2329}
24452330
2446fn checkInvariantsAfterAirInst(self: *CodeGen) void {2331fn genMainBody(
2447 assert(!self.register_manager.lockedRegsExist());2332 cg: *CodeGen,
2333 zir: *const std.zig.Zir,
2334 func_zir_inst: std.zig.Zir.Inst.Index,
2335 comptime_args: InternPool.Index.Slice,
2336 air_arg_count: u32,
2337) InnerError!void {
2338 const pt = cg.pt;
2339 const zcu = pt.zcu;
2340 const ip = &zcu.intern_pool;
2341
2342 const main_body = cg.air.getMainBody();
2343 const air_args_body = main_body[0..air_arg_count];
2344 try cg.genBody(air_args_body);
2345
2346 if (!cg.mod.strip) {
2347 var air_arg_index: usize = 0;
2348 const fn_info = zcu.typeToFunc(cg.fn_type).?;
2349 var fn_param_index: usize = 0;
2350 try cg.mir_local_types.ensureTotalCapacity(cg.gpa, fn_info.param_types.len);
2351 var zir_param_index: usize = 0;
2352 for (zir.getParamBody(func_zir_inst)) |zir_param_inst| {
2353 const name = zir.nullTerminatedString(zir.getParamName(zir_param_inst) orelse continue);
2354 defer zir_param_index += 1;
2355 try cg.mir_local_name_bytes.appendSlice(cg.gpa, name[0 .. name.len + 1]);
2356
2357 if (comptime_args.len > 0) switch (comptime_args.get(ip)[zir_param_index]) {
2358 .none => {},
2359 else => |comptime_arg| {
2360 _ = try cg.addInst(.{
2361 .tag = .pseudo,
2362 .ops = .pseudo_dbg_arg_val,
2363 .data = .{ .ip_index = comptime_arg },
2364 });
2365 continue;
2366 },
2367 };
2368
2369 const arg_ty: Type = .fromInterned(fn_info.param_types.get(ip)[fn_param_index]);
2370 fn_param_index += 1;
2371 cg.mir_local_types.appendAssumeCapacity(arg_ty.toIntern());
2372
2373 if (air_arg_index == air_args_body.len) {
2374 try cg.asmPseudo(.pseudo_dbg_arg_none);
2375 continue;
2376 }
2377 const air_arg_inst = air_args_body[air_arg_index];
2378 const air_arg_data = cg.air.instructions.items(.data)[air_arg_index].arg;
2379 if (air_arg_data.zir_param_index != zir_param_index) {
2380 try cg.asmPseudo(.pseudo_dbg_arg_none);
2381 continue;
2382 }
2383 air_arg_index += 1;
2384 try cg.genLocalDebugInfo(.arg, arg_ty, cg.getResolvedInstValue(air_arg_inst).short);
2385 }
2386 if (fn_info.is_var_args) try cg.asmPseudo(.pseudo_dbg_var_args_none);
2387 }
2388
2389 try cg.genBody(main_body[air_arg_count..]);
2390}
2391
2392fn checkInvariantsAfterAirInst(cg: *CodeGen) void {
2393 assert(!cg.register_manager.lockedRegsExist());
24482394
2449 if (std.debug.runtime_safety) {2395 if (std.debug.runtime_safety) {
2450 // check consistency of tracked registers2396 // check consistency of tracked registers
2451 var it = self.register_manager.free_registers.iterator(.{ .kind = .unset });2397 var it = cg.register_manager.free_registers.iterator(.{ .kind = .unset });
2452 while (it.next()) |index| {2398 while (it.next()) |index| {
2453 const tracked_inst = self.register_manager.registers[index];2399 const tracked_inst = cg.register_manager.registers[index];
2454 const tracking = self.getResolvedInstValue(tracked_inst);2400 const tracking = cg.getResolvedInstValue(tracked_inst);
2455 for (tracking.getRegs()) |reg| {2401 for (tracking.getRegs()) |reg| {
2456 if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;2402 if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;
2457 } else unreachable; // tracked register not in use2403 } else unreachable; // tracked register not in use
...@@ -2459,10 +2405,10 @@ fn checkInvariantsAfterAirInst(self: *CodeGen) void {...@@ -2459,10 +2405,10 @@ fn checkInvariantsAfterAirInst(self: *CodeGen) void {
2459 }2405 }
2460}2406}
24612407
2462fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {2408fn genBodyBlock(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2463 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_enter_block_none);2409 if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_enter_block_none);
2464 try self.genBody(body);2410 try cg.genBody(body);
2465 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_leave_block_none);2411 if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_leave_block_none);
2466}2412}
24672413
2468fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {2414fn 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 {...@@ -2474,25 +2420,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2474 const air_datas = cg.air.instructions.items(.data);2420 const air_datas = cg.air.instructions.items(.data);
2475 const use_old = cg.target.ofmt == .coff;2421 const use_old = cg.target.ofmt == .coff;
24762422
2477 cg.arg_index = 0;
2478 for (body) |inst| switch (air_tags[@intFromEnum(inst)]) {
2479 .arg => {
2480 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
2481 verbose_tracking_log.debug("{}", .{cg.fmtTracking()});
2482
2483 cg.reused_operands = .initEmpty();
2484 try cg.inst_tracking.ensureUnusedCapacity(cg.gpa, 1);
2485
2486 try cg.airArg(inst);
2487
2488 try cg.resetTemps(@enumFromInt(0));
2489 cg.checkInvariantsAfterAirInst();
2490 },
2491 else => break,
2492 };
2493
2494 if (cg.arg_index == 0) try cg.airDbgVarArgs();
2495 cg.arg_index = 0;
2496 for (body) |inst| {2423 for (body) |inst| {
2497 if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;2424 if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;
2498 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});2425 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
...@@ -2506,20 +2433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -2506,20 +2433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2506 .shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"),2433 .shuffle_one, .shuffle_two => @panic("x86_64 TODO: shuffle_one/shuffle_two"),
2507 // zig fmt: on2434 // zig fmt: on
25082435
2509 .arg => if (!cg.mod.strip) {2436 .arg => try cg.airArg(inst),
2510 // skip zero-bit arguments as they don't have a corresponding arg instruction
2511 var arg_index = cg.arg_index;
2512 while (cg.args[arg_index] == .none) arg_index += 1;
2513 cg.arg_index = arg_index + 1;
2514
2515 const name = air_datas[@intFromEnum(inst)].arg.name;
2516 if (name != .none) try cg.genLocalDebugInfo(inst, cg.getResolvedInstValue(inst).short);
2517 if (cg.liveness.isUnused(inst)) try cg.processDeath(inst);
2518
2519 for (cg.args[arg_index + 1 ..]) |arg| {
2520 if (arg != .none) break;
2521 } else try cg.airDbgVarArgs();
2522 },
2523 .add, .add_optimized, .add_wrap => |air_tag| if (use_old) try cg.airBinOp(inst, switch (air_tag) {2437 .add, .add_optimized, .add_wrap => |air_tag| if (use_old) try cg.airBinOp(inst, switch (air_tag) {
2524 else => unreachable,2438 else => unreachable,
2525 .add, .add_optimized => .add,2439 .add, .add_optimized => .add,
...@@ -85181,19 +85095,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85181,19 +85095,19 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85181 if (!cg.mod.strip) _ = try cg.addInst(.{85095 if (!cg.mod.strip) _ = try cg.addInst(.{
85182 .tag = .pseudo,85096 .tag = .pseudo,
85183 .ops = .pseudo_dbg_enter_inline_func,85097 .ops = .pseudo_dbg_enter_inline_func,
85184 .data = .{ .func = dbg_inline_block.data.func },85098 .data = .{ .ip_index = dbg_inline_block.data.func },
85185 });85099 });
85186 try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[dbg_inline_block.end..][0..dbg_inline_block.data.body_len]));85100 try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[dbg_inline_block.end..][0..dbg_inline_block.data.body_len]));
85187 if (!cg.mod.strip) _ = try cg.addInst(.{85101 if (!cg.mod.strip) _ = try cg.addInst(.{
85188 .tag = .pseudo,85102 .tag = .pseudo,
85189 .ops = .pseudo_dbg_leave_inline_func,85103 .ops = .pseudo_dbg_leave_inline_func,
85190 .data = .{ .func = old_inline_func },85104 .data = .{ .ip_index = old_inline_func },
85191 });85105 });
85192 },85106 },
85193 .dbg_var_ptr,85107 .dbg_var_ptr,
85194 .dbg_var_val,85108 .dbg_var_val,
85195 .dbg_arg_inline,85109 .dbg_arg_inline,
85196 => if (use_old) try cg.airDbgVar(inst) else if (!cg.mod.strip) {85110 => |air_tag| if (use_old) try cg.airDbgVar(inst) else if (!cg.mod.strip) {
85197 const pl_op = air_datas[@intFromEnum(inst)].pl_op;85111 const pl_op = air_datas[@intFromEnum(inst)].pl_op;
85198 var ops = try cg.tempsFromOperands(inst, .{pl_op.operand});85112 var ops = try cg.tempsFromOperands(inst, .{pl_op.operand});
85199 var mcv = ops[0].tracking(cg).short;85113 var mcv = ops[0].tracking(cg).short;
...@@ -85209,7 +85123,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -85209,7 +85123,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
85209 },85123 },
85210 },85124 },
85211 }85125 }
85212 try cg.genLocalDebugInfo(inst, ops[0].tracking(cg).short);85126
85127 const name_nts: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
85128 assert(name_nts != .none);
85129 const name = name_nts.toSlice(cg.air);
85130 try cg.mir_local_name_bytes.appendSlice(cg.gpa, name[0 .. name.len + 1]);
85131
85132 const ty = cg.typeOf(pl_op.operand);
85133 try cg.mir_local_types.append(cg.gpa, ty.toIntern());
85134
85135 try cg.genLocalDebugInfo(air_tag, ty, ops[0].tracking(cg).short);
85213 try ops[0].die(cg);85136 try ops[0].die(cg);
85214 },85137 },
85215 .is_null => if (use_old) try cg.airIsNull(inst) else {85138 .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...@@ -173321,16 +173244,14 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
173321}173244}
173322173245
173323fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {173246fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
173324 const pt = self.pt;173247 const zcu = self.pt.zcu;
173325 const zcu = pt.zcu;173248 const arg_index = for (self.args, 0..) |arg, arg_index| {
173326 // skip zero-bit arguments as they don't have a corresponding arg instruction173249 if (arg != .none) break arg_index;
173327 var arg_index = self.arg_index;173250 } else unreachable;
173328 while (self.args[arg_index] == .none) arg_index += 1;173251 const src_mcv = self.args[arg_index];
173329 self.arg_index = arg_index + 1;173252 self.args = self.args[arg_index + 1 ..];
173330
173331 const result: MCValue = if (self.mod.strip and self.liveness.isUnused(inst)) .unreach else result: {173253 const result: MCValue = if (self.mod.strip and self.liveness.isUnused(inst)) .unreach else result: {
173332 const arg_ty = self.typeOfIndex(inst);173254 const arg_ty = self.typeOfIndex(inst);
173333 const src_mcv = self.args[arg_index];
173334 switch (src_mcv) {173255 switch (src_mcv) {
173335 .register, .register_pair, .load_frame => {173256 .register, .register_pair, .load_frame => {
173336 for (src_mcv.getRegs()) |reg| self.register_manager.getRegAssumeFree(reg, inst);173257 for (src_mcv.getRegs()) |reg| self.register_manager.getRegAssumeFree(reg, inst);
...@@ -173429,68 +173350,108 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -173429,68 +173350,108 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
173429 return self.finishAir(inst, result, .{ .none, .none, .none });173350 return self.finishAir(inst, result, .{ .none, .none, .none });
173430}173351}
173431173352
173432fn airDbgVarArgs(self: *CodeGen) !void {173353fn genLocalDebugInfo(cg: *CodeGen, air_tag: Air.Inst.Tag, ty: Type, mcv: MCValue) !void {
173433 if (self.mod.strip) return;173354 assert(!cg.mod.strip);
173434 if (!self.pt.zcu.typeToFunc(self.fn_type).?.is_var_args) return;173355 _ = switch (air_tag) {
173435 try self.asmPseudo(.pseudo_dbg_var_args_none);
173436}
173437
173438fn genLocalDebugInfo(
173439 self: *CodeGen,
173440 inst: Air.Inst.Index,
173441 mcv: MCValue,
173442) !void {
173443 if (self.mod.strip) return;
173444 switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) {
173445 else => unreachable,173356 else => unreachable,
173446 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {173357 .arg, .dbg_var_val, .dbg_arg_inline => switch (mcv) {
173447 switch (mcv) {173358 .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
173448 .none => try self.asmAir(.dbg_local, inst),173359 .immediate => |imm| if (std.math.cast(u32, imm)) |small| try cg.addInst(.{
173449 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,173360 .tag = .pseudo,
173450 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)),173361 .ops = switch (air_tag) {
173451 .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr),173362 else => unreachable,
173452 .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)),173363 .arg, .dbg_arg_inline => .pseudo_dbg_arg_i_u,
173453 else => {173364 .dbg_var_val => .pseudo_dbg_var_i_u,
173454 const ty = switch (tag) {
173455 else => unreachable,
173456 .arg => self.typeOfIndex(inst),
173457 .dbg_arg_inline, .dbg_var_val => self.typeOf(
173458 self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op.operand,
173459 ),
173460 };
173461 const frame_index = try self.allocFrameIndex(.initSpill(ty, self.pt.zcu));
173462 try self.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
173463 try self.asmAirMemory(.dbg_local, inst, .{
173464 .base = .{ .frame = frame_index },
173465 .mod = .{ .rm = .{ .size = .qword } },
173466 });
173467 },173365 },
173468 }173366 .data = .{ .i = .{ .i = small } },
173367 }) else try cg.addInst(.{
173368 .tag = .pseudo,
173369 .ops = switch (air_tag) {
173370 else => unreachable,
173371 .arg, .dbg_arg_inline => .pseudo_dbg_arg_i_64,
173372 .dbg_var_val => .pseudo_dbg_var_i_64,
173373 },
173374 .data = .{ .i64 = imm },
173375 }),
173376 .lea_frame => |frame_addr| try cg.addInst(.{
173377 .tag = .pseudo,
173378 .ops = switch (air_tag) {
173379 else => unreachable,
173380 .arg, .dbg_arg_inline => .pseudo_dbg_arg_fa,
173381 .dbg_var_val => .pseudo_dbg_var_fa,
173382 },
173383 .data = .{ .fa = frame_addr },
173384 }),
173385 .lea_symbol => |sym_off| try cg.addInst(.{
173386 .tag = .pseudo,
173387 .ops = switch (air_tag) {
173388 else => unreachable,
173389 .arg, .dbg_arg_inline => .pseudo_dbg_arg_reloc,
173390 .dbg_var_val => .pseudo_dbg_var_reloc,
173391 },
173392 .data = .{ .reloc = sym_off },
173393 }),
173394 else => {
173395 const frame_index = try cg.allocFrameIndex(.initSpill(ty, cg.pt.zcu));
173396 try cg.genSetMem(.{ .frame = frame_index }, 0, ty, mcv, .{});
173397 _ = try cg.addInst(.{
173398 .tag = .pseudo,
173399 .ops = switch (air_tag) {
173400 else => unreachable,
173401 .arg, .dbg_arg_inline => .pseudo_dbg_arg_m,
173402 .dbg_var_val => .pseudo_dbg_var_m,
173403 },
173404 .data = .{ .x = .{
173405 .payload = try cg.addExtra(Mir.Memory.encode(.{
173406 .base = .{ .frame = frame_index },
173407 .mod = .{ .rm = .{ .size = .qword } },
173408 })),
173409 } },
173410 });
173411 },
173469 },173412 },
173470 .dbg_var_ptr => switch (mcv) {173413 .dbg_var_ptr => switch (mcv) {
173471 else => unreachable,173414 else => unreachable,
173472 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,173415 .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
173473 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{173416 .lea_frame => |frame_addr| try cg.addInst(.{
173474 .base = .{ .frame = frame_addr.index },173417 .tag = .pseudo,
173475 .mod = .{ .rm = .{173418 .ops = .pseudo_dbg_var_m,
173476 .size = .qword,173419 .data = .{ .x = .{
173477 .disp = frame_addr.off,173420 .payload = try cg.addExtra(Mir.Memory.encode(.{
173421 .base = .{ .frame = frame_addr.index },
173422 .mod = .{ .rm = .{
173423 .size = .qword,
173424 .disp = frame_addr.off,
173425 } },
173426 })),
173478 } },173427 } },
173479 }),173428 }),
173480 // debug info should explicitly ignore pcrel requirements173429 // debug info should explicitly ignore pcrel requirements
173481 .lea_symbol, .lea_pcrel => |sym_off| try self.asmAirMemory(.dbg_local, inst, .{173430 .lea_symbol, .lea_pcrel => |sym_off| try cg.addInst(.{
173482 .base = .{ .reloc = sym_off.sym_index },173431 .tag = .pseudo,
173483 .mod = .{ .rm = .{173432 .ops = .pseudo_dbg_var_m,
173484 .size = .qword,173433 .data = .{ .x = .{
173485 .disp = sym_off.off,173434 .payload = try cg.addExtra(Mir.Memory.encode(.{
173435 .base = .{ .reloc = sym_off.sym_index },
173436 .mod = .{ .rm = .{
173437 .size = .qword,
173438 .disp = sym_off.off,
173439 } },
173440 })),
173486 } },173441 } },
173487 }),173442 }),
173488 .lea_direct, .lea_got => |sym_index| try self.asmAirMemory(.dbg_local, inst, .{173443 .lea_direct, .lea_got => |sym_index| try cg.addInst(.{
173489 .base = .{ .reloc = sym_index },173444 .tag = .pseudo,
173490 .mod = .{ .rm = .{ .size = .qword } },173445 .ops = .pseudo_dbg_var_m,
173446 .data = .{ .x = .{
173447 .payload = try cg.addExtra(Mir.Memory.encode(.{
173448 .base = .{ .reloc = sym_index },
173449 .mod = .{ .rm = .{ .size = .qword } },
173450 })),
173451 } },
173491 }),173452 }),
173492 },173453 },
173493 }173454 };
173494}173455}
173495173456
173496fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void {173457fn airRetAddr(self: *CodeGen, inst: Air.Inst.Index) !void {
...@@ -173514,8 +173475,8 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -173514,8 +173475,8 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
173514 @ptrCast(self.air.extra.items[extra.end..][0..extra.data.args_len]);173475 @ptrCast(self.air.extra.items[extra.end..][0..extra.data.args_len]);
173515173476
173516 const ExpectedContents = extern struct {173477 const ExpectedContents = extern struct {
173517 tys: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),173478 tys: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
173518 vals: [16][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),173479 vals: [32][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
173519 };173480 };
173520 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =173481 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
173521 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);173482 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
...@@ -173570,9 +173531,9 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -173570,9 +173531,9 @@ fn genCall(self: *CodeGen, info: union(enum) {
173570 const fn_info = zcu.typeToFunc(fn_ty).?;173531 const fn_info = zcu.typeToFunc(fn_ty).?;
173571173532
173572 const ExpectedContents = extern struct {173533 const ExpectedContents = extern struct {
173573 var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),173534 var_args: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
173574 frame_indices: [16]FrameIndex,173535 frame_indices: [32]FrameIndex,
173575 reg_locks: [16][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),173536 reg_locks: [32][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),
173576 };173537 };
173577 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =173538 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
173578 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);173539 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
...@@ -174488,10 +174449,21 @@ fn genTry(...@@ -174488,10 +174449,21 @@ fn genTry(
174488 return result;174449 return result;
174489}174450}
174490174451
174491fn airDbgVar(self: *CodeGen, inst: Air.Inst.Index) !void {174452fn airDbgVar(cg: *CodeGen, inst: Air.Inst.Index) !void {
174492 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;174453 if (cg.mod.strip) return;
174493 try self.genLocalDebugInfo(inst, try self.resolveInst(pl_op.operand));174454 const air_tag = cg.air.instructions.items(.tag)[@intFromEnum(inst)];
174494 return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });174455 const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
174456
174457 const name_nts: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
174458 assert(name_nts != .none);
174459 const name = name_nts.toSlice(cg.air);
174460 try cg.mir_local_name_bytes.appendSlice(cg.gpa, name[0 .. name.len + 1]);
174461
174462 const ty = cg.typeOf(pl_op.operand);
174463 try cg.mir_local_types.append(cg.gpa, ty.toIntern());
174464
174465 try cg.genLocalDebugInfo(air_tag, ty, try cg.resolveInst(pl_op.operand));
174466 return cg.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
174495}174467}
174496174468
174497fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {174469fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {
...@@ -181477,6 +181449,7 @@ fn lowerUav(self: *CodeGen, val: Value, alignment: InternPool.Alignment) InnerEr...@@ -181477,6 +181449,7 @@ fn lowerUav(self: *CodeGen, val: Value, alignment: InternPool.Alignment) InnerEr
181477181449
181478const CallMCValues = struct {181450const CallMCValues = struct {
181479 args: []MCValue,181451 args: []MCValue,
181452 air_arg_count: u32,
181480 return_value: InstTracking,181453 return_value: InstTracking,
181481 stack_byte_count: u31,181454 stack_byte_count: u31,
181482 stack_align: InternPool.Alignment,181455 stack_align: InternPool.Alignment,
...@@ -181512,13 +181485,14 @@ fn resolveCallingConventionValues(...@@ -181512,13 +181485,14 @@ fn resolveCallingConventionValues(
181512 const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);181485 const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);
181513 defer allocator.free(param_types);181486 defer allocator.free(param_types);
181514181487
181515 for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src|181488 for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*param_ty, arg_ty|
181516 dest.* = .fromInterned(src);181489 param_ty.* = .fromInterned(arg_ty);
181517 for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty|181490 for (param_types[fn_info.param_types.len..], var_args) |*param_ty, arg_ty|
181518 param_ty.* = self.promoteVarArg(arg_ty);181491 param_ty.* = self.promoteVarArg(arg_ty);
181519181492
181520 var result: CallMCValues = .{181493 var result: CallMCValues = .{
181521 .args = try self.gpa.alloc(MCValue, param_types.len),181494 .args = try self.gpa.alloc(MCValue, param_types.len),
181495 .air_arg_count = 0,
181522 // These undefined values must be populated before returning from this function.181496 // These undefined values must be populated before returning from this function.
181523 .return_value = undefined,181497 .return_value = undefined,
181524 .stack_byte_count = 0,181498 .stack_byte_count = 0,
...@@ -181640,6 +181614,7 @@ fn resolveCallingConventionValues(...@@ -181640,6 +181614,7 @@ fn resolveCallingConventionValues(
181640 // Input params181614 // Input params
181641 for (param_types, result.args) |ty, *arg| {181615 for (param_types, result.args) |ty, *arg| {
181642 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));181616 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
181617 result.air_arg_count += 1;
181643 switch (cc) {181618 switch (cc) {
181644 .x86_64_sysv => {},181619 .x86_64_sysv => {},
181645 .x86_64_win => {181620 .x86_64_win => {
...@@ -181812,6 +181787,7 @@ fn resolveCallingConventionValues(...@@ -181812,6 +181787,7 @@ fn resolveCallingConventionValues(
181812 arg.* = .none;181787 arg.* = .none;
181813 continue;181788 continue;
181814 }181789 }
181790 result.air_arg_count += 1;
181815 const param_size: u31 = @intCast(param_ty.abiSize(zcu));181791 const param_size: u31 = @intCast(param_ty.abiSize(zcu));
181816 if (abi.zigcc.params_in_regs) switch (self.regClassForType(param_ty)) {181792 if (abi.zigcc.params_in_regs) switch (self.regClassForType(param_ty)) {
181817 .general_purpose, .gphi => if (param_gpr.len >= 1 and param_size <= @as(u4, switch (self.target.cpu.arch) {181793 .general_purpose, .gphi => if (param_gpr.len >= 1 and param_size <= @as(u4, switch (self.target.cpu.arch) {
src/arch/x86_64/Emit.zig+104-86
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1//! This file contains the functionality for emitting x86_64 MIR as machine code1//! This file contains the functionality for emitting x86_64 MIR as machine code
22
3air: Air,
4lower: Lower,3lower: Lower,
5atom_index: u32,4atom_index: u32,
6debug_output: link.File.DebugInfoOutput,5debug_output: link.File.DebugInfoOutput,
...@@ -22,6 +21,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -22,6 +21,8 @@ pub fn emitMir(emit: *Emit) Error!void {
22 defer relocs.deinit(emit.lower.allocator);21 defer relocs.deinit(emit.lower.allocator);
23 var table_relocs: std.ArrayListUnmanaged(TableReloc) = .empty;22 var table_relocs: std.ArrayListUnmanaged(TableReloc) = .empty;
24 defer table_relocs.deinit(emit.lower.allocator);23 defer table_relocs.deinit(emit.lower.allocator);
24 var local_name_index: usize = 0;
25 var local_index: usize = 0;
25 for (0..emit.lower.mir.instructions.len) |mir_i| {26 for (0..emit.lower.mir.instructions.len) |mir_i| {
26 const mir_index: Mir.Inst.Index = @intCast(mir_i);27 const mir_index: Mir.Inst.Index = @intCast(mir_i);
27 code_offset_mapping[mir_index] = @intCast(emit.code.items.len);28 code_offset_mapping[mir_index] = @intCast(emit.code.items.len);
...@@ -338,7 +339,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -338,7 +339,7 @@ pub fn emitMir(emit: *Emit) Error!void {
338 log.debug("mirDbgEnterInline (line={d}, col={d})", .{339 log.debug("mirDbgEnterInline (line={d}, col={d})", .{
339 emit.prev_di_loc.line, emit.prev_di_loc.column,340 emit.prev_di_loc.line, emit.prev_di_loc.column,
340 });341 });
341 try dwarf.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);342 try dwarf.enterInlineFunc(mir_inst.data.ip_index, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
342 },343 },
343 .plan9 => {},344 .plan9 => {},
344 .none => {},345 .none => {},
...@@ -348,77 +349,61 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -348,77 +349,61 @@ pub fn emitMir(emit: *Emit) Error!void {
348 log.debug("mirDbgLeaveInline (line={d}, col={d})", .{349 log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
349 emit.prev_di_loc.line, emit.prev_di_loc.column,350 emit.prev_di_loc.line, emit.prev_di_loc.column,
350 });351 });
351 try dwarf.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);352 try dwarf.leaveInlineFunc(mir_inst.data.ip_index, emit.code.items.len);
352 },353 },
353 .plan9 => {},354 .plan9 => {},
354 .none => {},355 .none => {},
355 },356 },
356 .pseudo_dbg_local_a,357 .pseudo_dbg_arg_none,
357 .pseudo_dbg_local_ai_s,358 .pseudo_dbg_arg_i_s,
358 .pseudo_dbg_local_ai_u,359 .pseudo_dbg_arg_i_u,
359 .pseudo_dbg_local_ai_64,360 .pseudo_dbg_arg_i_64,
360 .pseudo_dbg_local_as,361 .pseudo_dbg_arg_reloc,
361 .pseudo_dbg_local_aso,362 .pseudo_dbg_arg_ro,
362 .pseudo_dbg_local_aro,363 .pseudo_dbg_arg_fa,
363 .pseudo_dbg_local_af,364 .pseudo_dbg_arg_m,
364 .pseudo_dbg_local_am,365 .pseudo_dbg_var_none,
366 .pseudo_dbg_var_i_s,
367 .pseudo_dbg_var_i_u,
368 .pseudo_dbg_var_i_64,
369 .pseudo_dbg_var_reloc,
370 .pseudo_dbg_var_ro,
371 .pseudo_dbg_var_fa,
372 .pseudo_dbg_var_m,
365 => switch (emit.debug_output) {373 => switch (emit.debug_output) {
366 .dwarf => |dwarf| {374 .dwarf => |dwarf| {
367 var loc_buf: [2]link.File.Dwarf.Loc = undefined;375 var loc_buf: [2]link.File.Dwarf.Loc = undefined;
368 const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {376 const loc: link.File.Dwarf.Loc = loc: switch (mir_inst.ops) {
369 else => unreachable,377 else => unreachable,
370 .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },378 .pseudo_dbg_arg_none, .pseudo_dbg_var_none => .empty,
371 .pseudo_dbg_local_ai_s,379 .pseudo_dbg_arg_i_s,
372 .pseudo_dbg_local_ai_u,380 .pseudo_dbg_arg_i_u,
373 .pseudo_dbg_local_ai_64,381 .pseudo_dbg_var_i_s,
374 => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {382 .pseudo_dbg_var_i_u,
375 loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {383 => .{ .stack_value = stack_value: {
384 loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.i.i)) {
376 .signed => |s| .{ .consts = s },385 .signed => |s| .{ .consts = s },
377 .unsigned => |u| .{ .constu = u },386 .unsigned => |u| .{ .constu = u },
378 };387 };
379 break :stack_value &loc_buf[0];388 break :stack_value &loc_buf[0];
380 } } },
381 .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{
382 .addr_reloc = mir_inst.data.as.sym_index,
383 } },389 } },
384 .pseudo_dbg_local_aso => loc: {390 .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => .{ .stack_value = stack_value: {
385 const sym_off = emit.lower.mir.extraData(391 loc_buf[0] = .{ .constu = mir_inst.data.i64 };
386 bits.SymbolOffset,392 break :stack_value &loc_buf[0];
387 mir_inst.data.ax.payload,393 } },
388 ).data;394 .pseudo_dbg_arg_reloc, .pseudo_dbg_var_reloc => .{ .plus = .{
389 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{395 sym: {
390 sym: {396 loc_buf[0] = .{ .addr_reloc = mir_inst.data.reloc.sym_index };
391 loc_buf[0] = .{ .addr_reloc = sym_off.sym_index };397 break :sym &loc_buf[0];
392 break :sym &loc_buf[0];398 },
393 },399 off: {
394 off: {400 loc_buf[1] = .{ .consts = mir_inst.data.reloc.off };
395 loc_buf[1] = .{ .consts = sym_off.off };401 break :off &loc_buf[1];
396 break :off &loc_buf[1];402 },
397 },403 } },
398 } } };404 .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
399 },405 const reg_off = emit.lower.mir.resolveFrameAddr(mir_inst.data.fa);
400 .pseudo_dbg_local_aro => loc: {406 break :loc .{ .plus = .{
401 const air_off = emit.lower.mir.extraData(
402 Mir.AirOffset,
403 mir_inst.data.rx.payload,
404 ).data;
405 break :loc .{ air_off.air_inst, .{ .plus = .{
406 reg: {
407 loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
408 break :reg &loc_buf[0];
409 },
410 off: {
411 loc_buf[1] = .{ .consts = air_off.off };
412 break :off &loc_buf[1];
413 },
414 } } };
415 },
416 .pseudo_dbg_local_af => loc: {
417 const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
418 bits.FrameAddr,
419 mir_inst.data.ax.payload,
420 ).data);
421 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
422 reg: {407 reg: {
423 loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };408 loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
424 break :reg &loc_buf[0];409 break :reg &loc_buf[0];
...@@ -427,11 +412,11 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -427,11 +412,11 @@ pub fn emitMir(emit: *Emit) Error!void {
427 loc_buf[1] = .{ .consts = reg_off.off };412 loc_buf[1] = .{ .consts = reg_off.off };
428 break :off &loc_buf[1];413 break :off &loc_buf[1];
429 },414 },
430 } } };415 } };
431 },416 },
432 .pseudo_dbg_local_am => loc: {417 .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
433 const mem = emit.lower.mem(undefined, mir_inst.data.ax.payload);418 const mem = emit.lower.mem(undefined, mir_inst.data.x.payload);
434 break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{419 break :loc .{ .plus = .{
435 base: {420 base: {
436 loc_buf[0] = switch (mem.base()) {421 loc_buf[0] = switch (mem.base()) {
437 .none => .{ .constu = 0 },422 .none => .{ .constu = 0 },
...@@ -449,30 +434,64 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -449,30 +434,64 @@ pub fn emitMir(emit: *Emit) Error!void {
449 };434 };
450 break :disp &loc_buf[1];435 break :disp &loc_buf[1];
451 },436 },
452 } } };437 } };
453 },438 },
454 };439 };
455 const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;440
456 const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));441 const local_name_bytes = emit.lower.mir.local_name_bytes[local_name_index..];
457 const name: Air.NullTerminatedString = switch (air_inst.tag) {442 const local_name = local_name_bytes[0..std.mem.indexOfScalar(u8, local_name_bytes, 0).? :0];
458 else => unreachable,443 local_name_index += local_name.len + 1;
459 .arg => air_inst.data.arg.name,444
460 .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),445 const local_type = emit.lower.mir.local_types[local_index];
461 };446 local_index += 1;
462 try dwarf.genLocalDebugInfo(447
463 switch (air_inst.tag) {448 try dwarf.genLocalVarDebugInfo(
449 switch (mir_inst.ops) {
464 else => unreachable,450 else => unreachable,
465 .arg, .dbg_arg_inline => .local_arg,451 .pseudo_dbg_arg_none,
466 .dbg_var_ptr, .dbg_var_val => .local_var,452 .pseudo_dbg_arg_i_s,
453 .pseudo_dbg_arg_i_u,
454 .pseudo_dbg_arg_i_64,
455 .pseudo_dbg_arg_reloc,
456 .pseudo_dbg_arg_ro,
457 .pseudo_dbg_arg_fa,
458 .pseudo_dbg_arg_m,
459 .pseudo_dbg_arg_val,
460 => .arg,
461 .pseudo_dbg_var_none,
462 .pseudo_dbg_var_i_s,
463 .pseudo_dbg_var_i_u,
464 .pseudo_dbg_var_i_64,
465 .pseudo_dbg_var_reloc,
466 .pseudo_dbg_var_ro,
467 .pseudo_dbg_var_fa,
468 .pseudo_dbg_var_m,
469 .pseudo_dbg_var_val,
470 => .local_var,
467 },471 },
468 name.toSlice(emit.air),472 local_name,
469 switch (air_inst.tag) {473 .fromInterned(local_type),
474 loc,
475 );
476 },
477 .plan9 => {},
478 .none => {},
479 },
480 .pseudo_dbg_arg_val, .pseudo_dbg_var_val => switch (emit.debug_output) {
481 .dwarf => |dwarf| {
482 const local_name_bytes = emit.lower.mir.local_name_bytes[local_name_index..];
483 const local_name = local_name_bytes[0..std.mem.indexOfScalar(u8, local_name_bytes, 0).? :0];
484 local_name_index += local_name.len + 1;
485
486 try dwarf.genLocalConstDebugInfo(
487 emit.lower.src_loc,
488 switch (mir_inst.ops) {
470 else => unreachable,489 else => unreachable,
471 .arg => emit.air.typeOfIndex(air_inst_index, ip),490 .pseudo_dbg_arg_val => .comptime_arg,
472 .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),491 .pseudo_dbg_var_val => .local_const,
473 .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
474 },492 },
475 loc,493 local_name,
494 .fromInterned(mir_inst.data.ip_index),
476 );495 );
477 },496 },
478 .plan9 => {},497 .plan9 => {},
...@@ -611,11 +630,10 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {...@@ -611,11 +630,10 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
611}630}
612631
613const bits = @import("bits.zig");632const bits = @import("bits.zig");
633const Emit = @This();
634const InternPool = @import("../../InternPool.zig");
614const link = @import("../../link.zig");635const link = @import("../../link.zig");
615const log = std.log.scoped(.emit);636const log = std.log.scoped(.emit);
616const std = @import("std");
617
618const Air = @import("../../Air.zig");
619const Emit = @This();
620const Lower = @import("Lower.zig");637const Lower = @import("Lower.zig");
621const Mir = @import("Mir.zig");638const Mir = @import("Mir.zig");
639const std = @import("std");
src/arch/x86_64/Lower.zig+26-12
...@@ -327,16 +327,25 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {...@@ -327,16 +327,25 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
327 .pseudo_dbg_leave_block_none,327 .pseudo_dbg_leave_block_none,
328 .pseudo_dbg_enter_inline_func,328 .pseudo_dbg_enter_inline_func,
329 .pseudo_dbg_leave_inline_func,329 .pseudo_dbg_leave_inline_func,
330 .pseudo_dbg_local_a,330 .pseudo_dbg_arg_none,
331 .pseudo_dbg_local_ai_s,331 .pseudo_dbg_arg_i_s,
332 .pseudo_dbg_local_ai_u,332 .pseudo_dbg_arg_i_u,
333 .pseudo_dbg_local_ai_64,333 .pseudo_dbg_arg_i_64,
334 .pseudo_dbg_local_as,334 .pseudo_dbg_arg_reloc,
335 .pseudo_dbg_local_aso,335 .pseudo_dbg_arg_ro,
336 .pseudo_dbg_local_aro,336 .pseudo_dbg_arg_fa,
337 .pseudo_dbg_local_af,337 .pseudo_dbg_arg_m,
338 .pseudo_dbg_local_am,338 .pseudo_dbg_arg_val,
339 .pseudo_dbg_var_args_none,339 .pseudo_dbg_var_args_none,
340 .pseudo_dbg_var_none,
341 .pseudo_dbg_var_i_s,
342 .pseudo_dbg_var_i_u,
343 .pseudo_dbg_var_i_64,
344 .pseudo_dbg_var_reloc,
345 .pseudo_dbg_var_ro,
346 .pseudo_dbg_var_fa,
347 .pseudo_dbg_var_m,
348 .pseudo_dbg_var_val,
340349
341 .pseudo_dead_none,350 .pseudo_dead_none,
342 => {},351 => {},
...@@ -364,7 +373,8 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {...@@ -364,7 +373,8 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
364 .i_s,373 .i_s,
365 .mi_s,374 .mi_s,
366 .rmi_s,375 .rmi_s,
367 .pseudo_dbg_local_ai_s,376 .pseudo_dbg_arg_i_s,
377 .pseudo_dbg_var_i_s,
368 => .s(@bitCast(i)),378 => .s(@bitCast(i)),
369379
370 .ii,380 .ii,
...@@ -379,13 +389,17 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {...@@ -379,13 +389,17 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
379 .mri,389 .mri,
380 .rrm,390 .rrm,
381 .rrmi,391 .rrmi,
382 .pseudo_dbg_local_ai_u,392 .pseudo_dbg_arg_i_u,
393 .pseudo_dbg_var_i_u,
383 => .u(i),394 => .u(i),
384395
385 .ri_64,396 .ri_64,
386 .pseudo_dbg_local_ai_64,
387 => .u(lower.mir.extraData(Mir.Imm64, i).data.decode()),397 => .u(lower.mir.extraData(Mir.Imm64, i).data.decode()),
388398
399 .pseudo_dbg_arg_i_64,
400 .pseudo_dbg_var_i_64,
401 => unreachable,
402
389 else => unreachable,403 else => unreachable,
390 };404 };
391}405}
src/arch/x86_64/Mir.zig+69-50
...@@ -9,6 +9,8 @@...@@ -9,6 +9,8 @@
9instructions: std.MultiArrayList(Inst).Slice,9instructions: std.MultiArrayList(Inst).Slice,
10/// The meaning of this data is determined by `Inst.Tag` value.10/// The meaning of this data is determined by `Inst.Tag` value.
11extra: []const u32,11extra: []const u32,
12local_name_bytes: []const u8,
13local_types: []const InternPool.Index,
12table: []const Inst.Index,14table: []const Inst.Index,
13frame_locs: std.MultiArrayList(FrameLoc).Slice,15frame_locs: std.MultiArrayList(FrameLoc).Slice,
1416
...@@ -1522,6 +1524,7 @@ pub const Inst = struct {...@@ -1522,6 +1524,7 @@ pub const Inst = struct {
1522 pseudo_cfi_escape_bytes,1524 pseudo_cfi_escape_bytes,
15231525
1524 /// End of prologue1526 /// End of prologue
1527 /// Uses `none` payload.
1525 pseudo_dbg_prologue_end_none,1528 pseudo_dbg_prologue_end_none,
1526 /// Update debug line with is_stmt register set1529 /// Update debug line with is_stmt register set
1527 /// Uses `line_column` payload.1530 /// Uses `line_column` payload.
...@@ -1530,44 +1533,76 @@ pub const Inst = struct {...@@ -1530,44 +1533,76 @@ pub const Inst = struct {
1530 /// Uses `line_column` payload.1533 /// Uses `line_column` payload.
1531 pseudo_dbg_line_line_column,1534 pseudo_dbg_line_line_column,
1532 /// Start of epilogue1535 /// Start of epilogue
1536 /// Uses `none` payload.
1533 pseudo_dbg_epilogue_begin_none,1537 pseudo_dbg_epilogue_begin_none,
1534 /// Start of lexical block1538 /// Start of lexical block
1539 /// Uses `none` payload.
1535 pseudo_dbg_enter_block_none,1540 pseudo_dbg_enter_block_none,
1536 /// End of lexical block1541 /// End of lexical block
1542 /// Uses `none` payload.
1537 pseudo_dbg_leave_block_none,1543 pseudo_dbg_leave_block_none,
1538 /// Start of inline function1544 /// Start of inline function
1545 /// Uses `ip_index` payload.
1539 pseudo_dbg_enter_inline_func,1546 pseudo_dbg_enter_inline_func,
1540 /// End of inline function1547 /// End of inline function
1548 /// Uses `ip_index` payload.
1541 pseudo_dbg_leave_inline_func,1549 pseudo_dbg_leave_inline_func,
1542 /// Local argument or variable.1550 /// Local argument.
1543 /// Uses `a` payload.1551 /// Uses `none` payload.
1544 pseudo_dbg_local_a,1552 pseudo_dbg_arg_none,
1545 /// Local argument or variable.1553 /// Local argument.
1546 /// Uses `ai` payload.1554 /// Uses `i` payload.
1547 pseudo_dbg_local_ai_s,1555 pseudo_dbg_arg_i_s,
1548 /// Local argument or variable.1556 /// Local argument.
1549 /// Uses `ai` payload.1557 /// Uses `i` payload.
1550 pseudo_dbg_local_ai_u,1558 pseudo_dbg_arg_i_u,
1551 /// Local argument or variable.1559 /// Local argument.
1552 /// Uses `ai` payload with extra data of type `Imm64`.1560 /// Uses `i64` payload.
1553 pseudo_dbg_local_ai_64,1561 pseudo_dbg_arg_i_64,
1554 /// Local argument or variable.1562 /// Local argument.
1555 /// Uses `as` payload.1563 /// Uses `reloc` payload.
1556 pseudo_dbg_local_as,1564 pseudo_dbg_arg_reloc,
1557 /// Local argument or variable.1565 /// Local argument.
1558 /// Uses `ax` payload with extra data of type `bits.SymbolOffset`.1566 /// Uses `ro` payload.
1559 pseudo_dbg_local_aso,1567 pseudo_dbg_arg_ro,
1560 /// Local argument or variable.1568 /// Local argument.
1561 /// Uses `rx` payload with extra data of type `AirOffset`.1569 /// Uses `fa` payload.
1562 pseudo_dbg_local_aro,1570 pseudo_dbg_arg_fa,
1563 /// Local argument or variable.1571 /// Local argument.
1564 /// Uses `ax` payload with extra data of type `bits.FrameAddr`.1572 /// Uses `x` payload with extra data of type `Memory`.
1565 pseudo_dbg_local_af,1573 pseudo_dbg_arg_m,
1566 /// Local argument or variable.1574 /// Local argument.
1567 /// Uses `ax` payload with extra data of type `Memory`.1575 /// Uses `ip_index` payload.
1568 pseudo_dbg_local_am,1576 pseudo_dbg_arg_val,
1569 /// Remaining arguments are varargs.1577 /// Remaining arguments are varargs.
1570 pseudo_dbg_var_args_none,1578 pseudo_dbg_var_args_none,
1579 /// Local variable.
1580 /// Uses `none` payload.
1581 pseudo_dbg_var_none,
1582 /// Local variable.
1583 /// Uses `i` payload.
1584 pseudo_dbg_var_i_s,
1585 /// Local variable.
1586 /// Uses `i` payload.
1587 pseudo_dbg_var_i_u,
1588 /// Local variable.
1589 /// Uses `i64` payload.
1590 pseudo_dbg_var_i_64,
1591 /// Local variable.
1592 /// Uses `reloc` payload.
1593 pseudo_dbg_var_reloc,
1594 /// Local variable.
1595 /// Uses `ro` payload.
1596 pseudo_dbg_var_ro,
1597 /// Local variable.
1598 /// Uses `fa` payload.
1599 pseudo_dbg_var_fa,
1600 /// Local variable.
1601 /// Uses `x` payload with extra data of type `Memory`.
1602 pseudo_dbg_var_m,
1603 /// Local variable.
1604 /// Uses `ip_index` payload.
1605 pseudo_dbg_var_val,
15711606
1572 /// Tombstone1607 /// Tombstone
1573 /// Emitter should skip this instruction.1608 /// Emitter should skip this instruction.
...@@ -1584,6 +1619,7 @@ pub const Inst = struct {...@@ -1584,6 +1619,7 @@ pub const Inst = struct {
1584 inst: Index,1619 inst: Index,
1585 },1620 },
1586 /// A 32-bit immediate value.1621 /// A 32-bit immediate value.
1622 i64: u64,
1587 i: struct {1623 i: struct {
1588 fixes: Fixes = ._,1624 fixes: Fixes = ._,
1589 i: u32,1625 i: u32,
...@@ -1683,31 +1719,18 @@ pub const Inst = struct {...@@ -1683,31 +1719,18 @@ pub const Inst = struct {
1683 return std.mem.sliceAsBytes(mir.extra[bytes.payload..])[0..bytes.len];1719 return std.mem.sliceAsBytes(mir.extra[bytes.payload..])[0..bytes.len];
1684 }1720 }
1685 },1721 },
1686 a: struct {
1687 air_inst: Air.Inst.Index,
1688 },
1689 ai: struct {
1690 air_inst: Air.Inst.Index,
1691 i: u32,
1692 },
1693 as: struct {
1694 air_inst: Air.Inst.Index,
1695 sym_index: u32,
1696 },
1697 ax: struct {
1698 air_inst: Air.Inst.Index,
1699 payload: u32,
1700 },
1701 /// Relocation for the linker where:1722 /// Relocation for the linker where:
1702 /// * `sym_index` is the index of the target1723 /// * `sym_index` is the index of the target
1703 /// * `off` is the offset from the target1724 /// * `off` is the offset from the target
1704 reloc: bits.SymbolOffset,1725 reloc: bits.SymbolOffset,
1726 fa: bits.FrameAddr,
1727 ro: bits.RegisterOffset,
1705 /// Debug line and column position1728 /// Debug line and column position
1706 line_column: struct {1729 line_column: struct {
1707 line: u32,1730 line: u32,
1708 column: u32,1731 column: u32,
1709 },1732 },
1710 func: InternPool.Index,1733 ip_index: InternPool.Index,
1711 /// Register list1734 /// Register list
1712 reg_list: RegisterList,1735 reg_list: RegisterList,
1713 };1736 };
...@@ -1760,8 +1783,6 @@ pub const Inst = struct {...@@ -1760,8 +1783,6 @@ pub const Inst = struct {
1760 }1783 }
1761};1784};
17621785
1763pub const AirOffset = struct { air_inst: Air.Inst.Index, off: i32 };
1764
1765/// Used in conjunction with payload to transfer a list of used registers in a compact manner.1786/// Used in conjunction with payload to transfer a list of used registers in a compact manner.
1766pub const RegisterList = struct {1787pub const RegisterList = struct {
1767 bitset: BitSet,1788 bitset: BitSet,
...@@ -1924,6 +1945,8 @@ pub const Memory = struct {...@@ -1924,6 +1945,8 @@ pub const Memory = struct {
1924pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {1945pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
1925 mir.instructions.deinit(gpa);1946 mir.instructions.deinit(gpa);
1926 gpa.free(mir.extra);1947 gpa.free(mir.extra);
1948 gpa.free(mir.local_name_bytes);
1949 gpa.free(mir.local_types);
1927 gpa.free(mir.table);1950 gpa.free(mir.table);
1928 mir.frame_locs.deinit(gpa);1951 mir.frame_locs.deinit(gpa);
1929 mir.* = undefined;1952 mir.* = undefined;
...@@ -1937,8 +1960,6 @@ pub fn emit(...@@ -1937,8 +1960,6 @@ pub fn emit(
1937 func_index: InternPool.Index,1960 func_index: InternPool.Index,
1938 code: *std.ArrayListUnmanaged(u8),1961 code: *std.ArrayListUnmanaged(u8),
1939 debug_output: link.File.DebugInfoOutput,1962 debug_output: link.File.DebugInfoOutput,
1940 /// TODO: remove dependency on this argument. This blocks enabling `Zcu.Feature.separate_thread`.
1941 air: *const Air,
1942) codegen.CodeGenError!void {1963) codegen.CodeGenError!void {
1943 const zcu = pt.zcu;1964 const zcu = pt.zcu;
1944 const comp = zcu.comp;1965 const comp = zcu.comp;
...@@ -1948,7 +1969,6 @@ pub fn emit(...@@ -1948,7 +1969,6 @@ pub fn emit(
1948 const nav = func.owner_nav;1969 const nav = func.owner_nav;
1949 const mod = zcu.navFileScope(nav).mod.?;1970 const mod = zcu.navFileScope(nav).mod.?;
1950 var e: Emit = .{1971 var e: Emit = .{
1951 .air = air.*,
1952 .lower = .{1972 .lower = .{
1953 .bin_file = lf,1973 .bin_file = lf,
1954 .target = &mod.resolved_target.result,1974 .target = &mod.resolved_target.result,
...@@ -1998,7 +2018,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end:...@@ -1998,7 +2018,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end:
1998 @field(result, field.name) = switch (field.type) {2018 @field(result, field.name) = switch (field.type) {
1999 u32 => mir.extra[i],2019 u32 => mir.extra[i],
2000 i32, Memory.Info => @bitCast(mir.extra[i]),2020 i32, Memory.Info => @bitCast(mir.extra[i]),
2001 bits.FrameIndex, Air.Inst.Index => @enumFromInt(mir.extra[i]),2021 bits.FrameIndex => @enumFromInt(mir.extra[i]),
2002 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),2022 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
2003 };2023 };
2004 i += 1;2024 i += 1;
...@@ -2043,7 +2063,6 @@ const builtin = @import("builtin");...@@ -2043,7 +2063,6 @@ const builtin = @import("builtin");
2043const encoder = @import("encoder.zig");2063const encoder = @import("encoder.zig");
2044const std = @import("std");2064const std = @import("std");
20452065
2046const Air = @import("../../Air.zig");
2047const IntegerBitSet = std.bit_set.IntegerBitSet;2066const IntegerBitSet = std.bit_set.IntegerBitSet;
2048const InternPool = @import("../../InternPool.zig");2067const InternPool = @import("../../InternPool.zig");
2049const Mir = @This();2068const Mir = @This();
src/codegen.zig+1-5
...@@ -180,10 +180,6 @@ pub fn emitFunction(...@@ -180,10 +180,6 @@ pub fn emitFunction(
180 any_mir: *const AnyMir,180 any_mir: *const AnyMir,
181 code: *std.ArrayListUnmanaged(u8),181 code: *std.ArrayListUnmanaged(u8),
182 debug_output: link.File.DebugInfoOutput,182 debug_output: link.File.DebugInfoOutput,
183 /// TODO: this parameter needs to be removed. We should not still hold AIR this late
184 /// in the pipeline. Any information needed to call emit must be stored in MIR.
185 /// This is `undefined` if the backend supports the `separate_thread` feature.
186 air: *const Air,
187) CodeGenError!void {183) CodeGenError!void {
188 const zcu = pt.zcu;184 const zcu = pt.zcu;
189 const func = zcu.funcInfo(func_index);185 const func = zcu.funcInfo(func_index);
...@@ -199,7 +195,7 @@ pub fn emitFunction(...@@ -199,7 +195,7 @@ pub fn emitFunction(
199 => |backend| {195 => |backend| {
200 dev.check(devFeatureForBackend(backend));196 dev.check(devFeatureForBackend(backend));
201 const mir = &@field(any_mir, AnyMir.tag(backend));197 const mir = &@field(any_mir, AnyMir.tag(backend));
202 return mir.emit(lf, pt, src_loc, func_index, code, debug_output, air);198 return mir.emit(lf, pt, src_loc, func_index, code, debug_output);
203 },199 },
204 }200 }
205}201}
src/codegen/llvm.zig+10-5
...@@ -9509,15 +9509,21 @@ pub const FuncGen = struct {...@@ -9509,15 +9509,21 @@ pub const FuncGen = struct {
95099509
9510 const inst_ty = self.typeOfIndex(inst);9510 const inst_ty = self.typeOfIndex(inst);
95119511
9512 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
9513 if (name == .none) return arg_val;
9514
9515 const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());9512 const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());
9513 const func_zir = func.zir_body_inst.resolveFull(&zcu.intern_pool).?;
9514 const file = zcu.fileByIndex(func_zir.file);
9515
9516 const mod = file.mod.?;
9517 if (mod.strip) return arg_val;
9518 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
9519 const zir = &file.zir.?;
9520 const name = zir.nullTerminatedString(zir.getParamName(zir.getParamBody(func_zir.inst)[arg.zir_param_index]).?);
9521
9516 const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;9522 const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;
9517 const lbrace_col = func.lbrace_column + 1;9523 const lbrace_col = func.lbrace_column + 1;
95189524
9519 const debug_parameter = try o.builder.debugParameter(9525 const debug_parameter = try o.builder.debugParameter(
9520 try o.builder.metadataString(name.toSlice(self.air)),9526 try o.builder.metadataString(name),
9521 self.file,9527 self.file,
9522 self.scope,9528 self.scope,
9523 lbrace_line,9529 lbrace_line,
...@@ -9535,7 +9541,6 @@ pub const FuncGen = struct {...@@ -9535,7 +9541,6 @@ pub const FuncGen = struct {
9535 },9541 },
9536 };9542 };
95379543
9538 const mod = self.ng.ownerModule();
9539 if (isByRef(inst_ty, zcu)) {9544 if (isByRef(inst_ty, zcu)) {
9540 _ = try self.wip.callIntrinsic(9545 _ = try self.wip.callIntrinsic(
9541 .normal,9546 .normal,
src/link.zig+2-11
...@@ -8,7 +8,6 @@ const log = std.log.scoped(.link);...@@ -8,7 +8,6 @@ const log = std.log.scoped(.link);
8const trace = @import("tracy.zig").trace;8const trace = @import("tracy.zig").trace;
9const wasi_libc = @import("libs/wasi_libc.zig");9const wasi_libc = @import("libs/wasi_libc.zig");
1010
11const Air = @import("Air.zig");
12const Allocator = std.mem.Allocator;11const Allocator = std.mem.Allocator;
13const Cache = std.Build.Cache;12const Cache = std.Build.Cache;
14const Path = std.Build.Cache.Path;13const Path = std.Build.Cache.Path;
...@@ -752,9 +751,6 @@ pub const File = struct {...@@ -752,9 +751,6 @@ pub const File = struct {
752 /// that `mir.deinit` remains legal for the caller. For instance, the callee can751 /// that `mir.deinit` remains legal for the caller. For instance, the callee can
753 /// take ownership of an embedded slice and replace it with `&.{}` in `mir`.752 /// take ownership of an embedded slice and replace it with `&.{}` in `mir`.
754 mir: *codegen.AnyMir,753 mir: *codegen.AnyMir,
755 /// This may be `undefined`; only pass it to `emitFunction`.
756 /// This parameter will eventually be removed.
757 maybe_undef_air: *const Air,
758 ) UpdateNavError!void {754 ) UpdateNavError!void {
759 assert(base.comp.zcu.?.llvm_object == null);755 assert(base.comp.zcu.?.llvm_object == null);
760 switch (base.tag) {756 switch (base.tag) {
...@@ -762,7 +758,7 @@ pub const File = struct {...@@ -762,7 +758,7 @@ pub const File = struct {
762 .spirv => unreachable, // see corresponding special case in `Zcu.PerThread.runCodegenInner`758 .spirv => unreachable, // see corresponding special case in `Zcu.PerThread.runCodegenInner`
763 inline else => |tag| {759 inline else => |tag| {
764 dev.check(tag.devFeature());760 dev.check(tag.devFeature());
765 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir, maybe_undef_air);761 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir);
766 },762 },
767 }763 }
768 }764 }
...@@ -1271,11 +1267,6 @@ pub const ZcuTask = union(enum) {...@@ -1271,11 +1267,6 @@ pub const ZcuTask = union(enum) {
1271 /// the codegen job to ensure that the linker receives functions in a deterministic order,1267 /// the codegen job to ensure that the linker receives functions in a deterministic order,
1272 /// allowing reproducible builds.1268 /// allowing reproducible builds.
1273 mir: *SharedMir,1269 mir: *SharedMir,
1274 /// This field exists only due to deficiencies in some codegen implementations; it should
1275 /// be removed when the corresponding parameter of `CodeGen.emitFunction` can be removed.
1276 /// This is `undefined` if `Zcu.Feature.separate_thread` is supported.
1277 /// If this is defined, its memory is owned externally; do not `deinit` this `air`.
1278 air: *const Air,
12791270
1280 pub const SharedMir = struct {1271 pub const SharedMir = struct {
1281 /// This is initially `.pending`. When `value` is populated, the codegen thread will set1272 /// 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 {...@@ -1458,7 +1449,7 @@ pub fn doZcuTask(comp: *Compilation, tid: usize, task: ZcuTask) void {
1458 assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR1449 assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR
1459 const mir = &func.mir.value;1450 const mir = &func.mir.value;
1460 if (comp.bin_file) |lf| {1451 if (comp.bin_file) |lf| {
1461 lf.updateFunc(pt, func.func, mir, func.air) catch |err| switch (err) {1452 lf.updateFunc(pt, func.func, mir) catch |err| switch (err) {
1462 error.OutOfMemory => return diags.setAllocFailure(),1453 error.OutOfMemory => return diags.setAllocFailure(),
1463 error.CodegenFail => return zcu.assertCodegenFailed(nav),1454 error.CodegenFail => return zcu.assertCodegenFailed(nav),
1464 error.Overflow, error.RelocationNotByteAligned => {1455 error.Overflow, error.RelocationNotByteAligned => {
src/link/C.zig-6
...@@ -17,7 +17,6 @@ const link = @import("../link.zig");...@@ -17,7 +17,6 @@ const link = @import("../link.zig");
17const trace = @import("../tracy.zig").trace;17const trace = @import("../tracy.zig").trace;
18const Type = @import("../Type.zig");18const Type = @import("../Type.zig");
19const Value = @import("../Value.zig");19const Value = @import("../Value.zig");
20const Air = @import("../Air.zig");
21const AnyMir = @import("../codegen.zig").AnyMir;20const AnyMir = @import("../codegen.zig").AnyMir;
2221
23pub const zig_h = "#include \"zig.h\"\n";22pub const zig_h = "#include \"zig.h\"\n";
...@@ -182,12 +181,7 @@ pub fn updateFunc(...@@ -182,12 +181,7 @@ pub fn updateFunc(
182 pt: Zcu.PerThread,181 pt: Zcu.PerThread,
183 func_index: InternPool.Index,182 func_index: InternPool.Index,
184 mir: *AnyMir,183 mir: *AnyMir,
185 /// This may be `undefined`; only pass it to `emitFunction`.
186 /// This parameter will eventually be removed.
187 maybe_undef_air: *const Air,
188) link.File.UpdateNavError!void {184) link.File.UpdateNavError!void {
189 _ = maybe_undef_air; // It would be a bug to use this argument.
190
191 const zcu = pt.zcu;185 const zcu = pt.zcu;
192 const gpa = zcu.gpa;186 const gpa = zcu.gpa;
193 const func = zcu.funcInfo(func_index);187 const func = zcu.funcInfo(func_index);
src/link/Coff.zig-5
...@@ -1053,9 +1053,6 @@ pub fn updateFunc(...@@ -1053,9 +1053,6 @@ pub fn updateFunc(
1053 pt: Zcu.PerThread,1053 pt: Zcu.PerThread,
1054 func_index: InternPool.Index,1054 func_index: InternPool.Index,
1055 mir: *const codegen.AnyMir,1055 mir: *const codegen.AnyMir,
1056 /// This may be `undefined`; only pass it to `emitFunction`.
1057 /// This parameter will eventually be removed.
1058 maybe_undef_air: *const Air,
1059) link.File.UpdateNavError!void {1056) link.File.UpdateNavError!void {
1060 if (build_options.skip_non_native and builtin.object_format != .coff) {1057 if (build_options.skip_non_native and builtin.object_format != .coff) {
1061 @panic("Attempted to compile for object format that was disabled by build configuration");1058 @panic("Attempted to compile for object format that was disabled by build configuration");
...@@ -1084,7 +1081,6 @@ pub fn updateFunc(...@@ -1084,7 +1081,6 @@ pub fn updateFunc(
1084 mir,1081 mir,
1085 &code_buffer,1082 &code_buffer,
1086 .none,1083 .none,
1087 maybe_undef_air,
1088 );1084 );
10891085
1090 try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);1086 try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);
...@@ -3123,7 +3119,6 @@ const link = @import("../link.zig");...@@ -3123,7 +3119,6 @@ const link = @import("../link.zig");
3123const target_util = @import("../target.zig");3119const target_util = @import("../target.zig");
3124const trace = @import("../tracy.zig").trace;3120const trace = @import("../tracy.zig").trace;
31253121
3126const Air = @import("../Air.zig");
3127const Compilation = @import("../Compilation.zig");3122const Compilation = @import("../Compilation.zig");
3128const Zcu = @import("../Zcu.zig");3123const Zcu = @import("../Zcu.zig");
3129const InternPool = @import("../InternPool.zig");3124const InternPool = @import("../InternPool.zig");
src/link/Dwarf.zig+157-20
...@@ -1474,17 +1474,18 @@ pub const WipNav = struct {...@@ -1474,17 +1474,18 @@ pub const WipNav = struct {
1474 try cfa.write(wip_nav);1474 try cfa.write(wip_nav);
1475 }1475 }
14761476
1477 pub const LocalTag = enum { local_arg, local_var };1477 pub const LocalVarTag = enum { arg, local_var };
1478 pub fn genLocalDebugInfo(1478 pub fn genLocalVarDebugInfo(
1479 wip_nav: *WipNav,1479 wip_nav: *WipNav,
1480 tag: LocalTag,1480 tag: LocalVarTag,
1481 name: []const u8,1481 name: []const u8,
1482 ty: Type,1482 ty: Type,
1483 loc: Loc,1483 loc: Loc,
1484 ) UpdateError!void {1484 ) UpdateError!void {
1485 assert(wip_nav.func != .none);1485 assert(wip_nav.func != .none);
1486 try wip_nav.abbrevCode(switch (tag) {1486 try wip_nav.abbrevCode(switch (tag) {
1487 inline else => |ct_tag| @field(AbbrevCode, @tagName(ct_tag)),1487 .arg => .arg,
1488 .local_var => .local_var,
1488 });1489 });
1489 try wip_nav.strp(name);1490 try wip_nav.strp(name);
1490 try wip_nav.refType(ty);1491 try wip_nav.refType(ty);
...@@ -1492,6 +1493,40 @@ pub const WipNav = struct {...@@ -1492,6 +1493,40 @@ pub const WipNav = struct {
1492 wip_nav.any_children = true;1493 wip_nav.any_children = true;
1493 }1494 }
14941495
1496 pub const LocalConstTag = enum { comptime_arg, local_const };
1497 pub fn genLocalConstDebugInfo(
1498 wip_nav: *WipNav,
1499 src_loc: Zcu.LazySrcLoc,
1500 tag: LocalConstTag,
1501 name: []const u8,
1502 val: Value,
1503 ) UpdateError!void {
1504 assert(wip_nav.func != .none);
1505 const pt = wip_nav.pt;
1506 const zcu = pt.zcu;
1507 const ty = val.typeOf(zcu);
1508 const has_runtime_bits = ty.hasRuntimeBits(zcu);
1509 const has_comptime_state = ty.comptimeOnly(zcu) and try ty.onePossibleValue(pt) == null;
1510 try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state) switch (tag) {
1511 .comptime_arg => .comptime_arg_runtime_bits_comptime_state,
1512 .local_const => .local_const_runtime_bits_comptime_state,
1513 } else if (has_comptime_state) switch (tag) {
1514 .comptime_arg => .comptime_arg_comptime_state,
1515 .local_const => .local_const_comptime_state,
1516 } else if (has_runtime_bits) switch (tag) {
1517 .comptime_arg => .comptime_arg_runtime_bits,
1518 .local_const => .local_const_runtime_bits,
1519 } else switch (tag) {
1520 .comptime_arg => .comptime_arg,
1521 .local_const => .local_const,
1522 });
1523 try wip_nav.strp(name);
1524 try wip_nav.refType(ty);
1525 if (has_runtime_bits) try wip_nav.blockValue(src_loc, val);
1526 if (has_comptime_state) try wip_nav.refValue(val);
1527 wip_nav.any_children = true;
1528 }
1529
1495 pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void {1530 pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void {
1496 assert(wip_nav.func != .none);1531 assert(wip_nav.func != .none);
1497 try wip_nav.abbrevCode(.is_var_args);1532 try wip_nav.abbrevCode(.is_var_args);
...@@ -1825,7 +1860,8 @@ pub const WipNav = struct {...@@ -1825,7 +1860,8 @@ pub const WipNav = struct {
1825 fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {1860 fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {
1826 const zcu = wip_nav.pt.zcu;1861 const zcu = wip_nav.pt.zcu;
1827 const ip = &zcu.intern_pool;1862 const ip = &zcu.intern_pool;
1828 const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod.?);1863 const nav = ip.getNav(nav_index);
1864 const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?);
1829 const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);1865 const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);
1830 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1866 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1831 const entry = try wip_nav.dwarf.addCommonEntry(unit);1867 const entry = try wip_nav.dwarf.addCommonEntry(unit);
...@@ -1842,10 +1878,16 @@ pub const WipNav = struct {...@@ -1842,10 +1878,16 @@ pub const WipNav = struct {
1842 const zcu = wip_nav.pt.zcu;1878 const zcu = wip_nav.pt.zcu;
1843 const ip = &zcu.intern_pool;1879 const ip = &zcu.intern_pool;
1844 const maybe_inst_index = ty.typeDeclInst(zcu);1880 const maybe_inst_index = ty.typeDeclInst(zcu);
1845 const unit = if (maybe_inst_index) |inst_index|1881 const unit = if (maybe_inst_index) |inst_index| switch (switch (ip.indexToKey(ty.toIntern())) {
1846 try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?)1882 else => unreachable,
1847 else1883 .struct_type => ip.loadStructType(ty.toIntern()).name_nav,
1848 .main;1884 .union_type => ip.loadUnionType(ty.toIntern()).name_nav,
1885 .enum_type => ip.loadEnumType(ty.toIntern()).name_nav,
1886 .opaque_type => ip.loadOpaqueType(ty.toIntern()).name_nav,
1887 }) {
1888 .none => try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?),
1889 else => |name_nav| return wip_nav.getNavEntry(name_nav.unwrap().?),
1890 } else .main;
1849 const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());1891 const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());
1850 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1892 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
1851 const entry = try wip_nav.dwarf.addCommonEntry(unit);1893 const entry = try wip_nav.dwarf.addCommonEntry(unit);
...@@ -1864,10 +1906,8 @@ pub const WipNav = struct {...@@ -1864,10 +1906,8 @@ pub const WipNav = struct {
1864 const ip = &zcu.intern_pool;1906 const ip = &zcu.intern_pool;
1865 const ty = value.typeOf(zcu);1907 const ty = value.typeOf(zcu);
1866 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);1908 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
1867 if (!value.isUndef(zcu)) {1909 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
1868 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());1910 if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
1869 if (ip.isFunctionType(ty.toIntern())) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav);
1870 }
1871 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());1911 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
1872 const unit: Unit.Index = .main;1912 const unit: Unit.Index = .main;
1873 if (gop.found_existing) return .{ unit, gop.value_ptr.* };1913 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
...@@ -1916,7 +1956,10 @@ pub const WipNav = struct {...@@ -1916,7 +1956,10 @@ pub const WipNav = struct {
1916 &wip_nav.debug_info,1956 &wip_nav.debug_info,
1917 .{ .debug_output = .{ .dwarf = wip_nav } },1957 .{ .debug_output = .{ .dwarf = wip_nav } },
1918 );1958 );
1919 assert(old_len + bytes == wip_nav.debug_info.items.len);1959 if (old_len + bytes != wip_nav.debug_info.items.len) {
1960 std.debug.print("{} [{}]: {} != {}\n", .{ ty.fmt(wip_nav.pt), ty.toIntern(), bytes, wip_nav.debug_info.items.len - old_len });
1961 unreachable;
1962 }
1920 }1963 }
19211964
1922 const AbbrevCodeForForm = struct {1965 const AbbrevCodeForForm = struct {
...@@ -2788,6 +2831,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2788,6 +2831,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2788 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2831 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2789 if (type_gop.found_existing) {2832 if (type_gop.found_existing) {
2790 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;2833 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
2834 assert(!nav_gop.found_existing);
2791 nav_gop.value_ptr.* = type_gop.value_ptr.*;2835 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2792 } else {2836 } else {
2793 if (nav_gop.found_existing)2837 if (nav_gop.found_existing)
...@@ -2890,6 +2934,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2890,6 +2934,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2890 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2934 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2891 if (type_gop.found_existing) {2935 if (type_gop.found_existing) {
2892 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;2936 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
2937 assert(!nav_gop.found_existing);
2893 nav_gop.value_ptr.* = type_gop.value_ptr.*;2938 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2894 } else {2939 } else {
2895 if (nav_gop.found_existing)2940 if (nav_gop.found_existing)
...@@ -2928,6 +2973,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2928,6 +2973,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2928 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2973 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2929 if (type_gop.found_existing) {2974 if (type_gop.found_existing) {
2930 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;2975 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
2976 assert(!nav_gop.found_existing);
2931 nav_gop.value_ptr.* = type_gop.value_ptr.*;2977 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2932 } else {2978 } else {
2933 if (nav_gop.found_existing)2979 if (nav_gop.found_existing)
...@@ -2998,6 +3044,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2998,6 +3044,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
2998 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());3044 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2999 if (type_gop.found_existing) {3045 if (type_gop.found_existing) {
3000 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;3046 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
3047 assert(!nav_gop.found_existing);
3001 nav_gop.value_ptr.* = type_gop.value_ptr.*;3048 nav_gop.value_ptr.* = type_gop.value_ptr.*;
3002 } else {3049 } else {
3003 if (nav_gop.found_existing)3050 if (nav_gop.found_existing)
...@@ -3164,6 +3211,7 @@ fn updateLazyType(...@@ -3164,6 +3211,7 @@ fn updateLazyType(
3164) UpdateError!void {3211) UpdateError!void {
3165 const zcu = pt.zcu;3212 const zcu = pt.zcu;
3166 const ip = &zcu.intern_pool;3213 const ip = &zcu.intern_pool;
3214 assert(ip.typeOf(type_index) == .type_type);
3167 const ty: Type = .fromInterned(type_index);3215 const ty: Type = .fromInterned(type_index);
3168 switch (type_index) {3216 switch (type_index) {
3169 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),3217 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),
...@@ -3200,6 +3248,10 @@ fn updateLazyType(...@@ -3200,6 +3248,10 @@ fn updateLazyType(
3200 defer dwarf.gpa.free(name);3248 defer dwarf.gpa.free(name);
32013249
3202 switch (ip.indexToKey(type_index)) {3250 switch (ip.indexToKey(type_index)) {
3251 .undef => {
3252 try wip_nav.abbrevCode(.undefined_comptime_value);
3253 try wip_nav.refType(.type);
3254 },
3203 .int_type => |int_type| {3255 .int_type => |int_type| {
3204 try wip_nav.abbrevCode(.numeric_type);3256 try wip_nav.abbrevCode(.numeric_type);
3205 try wip_nav.strp(name);3257 try wip_nav.strp(name);
...@@ -3633,7 +3685,6 @@ fn updateLazyType(...@@ -3633,7 +3685,6 @@ fn updateLazyType(
3633 },3685 },
36343686
3635 // values, not types3687 // values, not types
3636 .undef,
3637 .simple_value,3688 .simple_value,
3638 .variable,3689 .variable,
3639 .@"extern",3690 .@"extern",
...@@ -3666,7 +3717,11 @@ fn updateLazyValue(...@@ -3666,7 +3717,11 @@ fn updateLazyValue(
3666) UpdateError!void {3717) UpdateError!void {
3667 const zcu = pt.zcu;3718 const zcu = pt.zcu;
3668 const ip = &zcu.intern_pool;3719 const ip = &zcu.intern_pool;
3669 log.debug("updateLazyValue({})", .{Value.fromInterned(value_index).fmtValue(pt)});3720 assert(ip.typeOf(value_index) != .type_type);
3721 log.debug("updateLazyValue(@as({}, {}))", .{
3722 Value.fromInterned(value_index).typeOf(zcu).fmt(pt),
3723 Value.fromInterned(value_index).fmtValue(pt),
3724 });
3670 var wip_nav: WipNav = .{3725 var wip_nav: WipNav = .{
3671 .dwarf = dwarf,3726 .dwarf = dwarf,
3672 .pt = pt,3727 .pt = pt,
...@@ -3710,9 +3765,8 @@ fn updateLazyValue(...@@ -3710,9 +3765,8 @@ fn updateLazyValue(
3710 .inferred_error_set_type,3765 .inferred_error_set_type,
3711 => unreachable, // already handled3766 => unreachable, // already handled
3712 .undef => |ty| {3767 .undef => |ty| {
3713 try wip_nav.abbrevCode(.aggregate_comptime_value);3768 try wip_nav.abbrevCode(.undefined_comptime_value);
3714 try wip_nav.refType(.fromInterned(ty));3769 try wip_nav.refType(.fromInterned(ty));
3715 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3716 },3770 },
3717 .simple_value => unreachable, // opv state3771 .simple_value => unreachable, // opv state
3718 .variable, .@"extern" => unreachable, // not a value3772 .variable, .@"extern" => unreachable, // not a value
...@@ -4890,8 +4944,17 @@ const AbbrevCode = enum {...@@ -4890,8 +4944,17 @@ const AbbrevCode = enum {
4890 block,4944 block,
4891 empty_inlined_func,4945 empty_inlined_func,
4892 inlined_func,4946 inlined_func,
4893 local_arg,4947 arg,
4948 comptime_arg,
4949 comptime_arg_runtime_bits,
4950 comptime_arg_comptime_state,
4951 comptime_arg_runtime_bits_comptime_state,
4894 local_var,4952 local_var,
4953 local_const,
4954 local_const_runtime_bits,
4955 local_const_comptime_state,
4956 local_const_runtime_bits_comptime_state,
4957 undefined_comptime_value,
4895 data2_comptime_value,4958 data2_comptime_value,
4896 data4_comptime_value,4959 data4_comptime_value,
4897 data8_comptime_value,4960 data8_comptime_value,
...@@ -5663,7 +5726,7 @@ const AbbrevCode = enum {...@@ -5663,7 +5726,7 @@ const AbbrevCode = enum {
5663 .{ .high_pc, .data4 },5726 .{ .high_pc, .data4 },
5664 },5727 },
5665 },5728 },
5666 .local_arg = .{5729 .arg = .{
5667 .tag = .formal_parameter,5730 .tag = .formal_parameter,
5668 .attrs = &.{5731 .attrs = &.{
5669 .{ .name, .strp },5732 .{ .name, .strp },
...@@ -5671,6 +5734,42 @@ const AbbrevCode = enum {...@@ -5671,6 +5734,42 @@ const AbbrevCode = enum {
5671 .{ .location, .exprloc },5734 .{ .location, .exprloc },
5672 },5735 },
5673 },5736 },
5737 .comptime_arg = .{
5738 .tag = .formal_parameter,
5739 .attrs = &.{
5740 .{ .const_expr, .flag_present },
5741 .{ .name, .strp },
5742 .{ .type, .ref_addr },
5743 },
5744 },
5745 .comptime_arg_runtime_bits = .{
5746 .tag = .formal_parameter,
5747 .attrs = &.{
5748 .{ .const_expr, .flag_present },
5749 .{ .name, .strp },
5750 .{ .type, .ref_addr },
5751 .{ .const_value, .block },
5752 },
5753 },
5754 .comptime_arg_comptime_state = .{
5755 .tag = .formal_parameter,
5756 .attrs = &.{
5757 .{ .const_expr, .flag_present },
5758 .{ .name, .strp },
5759 .{ .type, .ref_addr },
5760 .{ .ZIG_comptime_value, .ref_addr },
5761 },
5762 },
5763 .comptime_arg_runtime_bits_comptime_state = .{
5764 .tag = .formal_parameter,
5765 .attrs = &.{
5766 .{ .const_expr, .flag_present },
5767 .{ .name, .strp },
5768 .{ .type, .ref_addr },
5769 .{ .const_value, .block },
5770 .{ .ZIG_comptime_value, .ref_addr },
5771 },
5772 },
5674 .local_var = .{5773 .local_var = .{
5675 .tag = .variable,5774 .tag = .variable,
5676 .attrs = &.{5775 .attrs = &.{
...@@ -5679,6 +5778,44 @@ const AbbrevCode = enum {...@@ -5679,6 +5778,44 @@ const AbbrevCode = enum {
5679 .{ .location, .exprloc },5778 .{ .location, .exprloc },
5680 },5779 },
5681 },5780 },
5781 .local_const = .{
5782 .tag = .constant,
5783 .attrs = &.{
5784 .{ .name, .strp },
5785 .{ .type, .ref_addr },
5786 },
5787 },
5788 .local_const_runtime_bits = .{
5789 .tag = .constant,
5790 .attrs = &.{
5791 .{ .name, .strp },
5792 .{ .type, .ref_addr },
5793 .{ .const_value, .block },
5794 },
5795 },
5796 .local_const_comptime_state = .{
5797 .tag = .constant,
5798 .attrs = &.{
5799 .{ .name, .strp },
5800 .{ .type, .ref_addr },
5801 .{ .ZIG_comptime_value, .ref_addr },
5802 },
5803 },
5804 .local_const_runtime_bits_comptime_state = .{
5805 .tag = .constant,
5806 .attrs = &.{
5807 .{ .name, .strp },
5808 .{ .type, .ref_addr },
5809 .{ .const_value, .block },
5810 .{ .ZIG_comptime_value, .ref_addr },
5811 },
5812 },
5813 .undefined_comptime_value = .{
5814 .tag = .ZIG_comptime_value,
5815 .attrs = &.{
5816 .{ .type, .ref_addr },
5817 },
5818 },
5682 .data2_comptime_value = .{5819 .data2_comptime_value = .{
5683 .tag = .ZIG_comptime_value,5820 .tag = .ZIG_comptime_value,
5684 .attrs = &.{5821 .attrs = &.{
src/link/Elf.zig+1-3
...@@ -1683,12 +1683,11 @@ pub fn updateFunc(...@@ -1683,12 +1683,11 @@ pub fn updateFunc(
1683 pt: Zcu.PerThread,1683 pt: Zcu.PerThread,
1684 func_index: InternPool.Index,1684 func_index: InternPool.Index,
1685 mir: *const codegen.AnyMir,1685 mir: *const codegen.AnyMir,
1686 maybe_undef_air: *const Air,
1687) link.File.UpdateNavError!void {1686) link.File.UpdateNavError!void {
1688 if (build_options.skip_non_native and builtin.object_format != .elf) {1687 if (build_options.skip_non_native and builtin.object_format != .elf) {
1689 @panic("Attempted to compile for object format that was disabled by build configuration");1688 @panic("Attempted to compile for object format that was disabled by build configuration");
1690 }1689 }
1691 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir, maybe_undef_air);1690 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir);
1692}1691}
16931692
1694pub fn updateNav(1693pub fn updateNav(
...@@ -4516,7 +4515,6 @@ const trace = @import("../tracy.zig").trace;...@@ -4516,7 +4515,6 @@ const trace = @import("../tracy.zig").trace;
4516const synthetic_sections = @import("Elf/synthetic_sections.zig");4515const synthetic_sections = @import("Elf/synthetic_sections.zig");
45174516
4518const Merge = @import("Elf/Merge.zig");4517const Merge = @import("Elf/Merge.zig");
4519const Air = @import("../Air.zig");
4520const Archive = @import("Elf/Archive.zig");4518const Archive = @import("Elf/Archive.zig");
4521const AtomList = @import("Elf/AtomList.zig");4519const AtomList = @import("Elf/AtomList.zig");
4522const Compilation = @import("../Compilation.zig");4520const Compilation = @import("../Compilation.zig");
src/link/Elf/ZigObject.zig-5
...@@ -1417,9 +1417,6 @@ pub fn updateFunc(...@@ -1417,9 +1417,6 @@ pub fn updateFunc(
1417 pt: Zcu.PerThread,1417 pt: Zcu.PerThread,
1418 func_index: InternPool.Index,1418 func_index: InternPool.Index,
1419 mir: *const codegen.AnyMir,1419 mir: *const codegen.AnyMir,
1420 /// This may be `undefined`; only pass it to `emitFunction`.
1421 /// This parameter will eventually be removed.
1422 maybe_undef_air: *const Air,
1423) link.File.UpdateNavError!void {1420) link.File.UpdateNavError!void {
1424 const tracy = trace(@src());1421 const tracy = trace(@src());
1425 defer tracy.end();1422 defer tracy.end();
...@@ -1448,7 +1445,6 @@ pub fn updateFunc(...@@ -1448,7 +1445,6 @@ pub fn updateFunc(
1448 mir,1445 mir,
1449 &code_buffer,1446 &code_buffer,
1450 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,1447 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
1451 maybe_undef_air,
1452 );1448 );
1453 const code = code_buffer.items;1449 const code = code_buffer.items;
14541450
...@@ -2363,7 +2359,6 @@ const trace = @import("../../tracy.zig").trace;...@@ -2363,7 +2359,6 @@ const trace = @import("../../tracy.zig").trace;
2363const std = @import("std");2359const std = @import("std");
2364const Allocator = std.mem.Allocator;2360const Allocator = std.mem.Allocator;
23652361
2366const Air = @import("../../Air.zig");
2367const Archive = @import("Archive.zig");2362const Archive = @import("Archive.zig");
2368const Atom = @import("Atom.zig");2363const Atom = @import("Atom.zig");
2369const Dwarf = @import("../Dwarf.zig");2364const Dwarf = @import("../Dwarf.zig");
src/link/Goff.zig-3
...@@ -17,7 +17,6 @@ const codegen = @import("../codegen.zig");...@@ -17,7 +17,6 @@ const codegen = @import("../codegen.zig");
17const link = @import("../link.zig");17const link = @import("../link.zig");
18const trace = @import("../tracy.zig").trace;18const trace = @import("../tracy.zig").trace;
19const build_options = @import("build_options");19const build_options = @import("build_options");
20const Air = @import("../Air.zig");
2120
22base: link.File,21base: link.File,
2322
...@@ -74,13 +73,11 @@ pub fn updateFunc(...@@ -74,13 +73,11 @@ pub fn updateFunc(
74 pt: Zcu.PerThread,73 pt: Zcu.PerThread,
75 func_index: InternPool.Index,74 func_index: InternPool.Index,
76 mir: *const codegen.AnyMir,75 mir: *const codegen.AnyMir,
77 maybe_undef_air: *const Air,
78) link.File.UpdateNavError!void {76) link.File.UpdateNavError!void {
79 _ = self;77 _ = self;
80 _ = pt;78 _ = pt;
81 _ = func_index;79 _ = func_index;
82 _ = mir;80 _ = mir;
83 _ = maybe_undef_air;
84 unreachable; // we always use llvm81 unreachable; // we always use llvm
85}82}
8683
src/link/MachO.zig+1-3
...@@ -3040,12 +3040,11 @@ pub fn updateFunc(...@@ -3040,12 +3040,11 @@ pub fn updateFunc(
3040 pt: Zcu.PerThread,3040 pt: Zcu.PerThread,
3041 func_index: InternPool.Index,3041 func_index: InternPool.Index,
3042 mir: *const codegen.AnyMir,3042 mir: *const codegen.AnyMir,
3043 maybe_undef_air: *const Air,
3044) link.File.UpdateNavError!void {3043) link.File.UpdateNavError!void {
3045 if (build_options.skip_non_native and builtin.object_format != .macho) {3044 if (build_options.skip_non_native and builtin.object_format != .macho) {
3046 @panic("Attempted to compile for object format that was disabled by build configuration");3045 @panic("Attempted to compile for object format that was disabled by build configuration");
3047 }3046 }
3048 return self.getZigObject().?.updateFunc(self, pt, func_index, mir, maybe_undef_air);3047 return self.getZigObject().?.updateFunc(self, pt, func_index, mir);
3049}3048}
30503049
3051pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {3050pub 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");...@@ -5431,7 +5430,6 @@ const target_util = @import("../target.zig");
5431const trace = @import("../tracy.zig").trace;5430const trace = @import("../tracy.zig").trace;
5432const synthetic = @import("MachO/synthetic.zig");5431const synthetic = @import("MachO/synthetic.zig");
54335432
5434const Air = @import("../Air.zig");
5435const Alignment = Atom.Alignment;5433const Alignment = Atom.Alignment;
5436const Allocator = mem.Allocator;5434const Allocator = mem.Allocator;
5437const Archive = @import("MachO/Archive.zig");5435const Archive = @import("MachO/Archive.zig");
src/link/MachO/ZigObject.zig-5
...@@ -778,9 +778,6 @@ pub fn updateFunc(...@@ -778,9 +778,6 @@ pub fn updateFunc(
778 pt: Zcu.PerThread,778 pt: Zcu.PerThread,
779 func_index: InternPool.Index,779 func_index: InternPool.Index,
780 mir: *const codegen.AnyMir,780 mir: *const codegen.AnyMir,
781 /// This may be `undefined`; only pass it to `emitFunction`.
782 /// This parameter will eventually be removed.
783 maybe_undef_air: *const Air,
784) link.File.UpdateNavError!void {781) link.File.UpdateNavError!void {
785 const tracy = trace(@src());782 const tracy = trace(@src());
786 defer tracy.end();783 defer tracy.end();
...@@ -806,7 +803,6 @@ pub fn updateFunc(...@@ -806,7 +803,6 @@ pub fn updateFunc(
806 mir,803 mir,
807 &code_buffer,804 &code_buffer,
808 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,805 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
809 maybe_undef_air,
810 );806 );
811 const code = code_buffer.items;807 const code = code_buffer.items;
812808
...@@ -1815,7 +1811,6 @@ const target_util = @import("../../target.zig");...@@ -1815,7 +1811,6 @@ const target_util = @import("../../target.zig");
1815const trace = @import("../../tracy.zig").trace;1811const trace = @import("../../tracy.zig").trace;
1816const std = @import("std");1812const std = @import("std");
18171813
1818const Air = @import("../../Air.zig");
1819const Allocator = std.mem.Allocator;1814const Allocator = std.mem.Allocator;
1820const Archive = @import("Archive.zig");1815const Archive = @import("Archive.zig");
1821const Atom = @import("Atom.zig");1816const Atom = @import("Atom.zig");
src/link/Plan9.zig-4
...@@ -387,9 +387,6 @@ pub fn updateFunc(...@@ -387,9 +387,6 @@ pub fn updateFunc(
387 pt: Zcu.PerThread,387 pt: Zcu.PerThread,
388 func_index: InternPool.Index,388 func_index: InternPool.Index,
389 mir: *const codegen.AnyMir,389 mir: *const codegen.AnyMir,
390 /// This may be `undefined`; only pass it to `emitFunction`.
391 /// This parameter will eventually be removed.
392 maybe_undef_air: *const Air,
393) link.File.UpdateNavError!void {390) link.File.UpdateNavError!void {
394 if (build_options.skip_non_native and builtin.object_format != .plan9) {391 if (build_options.skip_non_native and builtin.object_format != .plan9) {
395 @panic("Attempted to compile for object format that was disabled by build configuration");392 @panic("Attempted to compile for object format that was disabled by build configuration");
...@@ -422,7 +419,6 @@ pub fn updateFunc(...@@ -422,7 +419,6 @@ pub fn updateFunc(
422 mir,419 mir,
423 &code_buffer,420 &code_buffer,
424 .{ .plan9 = &dbg_info_output },421 .{ .plan9 = &dbg_info_output },
425 maybe_undef_air,
426 );422 );
427 const code = try code_buffer.toOwnedSlice(gpa);423 const code = try code_buffer.toOwnedSlice(gpa);
428 self.getAtomPtr(atom_idx).code = .{424 self.getAtomPtr(atom_idx).code = .{
src/link/Wasm.zig-3
...@@ -29,7 +29,6 @@ const leb = std.leb;...@@ -29,7 +29,6 @@ const leb = std.leb;
29const log = std.log.scoped(.link);29const log = std.log.scoped(.link);
30const mem = std.mem;30const mem = std.mem;
3131
32const Air = @import("../Air.zig");
33const Mir = @import("../arch/wasm/Mir.zig");32const Mir = @import("../arch/wasm/Mir.zig");
34const CodeGen = @import("../arch/wasm/CodeGen.zig");33const CodeGen = @import("../arch/wasm/CodeGen.zig");
35const abi = @import("../arch/wasm/abi.zig");34const abi = @import("../arch/wasm/abi.zig");
...@@ -3182,14 +3181,12 @@ pub fn updateFunc(...@@ -3182,14 +3181,12 @@ pub fn updateFunc(
3182 pt: Zcu.PerThread,3181 pt: Zcu.PerThread,
3183 func_index: InternPool.Index,3182 func_index: InternPool.Index,
3184 any_mir: *const codegen.AnyMir,3183 any_mir: *const codegen.AnyMir,
3185 maybe_undef_air: *const Air,
3186) !void {3184) !void {
3187 if (build_options.skip_non_native and builtin.object_format != .wasm) {3185 if (build_options.skip_non_native and builtin.object_format != .wasm) {
3188 @panic("Attempted to compile for object format that was disabled by build configuration");3186 @panic("Attempted to compile for object format that was disabled by build configuration");
3189 }3187 }
31903188
3191 dev.check(.wasm_backend);3189 dev.check(.wasm_backend);
3192 _ = maybe_undef_air; // we (correctly) do not need this
31933190
3194 // This linker implementation only works with codegen backend `.stage2_wasm`.3191 // This linker implementation only works with codegen backend `.stage2_wasm`.
3195 const mir = &any_mir.wasm;3192 const mir = &any_mir.wasm;
src/link/Xcoff.zig-3
...@@ -17,7 +17,6 @@ const codegen = @import("../codegen.zig");...@@ -17,7 +17,6 @@ const codegen = @import("../codegen.zig");
17const link = @import("../link.zig");17const link = @import("../link.zig");
18const trace = @import("../tracy.zig").trace;18const trace = @import("../tracy.zig").trace;
19const build_options = @import("build_options");19const build_options = @import("build_options");
20const Air = @import("../Air.zig");
2120
22base: link.File,21base: link.File,
2322
...@@ -74,13 +73,11 @@ pub fn updateFunc(...@@ -74,13 +73,11 @@ pub fn updateFunc(
74 pt: Zcu.PerThread,73 pt: Zcu.PerThread,
75 func_index: InternPool.Index,74 func_index: InternPool.Index,
76 mir: *const codegen.AnyMir,75 mir: *const codegen.AnyMir,
77 maybe_undef_air: *const Air,
78) link.File.UpdateNavError!void {76) link.File.UpdateNavError!void {
79 _ = self;77 _ = self;
80 _ = pt;78 _ = pt;
81 _ = func_index;79 _ = func_index;
82 _ = mir;80 _ = mir;
83 _ = maybe_undef_air;
84 unreachable; // we always use llvm81 unreachable; // we always use llvm
85}82}
8683