authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-22 11:18:58+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-11 20:31:51+02:00
loge26d8d060410ff5f62356c41f3c782f8a9081495
tree7bfe6f191108e2191d79c5f64fecaab4a0bdbc6e
parentd961b11cde81e92ed3d35c98f7b191255aac58a6
signaturelock-open Commit is signed but in an unrecognized format.

spirv: make decl deps a hash map instead of an arraylist

The same declaration can be added to the dependency set multiple times, and in this case we still need to emit it once. By making this list a hash map instead, we can do that quite easily. This commit also introduces some additional debug logging regarding decls.

2 files changed, 15 insertions(+), 12 deletions(-)

src/codegen/spirv.zig+12-9
......@@ -238,6 +238,7 @@ pub const DeclGen = struct {
238238 else => unreachable,
239239 };
240240 const spv_decl_index = try self.resolveDecl(fn_decl_index);
241 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});
241242 return self.spv.declPtr(spv_decl_index).result_id;
242243 }
243244
......@@ -459,7 +460,7 @@ pub const DeclGen = struct {
459460 /// If full, its flushed.
460461 partial_word: std.BoundedArray(u8, @sizeOf(Word)) = .{},
461462 /// The declaration dependencies of the constant we are lowering.
462 decl_deps: std.ArrayList(SpvModule.Decl.Index),
463 decl_deps: std.AutoArrayHashMap(SpvModule.Decl.Index, void),
463464
464465 /// Utility function to get the section that instructions should be lowered to.
465466 fn section(self: *@This()) *SpvSection {
......@@ -582,14 +583,15 @@ pub const DeclGen = struct {
582583 // just generate an empty pointer. Function pointers are represented by usize for now,
583584 // though.
584585 try self.addInt(Type.usize, Value.initTag(.zero));
586 // TODO: Add dependency
585587 return;
586588 },
587589 .extern_fn => unreachable, // TODO
588590 else => {
589591 const result_id = dg.spv.allocId();
590 log.debug("addDeclRef {s} = {}", .{ decl.name, result_id.id });
592 log.debug("addDeclRef: id = {}, index = {}, name = {s}", .{ result_id.id, @enumToInt(spv_decl_index), decl.name });
591593
592 try self.decl_deps.append(spv_decl_index);
594 try self.decl_deps.put(spv_decl_index, {});
593595
594596 const decl_id = dg.spv.declPtr(spv_decl_index).result_id;
595597 // TODO: Do we need a storage class cast here?
......@@ -861,7 +863,8 @@ pub const DeclGen = struct {
861863
862864 assert(storage_class != .Generic and storage_class != .Function);
863865
864 log.debug("lowerIndirectConstant: ty = {}, val = {}", .{ ty.fmt(self.module), val.fmtDebug() });
866 const var_id = self.spv.allocId();
867 log.debug("lowerIndirectConstant: id = {}, index = {}, ty = {}, val = {}", .{ var_id.id, @enumToInt(spv_decl_index), ty.fmt(self.module), val.fmtDebug() });
865868
866869 const section = &self.spv.globals.section;
867870
......@@ -897,7 +900,7 @@ pub const DeclGen = struct {
897900 .u32_ty_id = self.typeId(u32_ty_ref),
898901 .members = std.ArrayList(SpvType.Payload.Struct.Member).init(self.gpa),
899902 .initializers = std.ArrayList(IdRef).init(self.gpa),
900 .decl_deps = std.ArrayList(SpvModule.Decl.Index).init(self.gpa),
903 .decl_deps = std.AutoArrayHashMap(SpvModule.Decl.Index, void).init(self.gpa),
901904 };
902905
903906 defer icl.members.deinit();
......@@ -917,7 +920,6 @@ pub const DeclGen = struct {
917920 .constituents = icl.initializers.items,
918921 });
919922
920 const var_id = self.spv.allocId();
921923 self.spv.globalPtr(spv_decl_index).?.result_id = var_id;
922924 try section.emit(self.spv.gpa, .OpVariable, .{
923925 .id_result_type = self.typeId(ptr_constant_struct_ty_ref),
......@@ -951,7 +953,7 @@ pub const DeclGen = struct {
951953 });
952954 }
953955
954 try self.spv.declareDeclDeps(spv_decl_index, icl.decl_deps.items);
956 try self.spv.declareDeclDeps(spv_decl_index, icl.decl_deps.keys());
955957 self.spv.endGlobal(spv_decl_index, begin_inst);
956958 }
957959
......@@ -1007,7 +1009,8 @@ pub const DeclGen = struct {
10071009 false,
10081010 alignment,
10091011 );
1010 try self.func.decl_deps.append(self.spv.gpa, spv_decl_index);
1012 log.debug("indirect constant: index = {}", .{@enumToInt(spv_decl_index)});
1013 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});
10111014
10121015 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
10131016 .id_result_type = result_ty_id,
......@@ -1471,7 +1474,7 @@ pub const DeclGen = struct {
14711474 const spv_decl_index = try self.resolveDecl(self.decl_index);
14721475
14731476 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
1474 log.debug("genDecl {s} = {}", .{ decl.name, decl_id });
1477 log.debug("genDecl: id = {}, index = {}, name = {s}", .{ decl_id.id, @enumToInt(spv_decl_index), decl.name });
14751478
14761479 if (decl.val.castTag(.function)) |_| {
14771480 assert(decl.ty.zigTypeTag() == .Fn);
src/codegen/spirv/Module.zig+3-3
......@@ -40,14 +40,14 @@ pub const Fn = struct {
4040 /// the end of this function definition.
4141 body: Section = .{},
4242 /// The decl dependencies that this function depends on.
43 decl_deps: std.ArrayListUnmanaged(Decl.Index) = .{},
43 decl_deps: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
4444
4545 /// Reset this function without deallocating resources, so that
4646 /// it may be used to emit code for another function.
4747 pub fn reset(self: *Fn) void {
4848 self.prologue.reset();
4949 self.body.reset();
50 self.decl_deps.items.len = 0;
50 self.decl_deps.clearRetainingCapacity();
5151 }
5252
5353 /// Free the resources owned by this function.
......@@ -358,7 +358,7 @@ pub fn flush(self: *Module, file: std.fs.File) !void {
358358pub fn addFunction(self: *Module, decl_index: Decl.Index, func: Fn) !void {
359359 try self.sections.functions.append(self.gpa, func.prologue);
360360 try self.sections.functions.append(self.gpa, func.body);
361 try self.declareDeclDeps(decl_index, func.decl_deps.items);
361 try self.declareDeclDeps(decl_index, func.decl_deps.keys());
362362}
363363
364364/// Fetch the result-id of an OpString instruction that encodes the path of the source