From 89ba8859704486d526a75434f18d5a25ff89d57b Mon Sep 17 00:00:00 2001 From: mlugg Date: Tue, 3 Jun 2025 22:42:10 +0100 Subject: [PATCH] spirv: make the backend compile again Unfortunately, the self-hosted SPIR-V backend is quite tightly coupled with the self-hosted SPIR-V linker through its `Object` concept (which is much like `llvm.Object`). Reworking this would be too much work for this branch. So, for now, I have introduced a special case (similar to the LLVM backend's special case) to the codegen logic when using this backend. We will want to delete this special case at some point, but it need not block this work. --- src/Zcu/PerThread.zig | 16 ++++++++++++++++ src/codegen/spirv.zig | 6 +++--- src/link.zig | 2 +- src/link/SpirV.zig | 18 ------------------ src/target.zig | 2 +- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 6475649a681d51665f44cf824acd4dbb129ee1b1..ffc103310b04a713ec39c8f3c832dd23422b4d77 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -4461,6 +4461,22 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e } const lf = comp.bin_file orelse return error.NoLinkFile; + + // TODO: self-hosted codegen should always have a type of MIR; codegen should produce that MIR, + // and the linker should consume it. However, our SPIR-V backend is currently tightly coupled + // with our SPIR-V linker, so needs to work more like the LLVM backend. This should be fixed to + // unblock threaded codegen for SPIR-V. + if (lf.cast(.spirv)) |spirv_file| { + assert(pt.tid == .main); // SPIR-V has a lot of shared state + spirv_file.object.updateFunc(pt, func_index, air, &liveness) catch |err| { + switch (err) { + error.OutOfMemory => comp.link_diags.setAllocFailure(), + } + return error.CodegenFail; + }; + return error.BackendDoesNotProduceMir; + } + return codegen.generateFunction(lf, pt, zcu.navSrcLoc(nav), func_index, air, &liveness) catch |err| switch (err) { error.OutOfMemory, error.CodegenFail, diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index e6c06d9f20fe167358098c3ce4f297940ebf111d..b9eb56dd23761a37343fd2f9eae71a4d36c1aef5 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -250,12 +250,12 @@ pub const Object = struct { self: *Object, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + air: *const Air, + liveness: *const Air.Liveness, ) !void { const nav = pt.zcu.funcInfo(func_index).owner_nav; // TODO: Separate types for generating decls and functions? - try self.genNav(pt, nav, air, liveness, true); + try self.genNav(pt, nav, air.*, liveness.*, true); } pub fn updateNav( diff --git a/src/link.zig b/src/link.zig index f49acbf3d6114643863a934b3e08f27d35c49bc1..577d7ba82c33bc157a629c32912fcf615ad56389 100644 --- a/src/link.zig +++ b/src/link.zig @@ -758,8 +758,8 @@ pub const File = struct { assert(base.comp.zcu.?.llvm_object == null); switch (base.tag) { .lld => unreachable, + .spirv => unreachable, // see corresponding special case in `Zcu.PerThread.runCodegenInner` inline else => |tag| { - 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/SpirV.zig b/src/link/SpirV.zig index 8b6b99525f03e0d1e24dcbcca3ed01e011dd8880..bafefccfc0e4a5eb78c889399adc8ced64e9ddce 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -111,24 +111,6 @@ pub fn deinit(self: *SpirV) void { self.object.deinit(); } -pub fn updateFunc( - self: *SpirV, - pt: Zcu.PerThread, - func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, -) link.File.UpdateNavError!void { - if (build_options.skip_non_native) { - @panic("Attempted to compile for architecture that was disabled by build configuration"); - } - - const ip = &pt.zcu.intern_pool; - const func = pt.zcu.funcInfo(func_index); - log.debug("lowering function {}", .{ip.getNav(func.owner_nav).name.fmt(ip)}); - - try self.object.updateFunc(pt, func_index, air, liveness); -} - pub fn updateNav(self: *SpirV, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { if (build_options.skip_non_native) { @panic("Attempted to compile for architecture that was disabled by build configuration"); diff --git a/src/target.zig b/src/target.zig index a408c82c14228ac57510732c8f1547dbc9cec2d0..02e64670d0b933c7b50069c3e35cae83c995f040 100644 --- a/src/target.zig +++ b/src/target.zig @@ -850,8 +850,8 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt }, .separate_thread => switch (backend) { .stage2_llvm => false, - // MLUGG TODO .stage2_c, .stage2_wasm => true, + // TODO: most self-hosted backends should be able to support this without too much work. else => false, }, }; -- 2.54.0