aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv/Module.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-05-29 13:19:08 +0200
committerRobin Voetter <robin@voetter.nl>2023-05-30 19:43:36 +0200
commitb2a984cda67edd25fa2bf3ebe697649d561ff80f (patch)
tree198ed214fcc02afd1f5c14ca432aea5b4b3e8514 /src/codegen/spirv/Module.zig
parent96a66d14a16a89f759c1ed86a61cef710e3a7d05 (diff)
downloadzig-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.zig50
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,
});
}