diff --git a/src/Compilation.zig b/src/Compilation.zig index 64ec1ab0a8..e967935539 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -4550,8 +4550,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { air.deinit(gpa); return; } - const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); - defer pt.deactivate(); const shared_mir = try gpa.create(link.ZcuTask.LinkFunc.SharedMir); shared_mir.* = .{ .status = .init(.pending), @@ -4567,7 +4565,11 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { } }); } else { const emit_needs_air = !zcu.backendSupportsFeature(.separate_thread); - pt.runCodegen(func.func, &air, shared_mir); + { + const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); + defer pt.deactivate(); + pt.runCodegen(func.func, &air, shared_mir); + } assert(shared_mir.status.load(.monotonic) != .pending); comp.dispatchZcuLinkTask(tid, .{ .link_func = .{ .func = func.func, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 92f1adbf2a..6475649a68 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -4376,26 +4376,40 @@ pub fn addDependency(pt: Zcu.PerThread, unit: AnalUnit, dependee: InternPool.Dep /// other code. This function is currently run either on the main thread, or on a separate /// codegen thread, depending on whether the backend supports `Zcu.Feature.separate_thread`. pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air, out: *@import("../link.zig").ZcuTask.LinkFunc.SharedMir) void { + const zcu = pt.zcu; if (runCodegenInner(pt, func_index, air)) |mir| { out.value = mir; out.status.store(.ready, .release); } else |err| switch (err) { error.OutOfMemory => { - pt.zcu.comp.setAllocFailure(); + zcu.comp.setAllocFailure(); out.status.store(.failed, .monotonic); }, error.CodegenFail => { - pt.zcu.assertCodegenFailed(pt.zcu.funcInfo(func_index).owner_nav); + zcu.assertCodegenFailed(zcu.funcInfo(func_index).owner_nav); out.status.store(.failed, .monotonic); }, error.NoLinkFile => { - assert(pt.zcu.comp.bin_file == null); + assert(zcu.comp.bin_file == null); + out.status.store(.failed, .monotonic); + }, + error.BackendDoesNotProduceMir => { + const backend = target_util.zigBackend(zcu.root_mod.resolved_target.result, zcu.comp.config.use_llvm); + switch (backend) { + else => unreachable, // assertion failure + .stage2_llvm => {}, + } out.status.store(.failed, .monotonic); }, } - pt.zcu.comp.link_task_queue.mirReady(pt.zcu.comp, out); + zcu.comp.link_task_queue.mirReady(zcu.comp, out); } -fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{ OutOfMemory, CodegenFail, NoLinkFile }!codegen.AnyMir { +fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{ + OutOfMemory, + CodegenFail, + NoLinkFile, + BackendDoesNotProduceMir, +}!codegen.AnyMir { const zcu = pt.zcu; const gpa = zcu.gpa; const ip = &zcu.intern_pool; @@ -4441,7 +4455,9 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e // "emit" step because LLVM does not support incremental linking. Our linker (LLD or self-hosted) // will just see the ZCU object file which LLVM ultimately emits. if (zcu.llvm_object) |llvm_object| { - return llvm_object.updateFunc(pt, func_index, air, &liveness); + assert(pt.tid == .main); // LLVM has a lot of shared state + try llvm_object.updateFunc(pt, func_index, air, &liveness); + return error.BackendDoesNotProduceMir; } const lf = comp.bin_file orelse return error.NoLinkFile; diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 00cceb0c67..0c29fd96e2 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -49,7 +49,6 @@ pt: Zcu.PerThread, air: Air, liveness: Air.Liveness, bin_file: *link.File, -debug_output: link.File.DebugInfoOutput, target: *const std.Target, func_index: InternPool.Index, owner_nav: InternPool.Nav.Index, @@ -185,6 +184,9 @@ const DbgInfoReloc = struct { } fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !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; switch (function.debug_output) { .dwarf => |dw| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -213,6 +215,9 @@ const DbgInfoReloc = struct { } fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !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; switch (function.debug_output) { .dwarf => |dwarf| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -326,11 +331,9 @@ pub fn generate( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, - code: *std.ArrayListUnmanaged(u8), - debug_output: link.File.DebugInfoOutput, -) CodeGenError!void { + air: *const Air, + liveness: *const Air.Liveness, +) CodeGenError!Mir { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); @@ -349,9 +352,8 @@ pub fn generate( var function: Self = .{ .gpa = gpa, .pt = pt, - .air = air, - .liveness = liveness, - .debug_output = debug_output, + .air = air.*, + .liveness = liveness.*, .target = target, .bin_file = lf, .func_index = func_index, @@ -395,29 +397,13 @@ pub fn generate( var mir: Mir = .{ .instructions = function.mir_instructions.toOwnedSlice(), - .extra = try function.mir_extra.toOwnedSlice(gpa), - }; - defer mir.deinit(gpa); - - var emit: Emit = .{ - .mir = mir, - .bin_file = lf, - .debug_output = debug_output, - .target = target, - .src_loc = src_loc, - .code = code, - .prev_di_pc = 0, - .prev_di_line = func.lbrace_line, - .prev_di_column = func.lbrace_column, - .stack_size = function.max_end_stack, + .extra = &.{}, // fallible, so assign after errdefer + .max_end_stack = function.max_end_stack, .saved_regs_stack_space = function.saved_regs_stack_space, }; - defer emit.deinit(); - - emit.emitMir() catch |err| switch (err) { - error.EmitFail => return function.failMsg(emit.err_msg.?), - else => |e| return e, - }; + errdefer mir.deinit(gpa); + mir.extra = try function.mir_extra.toOwnedSlice(gpa); + return mir; } fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { diff --git a/src/arch/aarch64/Mir.zig b/src/arch/aarch64/Mir.zig index edf05f625e..34fcc64c7e 100644 --- a/src/arch/aarch64/Mir.zig +++ b/src/arch/aarch64/Mir.zig @@ -13,6 +13,14 @@ const assert = std.debug.assert; const bits = @import("bits.zig"); const Register = bits.Register; +const InternPool = @import("../../InternPool.zig"); +const Emit = @import("Emit.zig"); +const codegen = @import("../../codegen.zig"); +const link = @import("../../link.zig"); +const Zcu = @import("../../Zcu.zig"); + +max_end_stack: u32, +saved_regs_stack_space: u32, instructions: std.MultiArrayList(Inst).Slice, /// The meaning of this data is determined by `Inst.Tag` value. @@ -498,6 +506,41 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { mir.* = undefined; } +pub fn emit( + mir: Mir, + lf: *link.File, + pt: Zcu.PerThread, + src_loc: Zcu.LazySrcLoc, + 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; + const mod = zcu.navFileScope(nav).mod.?; + var e: Emit = .{ + .mir = mir, + .bin_file = lf, + .debug_output = debug_output, + .target = &mod.resolved_target.result, + .src_loc = src_loc, + .code = code, + .prev_di_pc = 0, + .prev_di_line = func.lbrace_line, + .prev_di_column = func.lbrace_column, + .stack_size = mir.max_end_stack, + .saved_regs_stack_space = mir.saved_regs_stack_space, + }; + defer e.deinit(); + e.emitMir() catch |err| switch (err) { + error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?), + else => |e1| return e1, + }; +} + /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } { diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 421ba7d753..3868011557 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -50,7 +50,6 @@ pt: Zcu.PerThread, air: Air, liveness: Air.Liveness, bin_file: *link.File, -debug_output: link.File.DebugInfoOutput, target: *const std.Target, func_index: InternPool.Index, err_msg: ?*ErrorMsg, @@ -264,6 +263,9 @@ const DbgInfoReloc = struct { } fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !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; switch (function.debug_output) { .dwarf => |dw| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -292,6 +294,9 @@ const DbgInfoReloc = struct { } fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !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; switch (function.debug_output) { .dwarf => |dw| { const loc: link.File.Dwarf.Loc = switch (reloc.mcv) { @@ -335,11 +340,9 @@ pub fn generate( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, - code: *std.ArrayListUnmanaged(u8), - debug_output: link.File.DebugInfoOutput, -) CodeGenError!void { + air: *const Air, + liveness: *const Air.Liveness, +) CodeGenError!Mir { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); @@ -358,11 +361,10 @@ pub fn generate( var function: Self = .{ .gpa = gpa, .pt = pt, - .air = air, - .liveness = liveness, + .air = air.*, + .liveness = liveness.*, .target = target, .bin_file = lf, - .debug_output = debug_output, .func_index = func_index, .err_msg = null, .args = undefined, // populated after `resolveCallingConventionValues` @@ -402,31 +404,15 @@ pub fn generate( return function.fail("failed to generate debug info: {s}", .{@errorName(err)}); } - var mir = Mir{ + var mir: Mir = .{ .instructions = function.mir_instructions.toOwnedSlice(), - .extra = try function.mir_extra.toOwnedSlice(gpa), - }; - defer mir.deinit(gpa); - - var emit = Emit{ - .mir = mir, - .bin_file = lf, - .debug_output = debug_output, - .target = target, - .src_loc = src_loc, - .code = code, - .prev_di_pc = 0, - .prev_di_line = func.lbrace_line, - .prev_di_column = func.lbrace_column, - .stack_size = function.max_end_stack, + .extra = &.{}, // fallible, so assign after errdefer + .max_end_stack = function.max_end_stack, .saved_regs_stack_space = function.saved_regs_stack_space, }; - defer emit.deinit(); - - emit.emitMir() catch |err| switch (err) { - error.EmitFail => return function.failMsg(emit.err_msg.?), - else => |e| return e, - }; + errdefer mir.deinit(gpa); + mir.extra = try function.mir_extra.toOwnedSlice(gpa); + return mir; } fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { diff --git a/src/arch/arm/Mir.zig b/src/arch/arm/Mir.zig index 5e651b7939..0366663eae 100644 --- a/src/arch/arm/Mir.zig +++ b/src/arch/arm/Mir.zig @@ -13,6 +13,14 @@ const assert = std.debug.assert; const bits = @import("bits.zig"); const Register = bits.Register; +const InternPool = @import("../../InternPool.zig"); +const Emit = @import("Emit.zig"); +const codegen = @import("../../codegen.zig"); +const link = @import("../../link.zig"); +const Zcu = @import("../../Zcu.zig"); + +max_end_stack: u32, +saved_regs_stack_space: u32, instructions: std.MultiArrayList(Inst).Slice, /// The meaning of this data is determined by `Inst.Tag` value. @@ -278,6 +286,41 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { mir.* = undefined; } +pub fn emit( + mir: Mir, + lf: *link.File, + pt: Zcu.PerThread, + src_loc: Zcu.LazySrcLoc, + 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; + const mod = zcu.navFileScope(nav).mod.?; + var e: Emit = .{ + .mir = mir, + .bin_file = lf, + .debug_output = debug_output, + .target = &mod.resolved_target.result, + .src_loc = src_loc, + .code = code, + .prev_di_pc = 0, + .prev_di_line = func.lbrace_line, + .prev_di_column = func.lbrace_column, + .stack_size = mir.max_end_stack, + .saved_regs_stack_space = mir.saved_regs_stack_space, + }; + defer e.deinit(); + e.emitMir() catch |err| switch (err) { + error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?), + else => |e1| return e1, + }; +} + /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } { diff --git a/src/arch/powerpc/CodeGen.zig b/src/arch/powerpc/CodeGen.zig index 0cfee67ebd..4964fe19f4 100644 --- a/src/arch/powerpc/CodeGen.zig +++ b/src/arch/powerpc/CodeGen.zig @@ -19,19 +19,15 @@ pub fn generate( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, - code: *std.ArrayListUnmanaged(u8), - debug_output: link.File.DebugInfoOutput, -) codegen.CodeGenError!void { + air: *const Air, + liveness: *const Air.Liveness, +) codegen.CodeGenError!noreturn { _ = bin_file; _ = pt; _ = src_loc; _ = func_index; _ = air; _ = liveness; - _ = code; - _ = debug_output; unreachable; } diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 9fc51bd2d3..9b5e0ed69b 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -68,7 +68,6 @@ gpa: Allocator, mod: *Package.Module, target: *const std.Target, -debug_output: link.File.DebugInfoOutput, args: []MCValue, ret_mcv: InstTracking, fn_type: Type, @@ -746,13 +745,10 @@ pub fn generate( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, - code: *std.ArrayListUnmanaged(u8), - debug_output: link.File.DebugInfoOutput, -) CodeGenError!void { + air: *const Air, + liveness: *const Air.Liveness, +) CodeGenError!Mir { const zcu = pt.zcu; - const comp = zcu.comp; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const func = zcu.funcInfo(func_index); @@ -769,13 +765,12 @@ pub fn generate( var function: Func = .{ .gpa = gpa, - .air = air, + .air = air.*, .pt = pt, .mod = mod, .bin_file = bin_file, - .liveness = liveness, + .liveness = liveness.*, .target = &mod.resolved_target.result, - .debug_output = debug_output, .owner = .{ .nav_index = func.owner_nav }, .args = undefined, // populated after `resolveCallingConventionValues` .ret_mcv = undefined, // populated after `resolveCallingConventionValues` @@ -855,33 +850,8 @@ pub fn generate( .instructions = function.mir_instructions.toOwnedSlice(), .frame_locs = function.frame_locs.toOwnedSlice(), }; - defer mir.deinit(gpa); - - var emit: Emit = .{ - .lower = .{ - .pt = pt, - .allocator = gpa, - .mir = mir, - .cc = fn_info.cc, - .src_loc = src_loc, - .output_mode = comp.config.output_mode, - .link_mode = comp.config.link_mode, - .pic = mod.pic, - }, - .bin_file = bin_file, - .debug_output = debug_output, - .code = code, - .prev_di_pc = 0, - .prev_di_line = func.lbrace_line, - .prev_di_column = func.lbrace_column, - }; - defer emit.deinit(); - - emit.emitMir() catch |err| switch (err) { - error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), - error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}), - else => |e| return e, - }; + errdefer mir.deinit(gpa); + return mir; } pub fn generateLazy( @@ -904,7 +874,6 @@ pub fn generateLazy( .bin_file = bin_file, .liveness = undefined, .target = &mod.resolved_target.result, - .debug_output = debug_output, .owner = .{ .lazy_sym = lazy_sym }, .args = undefined, // populated after `resolveCallingConventionValues` .ret_mcv = undefined, // populated after `resolveCallingConventionValues` @@ -4760,6 +4729,9 @@ fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerErr const ty = arg.ty.toType(); if (arg.name == .none) return; + // 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; switch (func.debug_output) { .dwarf => |dw| switch (mcv) { .register => |reg| dw.genLocalDebugInfo( @@ -5273,6 +5245,9 @@ fn genVarDbgInfo( mcv: MCValue, name: []const u8, ) !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; switch (func.debug_output) { .dwarf => |dwarf| { const loc: link.File.Dwarf.Loc = switch (mcv) { diff --git a/src/arch/riscv64/Mir.zig b/src/arch/riscv64/Mir.zig index 2ae62fd9b2..eef3fe7511 100644 --- a/src/arch/riscv64/Mir.zig +++ b/src/arch/riscv64/Mir.zig @@ -109,6 +109,50 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { mir.* = undefined; } +pub fn emit( + mir: Mir, + lf: *link.File, + pt: Zcu.PerThread, + src_loc: Zcu.LazySrcLoc, + 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; + const func = zcu.funcInfo(func_index); + const fn_info = zcu.typeToFunc(.fromInterned(func.ty)).?; + const nav = func.owner_nav; + const mod = zcu.navFileScope(nav).mod.?; + var e: Emit = .{ + .lower = .{ + .pt = pt, + .allocator = gpa, + .mir = mir, + .cc = fn_info.cc, + .src_loc = src_loc, + .output_mode = comp.config.output_mode, + .link_mode = comp.config.link_mode, + .pic = mod.pic, + }, + .bin_file = lf, + .debug_output = debug_output, + .code = code, + .prev_di_pc = 0, + .prev_di_line = func.lbrace_line, + .prev_di_column = func.lbrace_column, + }; + defer e.deinit(); + e.emitMir() catch |err| switch (err) { + error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, e.lower.err_msg.?), + error.InvalidInstruction => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}), + else => |err1| return err1, + }; +} + pub const FrameLoc = struct { base: Register, disp: i32, @@ -202,3 +246,9 @@ const FrameIndex = bits.FrameIndex; const FrameAddr = @import("CodeGen.zig").FrameAddr; const IntegerBitSet = std.bit_set.IntegerBitSet; const Mnemonic = @import("mnem.zig").Mnemonic; + +const InternPool = @import("../../InternPool.zig"); +const Emit = @import("Emit.zig"); +const codegen = @import("../../codegen.zig"); +const link = @import("../../link.zig"); +const Zcu = @import("../../Zcu.zig"); diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index ad9884dcdb..180aaedd3c 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -57,8 +57,6 @@ liveness: Air.Liveness, bin_file: *link.File, target: *const std.Target, func_index: InternPool.Index, -code: *std.ArrayListUnmanaged(u8), -debug_output: link.File.DebugInfoOutput, err_msg: ?*ErrorMsg, args: []MCValue, ret_mcv: MCValue, @@ -268,11 +266,9 @@ pub fn generate( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, - code: *std.ArrayListUnmanaged(u8), - debug_output: link.File.DebugInfoOutput, -) CodeGenError!void { + air: *const Air, + liveness: *const Air.Liveness, +) CodeGenError!Mir { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); @@ -291,13 +287,11 @@ pub fn generate( var function: Self = .{ .gpa = gpa, .pt = pt, - .air = air, - .liveness = liveness, + .air = air.*, + .liveness = liveness.*, .target = target, .bin_file = lf, .func_index = func_index, - .code = code, - .debug_output = debug_output, .err_msg = null, .args = undefined, // populated after `resolveCallingConventionValues` .ret_mcv = undefined, // populated after `resolveCallingConventionValues` @@ -330,29 +324,13 @@ pub fn generate( else => |e| return e, }; - var mir = Mir{ + var mir: Mir = .{ .instructions = function.mir_instructions.toOwnedSlice(), - .extra = try function.mir_extra.toOwnedSlice(gpa), - }; - defer mir.deinit(gpa); - - var emit: Emit = .{ - .mir = mir, - .bin_file = lf, - .debug_output = debug_output, - .target = target, - .src_loc = src_loc, - .code = code, - .prev_di_pc = 0, - .prev_di_line = func.lbrace_line, - .prev_di_column = func.lbrace_column, - }; - defer emit.deinit(); - - emit.emitMir() catch |err| switch (err) { - error.EmitFail => return function.failMsg(emit.err_msg.?), - else => |e| return e, + .extra = &.{}, // fallible, so populated after errdefer }; + errdefer mir.deinit(gpa); + mir.extra = try function.mir_extra.toOwnedSlice(gpa); + return mir; } fn gen(self: *Self) !void { @@ -3566,6 +3544,9 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { const ty = arg.ty.toType(); if (arg.name == .none) return; + // 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; switch (self.debug_output) { .dwarf => |dw| switch (mcv) { .register => |reg| try dw.genLocalDebugInfo( diff --git a/src/arch/sparc64/Mir.zig b/src/arch/sparc64/Mir.zig index e9086db7a5..26c5c3267b 100644 --- a/src/arch/sparc64/Mir.zig +++ b/src/arch/sparc64/Mir.zig @@ -12,7 +12,11 @@ const assert = std.debug.assert; const Mir = @This(); const bits = @import("bits.zig"); -const Air = @import("../../Air.zig"); +const InternPool = @import("../../InternPool.zig"); +const Emit = @import("Emit.zig"); +const codegen = @import("../../codegen.zig"); +const link = @import("../../link.zig"); +const Zcu = @import("../../Zcu.zig"); const Instruction = bits.Instruction; const ASI = bits.Instruction.ASI; @@ -370,6 +374,39 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { mir.* = undefined; } +pub fn emit( + mir: Mir, + lf: *link.File, + pt: Zcu.PerThread, + src_loc: Zcu.LazySrcLoc, + 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; + const mod = zcu.navFileScope(nav).mod.?; + var e: Emit = .{ + .mir = mir, + .bin_file = lf, + .debug_output = debug_output, + .target = &mod.resolved_target.result, + .src_loc = src_loc, + .code = code, + .prev_di_pc = 0, + .prev_di_line = func.lbrace_line, + .prev_di_column = func.lbrace_column, + }; + defer e.deinit(); + e.emitMir() catch |err| switch (err) { + error.EmitFail => return zcu.codegenFailMsg(nav, e.err_msg.?), + else => |err1| return err1, + }; +} + /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } { diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b38492d500..1d95c8db77 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -125,7 +125,6 @@ pt: Zcu.PerThread, air: Air, liveness: Air.Liveness, bin_file: *link.File, -debug_output: link.File.DebugInfoOutput, target: *const std.Target, owner: Owner, inline_func: InternPool.Index, @@ -972,13 +971,10 @@ pub fn generate( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, - code: *std.ArrayListUnmanaged(u8), - debug_output: link.File.DebugInfoOutput, -) codegen.CodeGenError!void { + air: *const Air, + liveness: *const Air.Liveness, +) codegen.CodeGenError!Mir { const zcu = pt.zcu; - const comp = zcu.comp; const gpa = zcu.gpa; const ip = &zcu.intern_pool; const func = zcu.funcInfo(func_index); @@ -988,12 +984,11 @@ pub fn generate( var function: CodeGen = .{ .gpa = gpa, .pt = pt, - .air = air, - .liveness = liveness, + .air = air.*, + .liveness = liveness.*, .target = &mod.resolved_target.result, .mod = mod, .bin_file = bin_file, - .debug_output = debug_output, .owner = .{ .nav_index = func.owner_nav }, .inline_func = func_index, .arg_index = undefined, @@ -1090,7 +1085,7 @@ pub fn generate( }; // Drop them off at the rbrace. - if (debug_output != .none) _ = try function.addInst(.{ + if (!mod.strip) _ = try function.addInst(.{ .tag = .pseudo, .ops = .pseudo_dbg_line_line_column, .data = .{ .line_column = .{ @@ -1100,49 +1095,17 @@ pub fn generate( }); 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, - .cc = fn_info.cc, - .src_loc = src_loc, - .output_mode = comp.config.output_mode, - .link_mode = comp.config.link_mode, - .pic = mod.pic, - }, - .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) { - error.CodegenFail => return error.CodegenFail, - else => |e| return e, - }, - .debug_output = debug_output, - .code = code, - .prev_di_loc = .{ - .line = func.lbrace_line, - .column = func.lbrace_column, - .is_stmt = switch (debug_output) { - .dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt, - .plan9 => undefined, - .none => undefined, - }, - }, - .prev_di_pc = 0, - }; - emit.emitMir() catch |err| switch (err) { - error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?), - - error.InvalidInstruction, error.CannotEncode => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}), - else => |e| return function.fail("emit MIR failed: {s}", .{@errorName(e)}), + .instructions = .empty, + .extra = &.{}, + .table = &.{}, + .frame_locs = .empty, }; + errdefer mir.deinit(gpa); + mir.instructions = function.mir_instructions.toOwnedSlice(); + mir.extra = try function.mir_extra.toOwnedSlice(gpa); + mir.table = try function.mir_table.toOwnedSlice(gpa); + mir.frame_locs = function.frame_locs.toOwnedSlice(); + return mir; } pub fn generateLazy( @@ -1165,7 +1128,6 @@ pub fn generateLazy( .target = &mod.resolved_target.result, .mod = mod, .bin_file = bin_file, - .debug_output = debug_output, .owner = .{ .lazy_sym = lazy_sym }, .inline_func = undefined, .arg_index = undefined, @@ -2339,7 +2301,7 @@ fn gen(self: *CodeGen) InnerError!void { else => |cc| return self.fail("{s} does not support var args", .{@tagName(cc)}), }; - if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_prologue_end_none); + if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none); try self.genBody(self.air.getMainBody()); @@ -2356,7 +2318,7 @@ fn gen(self: *CodeGen) InnerError!void { } for (self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc); - if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none); + if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none); const backpatch_stack_dealloc = try self.asmPlaceholder(); const backpatch_pop_callee_preserved_regs = try self.asmPlaceholder(); try self.asmRegister(.{ ._, .pop }, .rbp); @@ -2475,9 +2437,9 @@ fn gen(self: *CodeGen) InnerError!void { }); } } else { - if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_prologue_end_none); + if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none); try self.genBody(self.air.getMainBody()); - if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none); + if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none); } } @@ -2498,9 +2460,9 @@ fn checkInvariantsAfterAirInst(self: *CodeGen) void { } fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void { - if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_enter_block_none); + if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_enter_block_none); try self.genBody(body); - if (self.debug_output != .none) try self.asmPseudo(.pseudo_dbg_leave_block_none); + if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_leave_block_none); } fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { @@ -2544,7 +2506,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.debug_output != .none) { + .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; @@ -64179,9 +64141,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .block => { const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; const block = cg.air.extraData(Air.Block, ty_pl.payload); - if (cg.debug_output != .none) try cg.asmPseudo(.pseudo_dbg_enter_block_none); + if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_enter_block_none); try cg.lowerBlock(inst, @ptrCast(cg.air.extra.items[block.end..][0..block.data.body_len])); - if (cg.debug_output != .none) try cg.asmPseudo(.pseudo_dbg_leave_block_none); + if (!cg.mod.strip) try cg.asmPseudo(.pseudo_dbg_leave_block_none); }, .loop => if (use_old) try cg.airLoop(inst) else { const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; @@ -85191,7 +85153,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .switch_dispatch => try cg.airSwitchDispatch(inst), .@"try", .try_cold => try cg.airTry(inst), .try_ptr, .try_ptr_cold => try cg.airTryPtr(inst), - .dbg_stmt => if (cg.debug_output != .none) { + .dbg_stmt => if (!cg.mod.strip) { const dbg_stmt = air_datas[@intFromEnum(inst)].dbg_stmt; _ = try cg.addInst(.{ .tag = .pseudo, @@ -85202,7 +85164,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { } }, }); }, - .dbg_empty_stmt => if (cg.debug_output != .none) { + .dbg_empty_stmt => if (!cg.mod.strip) { if (cg.mir_instructions.len > 0) { const prev_mir_op = &cg.mir_instructions.items(.ops)[cg.mir_instructions.len - 1]; if (prev_mir_op.* == .pseudo_dbg_line_line_column) @@ -85216,13 +85178,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { const old_inline_func = cg.inline_func; defer cg.inline_func = old_inline_func; cg.inline_func = dbg_inline_block.data.func; - if (cg.debug_output != .none) _ = try cg.addInst(.{ + if (!cg.mod.strip) _ = try cg.addInst(.{ .tag = .pseudo, .ops = .pseudo_dbg_enter_inline_func, .data = .{ .func = 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.debug_output != .none) _ = try cg.addInst(.{ + if (!cg.mod.strip) _ = try cg.addInst(.{ .tag = .pseudo, .ops = .pseudo_dbg_leave_inline_func, .data = .{ .func = old_inline_func }, @@ -85231,7 +85193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline, - => if (use_old) try cg.airDbgVar(inst) else if (cg.debug_output != .none) { + => 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; @@ -173366,7 +173328,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void { while (self.args[arg_index] == .none) arg_index += 1; self.arg_index = arg_index + 1; - const result: MCValue = if (self.debug_output == .none and self.liveness.isUnused(inst)) .unreach else result: { + 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) { @@ -173468,7 +173430,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void { } fn airDbgVarArgs(self: *CodeGen) !void { - if (self.debug_output == .none) return; + 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); } @@ -173478,7 +173440,7 @@ fn genLocalDebugInfo( inst: Air.Inst.Index, mcv: MCValue, ) !void { - if (self.debug_output == .none) return; + if (self.mod.strip) return; switch (self.air.instructions.items(.tag)[@intFromEnum(inst)]) { else => unreachable, .arg, .dbg_arg_inline, .dbg_var_val => |tag| { diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 8d202e6bae..14468677af 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -1929,6 +1929,67 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { mir.* = undefined; } +pub fn emit( + mir: Mir, + lf: *link.File, + pt: Zcu.PerThread, + src_loc: Zcu.LazySrcLoc, + 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; + const gpa = comp.gpa; + const func = zcu.funcInfo(func_index); + const fn_info = zcu.typeToFunc(.fromInterned(func.ty)).?; + 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, + .allocator = gpa, + .mir = mir, + .cc = fn_info.cc, + .src_loc = src_loc, + .output_mode = comp.config.output_mode, + .link_mode = comp.config.link_mode, + .pic = mod.pic, + }, + .atom_index = sym: { + if (lf.cast(.elf)) |ef| break :sym try ef.zigObjectPtr().?.getOrCreateMetadataForNav(zcu, nav); + if (lf.cast(.macho)) |mf| break :sym try mf.getZigObject().?.getOrCreateMetadataForNav(mf, nav); + if (lf.cast(.coff)) |cf| { + const atom = try cf.getOrCreateAtomForNav(nav); + break :sym cf.getAtom(atom).getSymbolIndex().?; + } + if (lf.cast(.plan9)) |p9f| break :sym try p9f.seeNav(pt, nav); + unreachable; + }, + .debug_output = debug_output, + .code = code, + .prev_di_loc = .{ + .line = func.lbrace_line, + .column = func.lbrace_column, + .is_stmt = switch (debug_output) { + .dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt, + .plan9 => undefined, + .none => undefined, + }, + }, + .prev_di_pc = 0, + }; + e.emitMir() catch |err| switch (err) { + error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, e.lower.err_msg.?), + error.InvalidInstruction, error.CannotEncode => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}), + else => return zcu.codegenFail(nav, "emit MIR failed: {s}", .{@errorName(err)}), + }; +} + pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: u32 } { const fields = std.meta.fields(T); var i: u32 = index; @@ -1987,3 +2048,7 @@ const IntegerBitSet = std.bit_set.IntegerBitSet; const InternPool = @import("../../InternPool.zig"); const Mir = @This(); const Register = bits.Register; +const Emit = @import("Emit.zig"); +const codegen = @import("../../codegen.zig"); +const link = @import("../../link.zig"); +const Zcu = @import("../../Zcu.zig"); diff --git a/src/codegen.zig b/src/codegen.zig index 2c2524257c..ea57aaf89c 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -182,7 +182,7 @@ pub fn emitFunction( /// 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, -) Allocator.Error!void { +) CodeGenError!void { const zcu = pt.zcu; const func = zcu.funcInfo(func_index); const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index 98d4a42f91..d90ba974fc 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -985,7 +985,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { assert(comp.freebsd_so_files == null); comp.freebsd_so_files = so_files; - var task_buffer: [libs.len]link.Task = undefined; + var task_buffer: [libs.len]link.PrelinkTask = undefined; var task_buffer_i: usize = 0; { diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig index c1146d933d..ed5eae377f 100644 --- a/src/libs/glibc.zig +++ b/src/libs/glibc.zig @@ -1148,7 +1148,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { assert(comp.glibc_so_files == null); comp.glibc_so_files = so_files; - var task_buffer: [libs.len]link.Task = undefined; + var task_buffer: [libs.len]link.PrelinkTask = undefined; var task_buffer_i: usize = 0; { diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig index aab75cce49..7121c308f5 100644 --- a/src/libs/netbsd.zig +++ b/src/libs/netbsd.zig @@ -650,7 +650,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { assert(comp.netbsd_so_files == null); comp.netbsd_so_files = so_files; - var task_buffer: [libs.len]link.Task = undefined; + var task_buffer: [libs.len]link.PrelinkTask = undefined; var task_buffer_i: usize = 0; { diff --git a/src/link.zig b/src/link.zig index 31fd0a4a4e..838654775d 100644 --- a/src/link.zig +++ b/src/link.zig @@ -759,6 +759,8 @@ pub const File = struct { switch (base.tag) { .lld => unreachable, inline else => |tag| { + if (tag == .wasm) @panic("MLUGG TODO"); + if (tag == .spirv) @panic("MLUGG TODO"); dev.check(tag.devFeature()); return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir, maybe_undef_air); }, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 9a040754ef..bb8faf583d 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1057,8 +1057,10 @@ pub fn updateFunc( coff: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + 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"); @@ -1079,15 +1081,15 @@ pub fn updateFunc( var code_buffer: std.ArrayListUnmanaged(u8) = .empty; defer code_buffer.deinit(gpa); - try codegen.generateFunction( + try codegen.emitFunction( &coff.base, pt, zcu.navSrcLoc(nav_index), func_index, - air, - liveness, + mir, &code_buffer, .none, + maybe_undef_air, ); try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION); diff --git a/src/link/Goff.zig b/src/link/Goff.zig index 28da184495..d0c2b8e80b 100644 --- a/src/link/Goff.zig +++ b/src/link/Goff.zig @@ -13,6 +13,7 @@ const Path = std.Build.Cache.Path; const Zcu = @import("../Zcu.zig"); const InternPool = @import("../InternPool.zig"); const Compilation = @import("../Compilation.zig"); +const codegen = @import("../codegen.zig"); const link = @import("../link.zig"); const trace = @import("../tracy.zig").trace; const build_options = @import("build_options"); @@ -72,14 +73,14 @@ pub fn updateFunc( self: *Goff, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + mir: *const codegen.AnyMir, + maybe_undef_air: *const Air, ) link.File.UpdateNavError!void { _ = self; _ = pt; _ = func_index; - _ = air; - _ = liveness; + _ = mir; + _ = maybe_undef_air; unreachable; // we always use llvm } diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2c30b34215..8fd85df0a3 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3051,13 +3051,13 @@ pub fn updateFunc( self: *MachO, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + 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, air, liveness); + return self.getZigObject().?.updateFunc(self, pt, func_index, mir, maybe_undef_air); } pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 13ebb40cf9..f378a9c410 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -777,8 +777,10 @@ pub fn updateFunc( macho_file: *MachO, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + 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(); @@ -796,15 +798,15 @@ pub fn updateFunc( var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null; defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit(); - try codegen.generateFunction( + try codegen.emitFunction( &macho_file.base, pt, zcu.navSrcLoc(func.owner_nav), func_index, - air, - liveness, + mir, &code_buffer, if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, + maybe_undef_air, ); const code = code_buffer.items; diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index c487169b3f..0d0699f0f0 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -386,8 +386,10 @@ pub fn updateFunc( self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + 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"); @@ -412,15 +414,15 @@ pub fn updateFunc( }; defer dbg_info_output.dbg_line.deinit(); - try codegen.generateFunction( + try codegen.emitFunction( &self.base, pt, zcu.navSrcLoc(func.owner_nav), func_index, - air, - liveness, + 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/Queue.zig b/src/link/Queue.zig index c73a0e9684..3436be5921 100644 --- a/src/link/Queue.zig +++ b/src/link/Queue.zig @@ -97,8 +97,7 @@ pub fn mirReady(q: *Queue, comp: *Compilation, mir: *ZcuTask.LinkFunc.SharedMir) q.mutex.lock(); defer q.mutex.unlock(); switch (q.state) { - .finished => unreachable, // there's definitely a task queued - .running => return, + .finished, .running => return, .wait_for_mir => |wait_for| if (wait_for != mir) return, } // We were waiting for `mir`, so we will restart the linker thread. diff --git a/src/link/Xcoff.zig b/src/link/Xcoff.zig index 7fe714ce6e..97ea300ed2 100644 --- a/src/link/Xcoff.zig +++ b/src/link/Xcoff.zig @@ -13,6 +13,7 @@ const Path = std.Build.Cache.Path; const Zcu = @import("../Zcu.zig"); const InternPool = @import("../InternPool.zig"); const Compilation = @import("../Compilation.zig"); +const codegen = @import("../codegen.zig"); const link = @import("../link.zig"); const trace = @import("../tracy.zig").trace; const build_options = @import("build_options"); @@ -72,14 +73,14 @@ pub fn updateFunc( self: *Xcoff, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + mir: *const codegen.AnyMir, + maybe_undef_air: *const Air, ) link.File.UpdateNavError!void { _ = self; _ = pt; _ = func_index; - _ = air; - _ = liveness; + _ = mir; + _ = maybe_undef_air; unreachable; // we always use llvm }