authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-29 17:42:49+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-30 19:43:36+02:00
logf13a6ee19edb756977e7ef83aa7a7d9b155427eb
treea479d5211d666faa5f1a6b7728472b54ff708323
parente05ace76736a8500b6ffdcd2748d1cd22e3354fe
signaturelock-open Commit is signed but in an unrecognized format.

spirv: cache pointers


2 files changed, 105 insertions(+), 1 deletions(-)

src/codegen/spirv.zig+14
......@@ -1331,6 +1331,20 @@ pub const DeclGen = struct {
13311331 return try self.sizeType2();
13321332 },
13331333 },
1334 .Pointer => {
1335 const ptr_info = ty.ptrInfo().data;
1336
1337 const storage_class = spvStorageClass(ptr_info.@"addrspace");
1338 const child_ty_ref = try self.resolveType2(ptr_info.pointee_type, .indirect);
1339 const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{
1340 .storage_class = storage_class,
1341 .child_type = child_ty_ref,
1342 } });
1343 if (ptr_info.size != .Slice) {
1344 return ptr_ty_ref;
1345 }
1346 unreachable; // TODO
1347 },
13341348
13351349 else => unreachable, // TODO
13361350 }
src/codegen/spirv/TypeConstantCache.zig+91-1
......@@ -19,6 +19,7 @@ const Module = @import("Module.zig");
1919const spec = @import("spec.zig");
2020const Opcode = spec.Opcode;
2121const IdResult = spec.IdResult;
22const StorageClass = spec.StorageClass;
2223
2324const Self = @This();
2425
......@@ -54,9 +55,21 @@ const Tag = enum {
5455 /// Array type
5556 /// data is payload to ArrayType
5657 type_array,
57 /// Function (proto)type.
58 /// Function (proto)type
5859 /// data is payload to FunctionType
5960 type_function,
61 /// Pointer type in the CrossWorkgroup storage class
62 /// data is child type
63 type_ptr_generic,
64 /// Pointer type in the CrossWorkgroup storage class
65 /// data is child type
66 type_ptr_crosswgp,
67 /// Pointer type in the Function storage class
68 /// data is child type
69 type_ptr_function,
70 /// Simple pointer type that does not have any decorations.
71 /// data is SimplePointerType
72 type_ptr_simple,
6073
6174 // -- Values
6275 /// Value of type u8
......@@ -100,6 +113,11 @@ const Tag = enum {
100113 return_type: Ref,
101114 };
102115
116 const SimplePointerType = struct {
117 storage_class: StorageClass,
118 child_type: Ref,
119 };
120
103121 const Float64 = struct {
104122 // Low-order 32 bits of the value.
105123 low: u32,
......@@ -182,6 +200,7 @@ pub const Key = union(enum) {
182200 vector_type: VectorType,
183201 array_type: ArrayType,
184202 function_type: FunctionType,
203 ptr_type: PointerType,
185204
186205 // -- values
187206 int: Int,
......@@ -210,6 +229,15 @@ pub const Key = union(enum) {
210229 parameters: []const Ref,
211230 };
212231
232 pub const PointerType = struct {
233 storage_class: StorageClass,
234 child_type: Ref,
235 // TODO: Decorations:
236 // - Alignment
237 // - ArrayStride,
238 // - MaxByteOffset,
239 };
240
213241 pub const Int = struct {
214242 /// The type: any bitness integer.
215243 ty: Ref,
......@@ -406,6 +434,14 @@ fn emit(
406434 section.writeOperand(IdResult, self.resultId(param_type));
407435 }
408436 },
437 .ptr_type => |ptr| {
438 try section.emit(spv.gpa, .OpTypePointer, .{
439 .id_result = result_id,
440 .storage_class = ptr.storage_class,
441 .type = self.resultId(ptr.child_type),
442 });
443 // TODO: Decorations?
444 },
409445 .int => |int| {
410446 const int_type = self.lookup(int.ty).int_type;
411447 const ty_id = self.resultId(int.ty);
......@@ -491,6 +527,31 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref {
491527 .data = extra,
492528 };
493529 },
530 .ptr_type => |ptr| switch (ptr.storage_class) {
531 .Generic => Item{
532 .tag = .type_ptr_generic,
533 .result_id = result_id,
534 .data = @enumToInt(ptr.child_type),
535 },
536 .CrossWorkgroup => Item{
537 .tag = .type_ptr_crosswgp,
538 .result_id = result_id,
539 .data = @enumToInt(ptr.child_type),
540 },
541 .Function => Item{
542 .tag = .type_ptr_function,
543 .result_id = result_id,
544 .data = @enumToInt(ptr.child_type),
545 },
546 else => |storage_class| Item{
547 .tag = .type_ptr_simple,
548 .result_id = result_id,
549 .data = try self.addExtra(spv, Tag.SimplePointerType{
550 .storage_class = storage_class,
551 .child_type = ptr.child_type,
552 }),
553 },
554 },
494555 .int => |int| blk: {
495556 const int_type = self.lookup(int.ty).int_type;
496557 if (int_type.signedness == .unsigned and int_type.bits == 8) {
......@@ -599,6 +660,33 @@ pub fn lookup(self: *const Self, ref: Ref) Key {
599660 },
600661 };
601662 },
663 .type_ptr_generic => .{
664 .ptr_type = .{
665 .storage_class = .Generic,
666 .child_type = @intToEnum(Ref, data),
667 },
668 },
669 .type_ptr_crosswgp => .{
670 .ptr_type = .{
671 .storage_class = .CrossWorkgroup,
672 .child_type = @intToEnum(Ref, data),
673 },
674 },
675 .type_ptr_function => .{
676 .ptr_type = .{
677 .storage_class = .Function,
678 .child_type = @intToEnum(Ref, data),
679 },
680 },
681 .type_ptr_simple => {
682 const payload = self.extraData(Tag.SimplePointerType, data);
683 return .{
684 .ptr_type = .{
685 .storage_class = payload.storage_class,
686 .child_type = payload.child_type,
687 },
688 };
689 },
602690 .float16 => .{ .float = .{
603691 .ty = self.get(.{ .float_type = .{ .bits = 16 } }),
604692 .value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },
......@@ -677,6 +765,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 {
677765 u32 => field_val,
678766 i32 => @bitCast(u32, field_val),
679767 Ref => @enumToInt(field_val),
768 StorageClass => @enumToInt(field_val),
680769 else => @compileError("Invalid type: " ++ @typeName(field.type)),
681770 };
682771 self.extra.appendAssumeCapacity(word);
......@@ -697,6 +786,7 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t
697786 u32 => word,
698787 i32 => @bitCast(i32, word),
699788 Ref => @intToEnum(Ref, word),
789 StorageClass => @intToEnum(StorageClass, word),
700790 else => @compileError("Invalid type: " ++ @typeName(field.type)),
701791 };
702792 }