From a72179fed0f20619f6787c760fae00ece16e9d20 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Mon, 29 May 2023 19:25:48 +0200 Subject: [PATCH] spirv: translate structs to cache key --- src/codegen/spirv/Module.zig | 10 ++++ src/codegen/spirv/TypeConstantCache.zig | 62 +++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig index 9fcb27b366..54b868aba2 100644 --- a/src/codegen/spirv/Module.zig +++ b/src/codegen/spirv/Module.zig @@ -918,3 +918,13 @@ pub fn debugName(self: *Module, target: IdResult, comptime fmt: []const u8, args .name = name, }); } + +pub fn memberDebugName(self: *Module, target: IdResult, member: u32, comptime fmt: []const u8, args: anytype) !void { + const name = try std.fmt.allocPrint(self.gpa, fmt, args); + defer self.gpa.free(name); + try self.sections.debug_names.emit(self.gpa, .OpMemberName, .{ + .type = target, + .member = member, + .name = name, + }); +} diff --git a/src/codegen/spirv/TypeConstantCache.zig b/src/codegen/spirv/TypeConstantCache.zig index 2a94359f15..aec1ba226f 100644 --- a/src/codegen/spirv/TypeConstantCache.zig +++ b/src/codegen/spirv/TypeConstantCache.zig @@ -11,6 +11,7 @@ //! vectors) must have a _unique_ representation in the final binary. const std = @import("std"); +const assert = std.debug.assert; const Allocator = std.mem.Allocator; const Section = @import("Section.zig"); @@ -68,8 +69,11 @@ const Tag = enum { /// data is child type type_ptr_function, /// Simple pointer type that does not have any decorations. - /// data is SimplePointerType + /// data is payload to SimplePointerType type_ptr_simple, + /// Simple structure type that does not have any decorations. + /// data is payload to SimpleStructType + type_struct_simple, // -- Values /// Value of type u8 @@ -107,7 +111,7 @@ const Tag = enum { const ArrayType = Key.ArrayType; // Trailing: - // - [param_len]Ref: parameter types + // - [param_len]Ref: parameter types. const FunctionType = struct { param_len: u32, return_type: Ref, @@ -118,6 +122,13 @@ const Tag = enum { child_type: Ref, }; + /// Trailing: + /// - [members_len]Ref: Member types. + const SimpleStructType = struct { + /// Number of members that this struct has. + members_len: u32, + }; + const Float64 = struct { // Low-order 32 bits of the value. low: u32, @@ -201,6 +212,7 @@ pub const Key = union(enum) { array_type: ArrayType, function_type: FunctionType, ptr_type: PointerType, + struct_type: StructType, // -- values int: Int, @@ -238,6 +250,12 @@ pub const Key = union(enum) { // - MaxByteOffset, }; + pub const StructType = struct { + // TODO: Decorations. + /// The type of each member. + member_types: []const Ref, + }; + pub const Int = struct { /// The type: any bitness integer. ty: Ref, @@ -304,6 +322,11 @@ pub const Key = union(enum) { std.hash.autoHash(&hasher, param_type); } }, + .struct_type => |struct_type| { + for (struct_type.member_types) |member_type| { + std.hash.autoHash(&hasher, member_type); + } + }, inline else => |key| std.hash.autoHash(&hasher, key), } return @truncate(u32, hasher.final()); @@ -318,10 +341,14 @@ pub const Key = union(enum) { } return switch (a) { .function_type => |a_func| { - const b_func = a.function_type; + const b_func = b.function_type; return a_func.return_type == b_func.return_type and std.mem.eql(Ref, a_func.parameters, b_func.parameters); }, + .struct_type => |a_struct| { + const b_struct = b.struct_type; + return std.mem.eql(Ref, a_struct.member_types, b_struct.member_types); + }, // TODO: Unroll? else => std.meta.eql(a, b), }; @@ -442,6 +469,14 @@ fn emit( }); // TODO: Decorations? }, + .struct_type => |struct_type| { + try section.emitRaw(spv.gpa, .OpTypeStruct, 1 + struct_type.member_types.len); + section.writeOperand(IdResult, result_id); + for (struct_type.member_types) |member_type| { + section.writeOperand(IdResult, self.resultId(member_type)); + } + // TODO: Decorations? + }, .int => |int| { const int_type = self.lookup(int.ty).int_type; const ty_id = self.resultId(int.ty); @@ -552,6 +587,18 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { }), }, }, + .struct_type => |struct_type| blk: { + const extra = try self.addExtra(spv, Tag.SimpleStructType{ + .members_len = @intCast(u32, struct_type.member_types.len), + }); + try self.extra.appendSlice(spv.gpa, @ptrCast([]const u32, struct_type.member_types)); + + break :blk Item{ + .tag = .type_struct_simple, + .result_id = result_id, + .data = extra, + }; + }, .int => |int| blk: { const int_type = self.lookup(int.ty).int_type; if (int_type.signedness == .unsigned and int_type.bits == 8) { @@ -687,6 +734,15 @@ pub fn lookup(self: *const Self, ref: Ref) Key { }, }; }, + .type_struct_simple => { + const payload = self.extraDataTrail(Tag.SimpleStructType, data); + const member_types = @ptrCast([]const Ref, self.extra.items[payload.trail..][0..payload.data.members_len]); + return .{ + .struct_type = .{ + .member_types = member_types, + }, + }; + }, .float16 => .{ .float = .{ .ty = self.get(.{ .float_type = .{ .bits = 16 } }), .value = .{ .float16 = @bitCast(f16, @intCast(u16, data)) },