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
signature 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 {...@@ -1331,6 +1331,20 @@ pub const DeclGen = struct {
1331 return try self.sizeType2();1331 return try self.sizeType2();
1332 },1332 },
1333 },1333 },
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
1335 else => unreachable, // TODO1349 else => unreachable, // TODO
1336 }1350 }
src/codegen/spirv/TypeConstantCache.zig+91-1
...@@ -19,6 +19,7 @@ const Module = @import("Module.zig");...@@ -19,6 +19,7 @@ const Module = @import("Module.zig");
19const spec = @import("spec.zig");19const spec = @import("spec.zig");
20const Opcode = spec.Opcode;20const Opcode = spec.Opcode;
21const IdResult = spec.IdResult;21const IdResult = spec.IdResult;
22const StorageClass = spec.StorageClass;
2223
23const Self = @This();24const Self = @This();
2425
...@@ -54,9 +55,21 @@ const Tag = enum {...@@ -54,9 +55,21 @@ const Tag = enum {
54 /// Array type55 /// Array type
55 /// data is payload to ArrayType56 /// data is payload to ArrayType
56 type_array,57 type_array,
57 /// Function (proto)type.58 /// Function (proto)type
58 /// data is payload to FunctionType59 /// data is payload to FunctionType
59 type_function,60 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
61 // -- Values74 // -- Values
62 /// Value of type u875 /// Value of type u8
...@@ -100,6 +113,11 @@ const Tag = enum {...@@ -100,6 +113,11 @@ const Tag = enum {
100 return_type: Ref,113 return_type: Ref,
101 };114 };
102115
116 const SimplePointerType = struct {
117 storage_class: StorageClass,
118 child_type: Ref,
119 };
120
103 const Float64 = struct {121 const Float64 = struct {
104 // Low-order 32 bits of the value.122 // Low-order 32 bits of the value.
105 low: u32,123 low: u32,
...@@ -182,6 +200,7 @@ pub const Key = union(enum) {...@@ -182,6 +200,7 @@ pub const Key = union(enum) {
182 vector_type: VectorType,200 vector_type: VectorType,
183 array_type: ArrayType,201 array_type: ArrayType,
184 function_type: FunctionType,202 function_type: FunctionType,
203 ptr_type: PointerType,
185204
186 // -- values205 // -- values
187 int: Int,206 int: Int,
...@@ -210,6 +229,15 @@ pub const Key = union(enum) {...@@ -210,6 +229,15 @@ pub const Key = union(enum) {
210 parameters: []const Ref,229 parameters: []const Ref,
211 };230 };
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
213 pub const Int = struct {241 pub const Int = struct {
214 /// The type: any bitness integer.242 /// The type: any bitness integer.
215 ty: Ref,243 ty: Ref,
...@@ -406,6 +434,14 @@ fn emit(...@@ -406,6 +434,14 @@ fn emit(
406 section.writeOperand(IdResult, self.resultId(param_type));434 section.writeOperand(IdResult, self.resultId(param_type));
407 }435 }
408 },436 },
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 },
409 .int => |int| {445 .int => |int| {
410 const int_type = self.lookup(int.ty).int_type;446 const int_type = self.lookup(int.ty).int_type;
411 const ty_id = self.resultId(int.ty);447 const ty_id = self.resultId(int.ty);
...@@ -491,6 +527,31 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref {...@@ -491,6 +527,31 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref {
491 .data = extra,527 .data = extra,
492 };528 };
493 },529 },
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 },
494 .int => |int| blk: {555 .int => |int| blk: {
495 const int_type = self.lookup(int.ty).int_type;556 const int_type = self.lookup(int.ty).int_type;
496 if (int_type.signedness == .unsigned and int_type.bits == 8) {557 if (int_type.signedness == .unsigned and int_type.bits == 8) {
...@@ -599,6 +660,33 @@ pub fn lookup(self: *const Self, ref: Ref) Key {...@@ -599,6 +660,33 @@ pub fn lookup(self: *const Self, ref: Ref) Key {
599 },660 },
600 };661 };
601 },662 },
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 },
602 .float16 => .{ .float = .{690 .float16 => .{ .float = .{
603 .ty = self.get(.{ .float_type = .{ .bits = 16 } }),691 .ty = self.get(.{ .float_type = .{ .bits = 16 } }),
604 .value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },692 .value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },
...@@ -677,6 +765,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 {...@@ -677,6 +765,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 {
677 u32 => field_val,765 u32 => field_val,
678 i32 => @bitCast(u32, field_val),766 i32 => @bitCast(u32, field_val),
679 Ref => @enumToInt(field_val),767 Ref => @enumToInt(field_val),
768 StorageClass => @enumToInt(field_val),
680 else => @compileError("Invalid type: " ++ @typeName(field.type)),769 else => @compileError("Invalid type: " ++ @typeName(field.type)),
681 };770 };
682 self.extra.appendAssumeCapacity(word);771 self.extra.appendAssumeCapacity(word);
...@@ -697,6 +786,7 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t...@@ -697,6 +786,7 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t
697 u32 => word,786 u32 => word,
698 i32 => @bitCast(i32, word),787 i32 => @bitCast(i32, word),
699 Ref => @intToEnum(Ref, word),788 Ref => @intToEnum(Ref, word),
789 StorageClass => @intToEnum(StorageClass, word),
700 else => @compileError("Invalid type: " ++ @typeName(field.type)),790 else => @compileError("Invalid type: " ++ @typeName(field.type)),
701 };791 };
702 }792 }