spirv: cache pointers

This commit is contained in:
Robin Voetter 2023-05-29 17:42:49 +02:00
parent e05ace7673
commit f13a6ee19e
No known key found for this signature in database
GPG Key ID: E755662F227CB468
2 changed files with 105 additions and 1 deletions

View File

@ -1331,6 +1331,20 @@ pub const DeclGen = struct {
return try self.sizeType2();
},
},
.Pointer => {
const ptr_info = ty.ptrInfo().data;
const storage_class = spvStorageClass(ptr_info.@"addrspace");
const child_ty_ref = try self.resolveType2(ptr_info.pointee_type, .indirect);
const ptr_ty_ref = try self.spv.resolve(.{ .ptr_type = .{
.storage_class = storage_class,
.child_type = child_ty_ref,
} });
if (ptr_info.size != .Slice) {
return ptr_ty_ref;
}
unreachable; // TODO
},
else => unreachable, // TODO
}

View File

@ -19,6 +19,7 @@ const Module = @import("Module.zig");
const spec = @import("spec.zig");
const Opcode = spec.Opcode;
const IdResult = spec.IdResult;
const StorageClass = spec.StorageClass;
const Self = @This();
@ -54,9 +55,21 @@ const Tag = enum {
/// Array type
/// data is payload to ArrayType
type_array,
/// Function (proto)type.
/// Function (proto)type
/// data is payload to FunctionType
type_function,
/// Pointer type in the CrossWorkgroup storage class
/// data is child type
type_ptr_generic,
/// Pointer type in the CrossWorkgroup storage class
/// data is child type
type_ptr_crosswgp,
/// Pointer type in the Function storage class
/// data is child type
type_ptr_function,
/// Simple pointer type that does not have any decorations.
/// data is SimplePointerType
type_ptr_simple,
// -- Values
/// Value of type u8
@ -100,6 +113,11 @@ const Tag = enum {
return_type: Ref,
};
const SimplePointerType = struct {
storage_class: StorageClass,
child_type: Ref,
};
const Float64 = struct {
// Low-order 32 bits of the value.
low: u32,
@ -182,6 +200,7 @@ pub const Key = union(enum) {
vector_type: VectorType,
array_type: ArrayType,
function_type: FunctionType,
ptr_type: PointerType,
// -- values
int: Int,
@ -210,6 +229,15 @@ pub const Key = union(enum) {
parameters: []const Ref,
};
pub const PointerType = struct {
storage_class: StorageClass,
child_type: Ref,
// TODO: Decorations:
// - Alignment
// - ArrayStride,
// - MaxByteOffset,
};
pub const Int = struct {
/// The type: any bitness integer.
ty: Ref,
@ -406,6 +434,14 @@ fn emit(
section.writeOperand(IdResult, self.resultId(param_type));
}
},
.ptr_type => |ptr| {
try section.emit(spv.gpa, .OpTypePointer, .{
.id_result = result_id,
.storage_class = ptr.storage_class,
.type = self.resultId(ptr.child_type),
});
// TODO: Decorations?
},
.int => |int| {
const int_type = self.lookup(int.ty).int_type;
const ty_id = self.resultId(int.ty);
@ -491,6 +527,31 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref {
.data = extra,
};
},
.ptr_type => |ptr| switch (ptr.storage_class) {
.Generic => Item{
.tag = .type_ptr_generic,
.result_id = result_id,
.data = @enumToInt(ptr.child_type),
},
.CrossWorkgroup => Item{
.tag = .type_ptr_crosswgp,
.result_id = result_id,
.data = @enumToInt(ptr.child_type),
},
.Function => Item{
.tag = .type_ptr_function,
.result_id = result_id,
.data = @enumToInt(ptr.child_type),
},
else => |storage_class| Item{
.tag = .type_ptr_simple,
.result_id = result_id,
.data = try self.addExtra(spv, Tag.SimplePointerType{
.storage_class = storage_class,
.child_type = ptr.child_type,
}),
},
},
.int => |int| blk: {
const int_type = self.lookup(int.ty).int_type;
if (int_type.signedness == .unsigned and int_type.bits == 8) {
@ -599,6 +660,33 @@ pub fn lookup(self: *const Self, ref: Ref) Key {
},
};
},
.type_ptr_generic => .{
.ptr_type = .{
.storage_class = .Generic,
.child_type = @intToEnum(Ref, data),
},
},
.type_ptr_crosswgp => .{
.ptr_type = .{
.storage_class = .CrossWorkgroup,
.child_type = @intToEnum(Ref, data),
},
},
.type_ptr_function => .{
.ptr_type = .{
.storage_class = .Function,
.child_type = @intToEnum(Ref, data),
},
},
.type_ptr_simple => {
const payload = self.extraData(Tag.SimplePointerType, data);
return .{
.ptr_type = .{
.storage_class = payload.storage_class,
.child_type = payload.child_type,
},
};
},
.float16 => .{ .float = .{
.ty = self.get(.{ .float_type = .{ .bits = 16 } }),
.value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },
@ -677,6 +765,7 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 {
u32 => field_val,
i32 => @bitCast(u32, field_val),
Ref => @enumToInt(field_val),
StorageClass => @enumToInt(field_val),
else => @compileError("Invalid type: " ++ @typeName(field.type)),
};
self.extra.appendAssumeCapacity(word);
@ -697,6 +786,7 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t
u32 => word,
i32 => @bitCast(i32, word),
Ref => @intToEnum(Ref, word),
StorageClass => @intToEnum(StorageClass, word),
else => @compileError("Invalid type: " ++ @typeName(field.type)),
};
}