diff options
| author | Robin Voetter <robin@voetter.nl> | 2023-05-29 13:19:08 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2023-05-30 19:43:36 +0200 |
| commit | b2a984cda67edd25fa2bf3ebe697649d561ff80f (patch) | |
| tree | 198ed214fcc02afd1f5c14ca432aea5b4b3e8514 /src/codegen/spirv/Module.zig | |
| parent | 96a66d14a16a89f759c1ed86a61cef710e3a7d05 (diff) | |
| download | zig-b2a984cda67edd25fa2bf3ebe697649d561ff80f.tar.gz zig-b2a984cda67edd25fa2bf3ebe697649d561ff80f.zip | |
spirv: basic setup for using new type constant cache
Diffstat (limited to 'src/codegen/spirv/Module.zig')
| -rw-r--r-- | src/codegen/spirv/Module.zig | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig index d5c293d912..9fcb27b366 100644 --- a/src/codegen/spirv/Module.zig +++ b/src/codegen/spirv/Module.zig @@ -21,6 +21,7 @@ const IdResultType = spec.IdResultType; const Section = @import("Section.zig"); const Type = @import("type.zig").Type; +pub const TypeConstantCache = @import("TypeConstantCache.zig"); const TypeCache = std.ArrayHashMapUnmanaged(Type, IdResultType, Type.ShallowHashContext32, true); @@ -125,8 +126,16 @@ sections: struct { // OpModuleProcessed - skip for now. /// Annotation instructions (OpDecorate etc). annotations: Section = .{}, - /// Type and constant declarations that are generated by the TypeConstantCache. - types_and_constants: Section = .{}, + /// Global variable declarations + /// From this section, OpLine and OpNoLine is allowed. + /// According to the SPIR-V documentation, this section normally + /// also holds type and constant instructions. These are managed + /// via the tc_cache instead, which is the sole structure that + /// manages that section. These will be inserted between this and + /// the previous section when emitting the final binary. + /// TODO: Do we need this section? Globals are also managed with another mechanism. + /// The only thing that needs to be kept here is OpUndef + globals: Section = .{}, /// Type declarations, constants, global variables /// Below this section, OpLine and OpNoLine is allowed. types_globals_constants: Section = .{}, @@ -143,11 +152,10 @@ next_result_id: Word, /// just the ones for OpLine. Note that OpLine needs the result of OpString, and not that of OpSource. source_file_names: std.StringHashMapUnmanaged(IdRef) = .{}, -/// SPIR-V type cache. Note that according to SPIR-V spec section 2.8, Types and Variables, non-pointer -/// non-aggrerate types (which includes matrices and vectors) must have a _unique_ representation in -/// the final binary. -/// Note: Uses ArrayHashMap which is insertion ordered, so that we may refer to other types by index (Type.Ref). type_cache: TypeCache = .{}, +/// SPIR-V type- and constant cache. This structure is used to store information about these in a more +/// efficient manner. +tc_cache: TypeConstantCache = .{}, /// Set of Decls, referred to by Decl.Index. decls: std.ArrayListUnmanaged(Decl) = .{}, @@ -165,7 +173,7 @@ globals: struct { globals: std.AutoArrayHashMapUnmanaged(Decl.Index, Global) = .{}, /// This pseudo-section contains the initialization code for all the globals. Instructions from /// here are reordered when flushing the module. Its contents should be part of the - /// `types_globals_constants` SPIR-V section. + /// `types_globals_constants` SPIR-V section when the module is emitted. section: Section = .{}, } = .{}, @@ -184,12 +192,11 @@ pub fn deinit(self: *Module) void { self.sections.debug_strings.deinit(self.gpa); self.sections.debug_names.deinit(self.gpa); self.sections.annotations.deinit(self.gpa); - self.sections.types_and_constants(self.gpa); - self.sections.types_globals_constants.deinit(self.gpa); + self.sections.globals.deinit(self.gpa); self.sections.functions.deinit(self.gpa); self.source_file_names.deinit(self.gpa); - self.type_cache.deinit(self.gpa); + self.tc_cache.deinit(self); self.decls.deinit(self.gpa); self.decl_deps.deinit(self.gpa); @@ -216,6 +223,18 @@ pub fn idBound(self: Module) Word { return self.next_result_id; } +pub fn resolve(self: *Module, key: TypeConstantCache.Key) !TypeConstantCache.Ref { + return self.tc_cache.resolve(self, key); +} + +pub fn resultId(self: *Module, ref: TypeConstantCache.Ref) IdResult { + return self.tc_cache.resultId(ref); +} + +pub fn resolveId(self: *Module, key: TypeConstantCache.Key) !IdResult { + return self.resultId(try self.resolve(key)); +} + fn orderGlobalsInto( self: *Module, decl_index: Decl.Index, @@ -327,6 +346,9 @@ pub fn flush(self: *Module, file: std.fs.File) !void { var entry_points = try self.entryPoints(); defer entry_points.deinit(self.gpa); + var types_constants = try self.tc_cache.materialize(self); + defer types_constants.deinit(self.gpa); + // Note: needs to be kept in order according to section 2.3! const buffers = &[_][]const Word{ &header, @@ -337,8 +359,8 @@ pub fn flush(self: *Module, file: std.fs.File) !void { self.sections.debug_strings.toWords(), self.sections.debug_names.toWords(), self.sections.annotations.toWords(), - self.sections.types_constants.toWords(), - self.sections.types_globals_constants.toWords(), + types_constants.toWords(), + self.sections.globals.toWords(), globals.toWords(), self.sections.functions.toWords(), }; @@ -891,8 +913,8 @@ pub fn declareEntryPoint(self: *Module, decl_index: Decl.Index, name: []const u8 pub fn debugName(self: *Module, target: IdResult, comptime fmt: []const u8, args: anytype) !void { const name = try std.fmt.allocPrint(self.gpa, fmt, args); defer self.gpa.free(name); - try debug.emit(self.gpa, .OpName, .{ - .target = result_id, + try self.sections.debug_names.emit(self.gpa, .OpName, .{ + .target = target, .name = name, }); } |
