authorgravatar for me@brianferri.devBrian Ferri <me@brianferri.dev> 2026-10-03 00:10:06+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-06 04:18:28+02:00
log44dce00408af3da922d35765393a6265ece44284
tree8a594bfa53dfa42b935d6fe306ac78f2cf0e3b6d
parent3c8e94f7e7e8814f0c19f5fa54efd7a865841e7b
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

spirv: build derived pointer types only where they are used


1 files changed, 15 insertions(+), 13 deletions(-)

src/codegen/spirv/CodeGen.zig+15-13
......@@ -1684,6 +1684,13 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id {
16841684 return cg.derivePtr(ptr_val.typeOf(zcu).ptrAddressSpace(zcu), derivation);
16851685}
16861686
1687/// Emits the pointer type that one step of a pointer derivation results in, along with its
1688/// pointee type. A derivation is the sequence of steps that builds a comptime-known pointer: a
1689/// base address, such as a declaration, an anonymous value or an integer, followed by field,
1690/// element and cast steps, each of which is lowered on its own.
1691/// This function emits instructions on every call, and they stay in the module whether or not they
1692/// are read, so it should only be called where the resulting type is used: a buffer struct emitted
1693/// without `Block` fails validation even when nothing refers to it.
16871694fn derivedPtrType(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id {
16881695 return cg.ptrType(
16891696 try cg.pointeeType(@"addrspace", derivation.elem_ty, false),
......@@ -1696,13 +1703,6 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu
16961703 const zcu = cg.zcu;
16971704 const target = zcu.getTarget();
16981705
1699 // A variable on Vulkan and OpenGL is used through its own pointer, so a `nav` resolves this only
1700 // where it is used; a type emitted and left unused stays in the module.
1701 const result_ty_id = switch (derivation.addr) {
1702 .nav => undefined,
1703 else => try cg.derivedPtrType(@"addrspace", derivation),
1704 };
1705
17061706 switch (derivation.addr) {
17071707 .comptime_alloc, .comptime_field => unreachable,
17081708 .int => |int| {
......@@ -1717,6 +1717,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu
17171717 // TODO: This can probably be an OpSpecConstantOp Bitcast, but
17181718 // that is not implemented by Mesa yet. Therefore, just generate it
17191719 // as a runtime operation.
1720 const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation);
17201721 const result_ptr_id = cg.allocId();
17211722 const value_id = try cg.constInt(.usize, int);
17221723 try cg.body.emit(gpa, .OpConvertUToPtr, .{
......@@ -1759,12 +1760,12 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu
17591760
17601761 const nav_ty_id = try cg.resolveType(nav_ty, .indirect);
17611762 const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, cg.storageClass(as));
1762 const nav_result_ty_id = try cg.derivedPtrType(@"addrspace", derivation);
1763 if (decl_ptr_ty_id == nav_result_ty_id) return var_id;
1763 const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation);
1764 if (decl_ptr_ty_id == result_ty_id) return var_id;
17641765
17651766 const casted_ptr_id = cg.allocId();
17661767 try cg.body.emit(gpa, .OpBitcast, .{
1767 .id_result_type = nav_result_ty_id,
1768 .id_result_type = result_ty_id,
17681769 .id_result = casted_ptr_id,
17691770 .operand = var_id,
17701771 });
......@@ -1781,7 +1782,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu
17811782 }
17821783
17831784 if (!uav_ty.hasRuntimeBits(zcu) and uav_ty.zigTypeTag(zcu) != .spirv) {
1784 return cg.constUndef(result_ty_id);
1785 return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation));
17851786 }
17861787
17871788 if (cg.storageClass(@"addrspace") != .function) {
......@@ -1798,7 +1799,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu
17981799 .opt_payload => @panic("TODO"),
17991800 .field => |derived| return cg.structFieldPtr(
18001801 @"addrspace",
1801 result_ty_id,
1802 try cg.derivedPtrType(@"addrspace", derivation),
18021803 derivation.elem_ty,
18031804 derived.parent.elem_ty,
18041805 try cg.derivePtr(@"addrspace", derived.parent.*),
......@@ -1850,12 +1851,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu
18501851 const zero = try cg.constInt(.u32, 0);
18511852 const ids = try cg.id_scratch.addManyAsSlice(gpa, depth);
18521853 @memset(ids, zero);
1853 return cg.accessChainId(result_ty_id, parent_ptr_id, ids);
1854 return cg.accessChainId(try cg.derivedPtrType(@"addrspace", derivation), parent_ptr_id, ids);
18541855 } else {
18551856 return parent_ptr_id;
18561857 }
18571858 }
18581859 if (target.os.tag == .opencl) {
1860 const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation);
18591861 const result_ptr_id = cg.allocId();
18601862 try cg.body.emit(gpa, .OpBitcast, .{
18611863 .id_result_type = result_ty_id,