authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-03 22:42:10+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-12 13:55:40+01:00
log89ba8859704486d526a75434f18d5a25ff89d57b
treeda2ee8131619f320818ae99778d270c8589f17cb
parentc0df70706695a67089d4e691d3d3a0f77b90298f
signaturelock-open Commit is signed but in an unrecognized format.

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.

5 files changed, 21 insertions(+), 23 deletions(-)

src/Zcu/PerThread.zig+16
......@@ -4461,6 +4461,22 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
44614461 }
44624462
44634463 const lf = comp.bin_file orelse return error.NoLinkFile;
4464
4465 // TODO: self-hosted codegen should always have a type of MIR; codegen should produce that MIR,
4466 // and the linker should consume it. However, our SPIR-V backend is currently tightly coupled
4467 // with our SPIR-V linker, so needs to work more like the LLVM backend. This should be fixed to
4468 // unblock threaded codegen for SPIR-V.
4469 if (lf.cast(.spirv)) |spirv_file| {
4470 assert(pt.tid == .main); // SPIR-V has a lot of shared state
4471 spirv_file.object.updateFunc(pt, func_index, air, &liveness) catch |err| {
4472 switch (err) {
4473 error.OutOfMemory => comp.link_diags.setAllocFailure(),
4474 }
4475 return error.CodegenFail;
4476 };
4477 return error.BackendDoesNotProduceMir;
4478 }
4479
44644480 return codegen.generateFunction(lf, pt, zcu.navSrcLoc(nav), func_index, air, &liveness) catch |err| switch (err) {
44654481 error.OutOfMemory,
44664482 error.CodegenFail,
src/codegen/spirv.zig+3-3
......@@ -250,12 +250,12 @@ pub const Object = struct {
250250 self: *Object,
251251 pt: Zcu.PerThread,
252252 func_index: InternPool.Index,
253 air: Air,
254 liveness: Air.Liveness,
253 air: *const Air,
254 liveness: *const Air.Liveness,
255255 ) !void {
256256 const nav = pt.zcu.funcInfo(func_index).owner_nav;
257257 // TODO: Separate types for generating decls and functions?
258 try self.genNav(pt, nav, air, liveness, true);
258 try self.genNav(pt, nav, air.*, liveness.*, true);
259259 }
260260
261261 pub fn updateNav(
src/link.zig+1-1
......@@ -758,8 +758,8 @@ pub const File = struct {
758758 assert(base.comp.zcu.?.llvm_object == null);
759759 switch (base.tag) {
760760 .lld => unreachable,
761 .spirv => unreachable, // see corresponding special case in `Zcu.PerThread.runCodegenInner`
761762 inline else => |tag| {
762 if (tag == .spirv) @panic("MLUGG TODO");
763763 dev.check(tag.devFeature());
764764 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, mir, maybe_undef_air);
765765 },
src/link/SpirV.zig-18
......@@ -111,24 +111,6 @@ pub fn deinit(self: *SpirV) void {
111111 self.object.deinit();
112112}
113113
114pub fn updateFunc(
115 self: *SpirV,
116 pt: Zcu.PerThread,
117 func_index: InternPool.Index,
118 air: Air,
119 liveness: Air.Liveness,
120) link.File.UpdateNavError!void {
121 if (build_options.skip_non_native) {
122 @panic("Attempted to compile for architecture that was disabled by build configuration");
123 }
124
125 const ip = &pt.zcu.intern_pool;
126 const func = pt.zcu.funcInfo(func_index);
127 log.debug("lowering function {}", .{ip.getNav(func.owner_nav).name.fmt(ip)});
128
129 try self.object.updateFunc(pt, func_index, air, liveness);
130}
131
132114pub fn updateNav(self: *SpirV, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
133115 if (build_options.skip_non_native) {
134116 @panic("Attempted to compile for architecture that was disabled by build configuration");
src/target.zig+1-1
......@@ -850,8 +850,8 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
850850 },
851851 .separate_thread => switch (backend) {
852852 .stage2_llvm => false,
853 // MLUGG TODO
854853 .stage2_c, .stage2_wasm => true,
854 // TODO: most self-hosted backends should be able to support this without too much work.
855855 else => false,
856856 },
857857 };