authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-21 13:04:18+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-10-21 17:46:52+02:00
log5090d75e48ba0a044997b93b0c5cf1f7dcec60f1
treeba940a217a474f6eace8a3b42970c941da5741db
parent200bca360e333abeb29f4af6d050adf42c2ca5a7
signaturebadge-check Signed by SSH key SHA256:CQ99aPxq+RueiL9u7z0FEki5Fm7V6T8q4PrEGmINrA4

spirv: make load() and store() accept MemoryOptions

This struct is used to configure the load, such as to make it volatile. Previously this was done using a single bool, but this struct makes it shorter to write non-volatile loads (the usual) and more clear whats going on when a volatile load is required.

1 files changed, 23 insertions(+), 19 deletions(-)

src/codegen/spirv.zig+23-19
......@@ -1910,11 +1910,15 @@ const DeclGen = struct {
19101910 return try self.convertToDirect(result_ty, result_id);
19111911 }
19121912
1913 fn load(self: *DeclGen, value_ty: Type, ptr_id: IdRef, is_volatile: bool) !IdRef {
1913 const MemoryOptions = struct {
1914 is_volatile: bool = false,
1915 };
1916
1917 fn load(self: *DeclGen, value_ty: Type, ptr_id: IdRef, options: MemoryOptions) !IdRef {
19141918 const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect);
19151919 const result_id = self.spv.allocId();
19161920 const access = spec.MemoryAccess.Extended{
1917 .Volatile = is_volatile,
1921 .Volatile = options.is_volatile,
19181922 };
19191923 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
19201924 .id_result_type = self.typeId(indirect_value_ty_ref),
......@@ -1925,10 +1929,10 @@ const DeclGen = struct {
19251929 return try self.convertToDirect(value_ty, result_id);
19261930 }
19271931
1928 fn store(self: *DeclGen, value_ty: Type, ptr_id: IdRef, value_id: IdRef, is_volatile: bool) !void {
1932 fn store(self: *DeclGen, value_ty: Type, ptr_id: IdRef, value_id: IdRef, options: MemoryOptions) !void {
19291933 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);
19301934 const access = spec.MemoryAccess.Extended{
1931 .Volatile = is_volatile,
1935 .Volatile = options.is_volatile,
19321936 };
19331937 try self.func.body.emit(self.spv.gpa, .OpStore, .{
19341938 .pointer = ptr_id,
......@@ -2849,14 +2853,14 @@ const DeclGen = struct {
28492853 const dst_ptr_ty_ref = try self.ptrType(dst_ty, .Function);
28502854
28512855 const tmp_id = try self.alloc(src_ty, .{ .storage_class = .Function });
2852 try self.store(src_ty, tmp_id, src_id, false);
2856 try self.store(src_ty, tmp_id, src_id, .{});
28532857 const casted_ptr_id = self.spv.allocId();
28542858 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
28552859 .id_result_type = self.typeId(dst_ptr_ty_ref),
28562860 .id_result = casted_ptr_id,
28572861 .operand = tmp_id,
28582862 });
2859 return try self.load(dst_ty, casted_ptr_id, false);
2863 return try self.load(dst_ty, casted_ptr_id, .{});
28602864 }
28612865
28622866 fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
......@@ -3219,7 +3223,7 @@ const DeclGen = struct {
32193223
32203224 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
32213225 const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index_id, &.{});
3222 return try self.load(slice_ty.childType(mod), elem_ptr, slice_ty.isVolatilePtr(mod));
3226 return try self.load(slice_ty.childType(mod), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(mod) });
32233227 }
32243228
32253229 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
......@@ -3273,9 +3277,9 @@ const DeclGen = struct {
32733277 const elem_ptr_ty_ref = try self.ptrType(elem_ty, .Function);
32743278
32753279 const tmp_id = try self.alloc(array_ty, .{ .storage_class = .Function });
3276 try self.store(array_ty, tmp_id, array_id, false);
3280 try self.store(array_ty, tmp_id, array_id, .{});
32773281 const elem_ptr_id = try self.accessChainId(elem_ptr_ty_ref, tmp_id, &.{index_id});
3278 return try self.load(elem_ty, elem_ptr_id, false);
3282 return try self.load(elem_ty, elem_ptr_id, .{});
32793283 }
32803284
32813285 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
......@@ -3288,7 +3292,7 @@ const DeclGen = struct {
32883292 const ptr_id = try self.resolve(bin_op.lhs);
32893293 const index_id = try self.resolve(bin_op.rhs);
32903294 const elem_ptr_id = try self.ptrElemPtr(ptr_ty, ptr_id, index_id);
3291 return try self.load(elem_ty, elem_ptr_id, ptr_ty.isVolatilePtr(mod));
3295 return try self.load(elem_ty, elem_ptr_id, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
32923296 }
32933297
32943298 fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {
......@@ -3307,10 +3311,10 @@ const DeclGen = struct {
33073311 const new_tag_id = try self.resolve(bin_op.rhs);
33083312
33093313 if (layout.payload_size == 0) {
3310 try self.store(tag_ty, union_ptr_id, new_tag_id, un_ptr_ty.isVolatilePtr(mod));
3314 try self.store(tag_ty, union_ptr_id, new_tag_id, .{ .is_volatile = un_ptr_ty.isVolatilePtr(mod) });
33113315 } else {
33123316 const ptr_id = try self.accessChain(tag_ptr_ty_ref, union_ptr_id, &.{layout.tag_index});
3313 try self.store(tag_ty, ptr_id, new_tag_id, un_ptr_ty.isVolatilePtr(mod));
3317 try self.store(tag_ty, ptr_id, new_tag_id, .{ .is_volatile = un_ptr_ty.isVolatilePtr(mod) });
33143318 }
33153319 }
33163320
......@@ -3384,13 +3388,13 @@ const DeclGen = struct {
33843388 const tag_ptr_ty_ref = try self.ptrType(maybe_tag_ty.?, .Function);
33853389 const ptr_id = try self.accessChain(tag_ptr_ty_ref, tmp_id, &.{@as(u32, @intCast(layout.tag_index))});
33863390 const tag_id = try self.constInt(tag_ty_ref, tag_int);
3387 try self.store(maybe_tag_ty.?, ptr_id, tag_id, false);
3391 try self.store(maybe_tag_ty.?, ptr_id, tag_id, .{});
33883392 }
33893393
33903394 if (layout.active_field_size != 0) {
33913395 const active_field_ptr_ty_ref = try self.ptrType(layout.active_field_ty, .Function);
33923396 const ptr_id = try self.accessChain(active_field_ptr_ty_ref, tmp_id, &.{@as(u32, @intCast(layout.active_field_index))});
3393 try self.store(layout.active_field_ty, ptr_id, payload.?, false);
3397 try self.store(layout.active_field_ty, ptr_id, payload.?, .{});
33943398 } else {
33953399 assert(payload == null);
33963400 }
......@@ -3468,7 +3472,7 @@ const DeclGen = struct {
34683472 .id_result = tmp_id,
34693473 .storage_class = .Function,
34703474 });
3471 try self.store(object_ty, tmp_id, object_id, false);
3475 try self.store(object_ty, tmp_id, object_id, .{});
34723476 const casted_tmp_id = self.spv.allocId();
34733477 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
34743478 .id_result_type = self.typeId(un_active_ptr_ty_ref),
......@@ -3477,7 +3481,7 @@ const DeclGen = struct {
34773481 });
34783482 const layout = self.unionLayout(object_ty, field_index);
34793483 const field_ptr_id = try self.accessChain(field_ptr_ty_ref, casted_tmp_id, &.{layout.active_field_index});
3480 return try self.load(field_ty, field_ptr_id, false);
3484 return try self.load(field_ty, field_ptr_id, .{});
34813485 },
34823486 },
34833487 else => unreachable,
......@@ -3730,7 +3734,7 @@ const DeclGen = struct {
37303734 const operand = try self.resolve(ty_op.operand);
37313735 if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
37323736
3733 return try self.load(elem_ty, operand, ptr_ty.isVolatilePtr(mod));
3737 return try self.load(elem_ty, operand, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
37343738 }
37353739
37363740 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
......@@ -3740,7 +3744,7 @@ const DeclGen = struct {
37403744 const ptr = try self.resolve(bin_op.lhs);
37413745 const value = try self.resolve(bin_op.rhs);
37423746
3743 try self.store(elem_ty, ptr, value, ptr_ty.isVolatilePtr(self.module));
3747 try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(self.module) });
37443748 }
37453749
37463750 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {
......@@ -3804,7 +3808,7 @@ const DeclGen = struct {
38043808 }
38053809
38063810 const ptr = try self.resolve(un_op);
3807 const value = try self.load(ret_ty, ptr, ptr_ty.isVolatilePtr(mod));
3811 const value = try self.load(ret_ty, ptr, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
38083812 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{
38093813 .value = value,
38103814 });