spirv: basic setup for using new type constant cache
This commit is contained in:
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user