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