authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-11-30 23:28:07+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-09 01:51:51+02:00
logcaf8461af8df9a34abc5985042d98b8188575cd0
tree09db4533e38137d70c64c5aaccc62443916038e7
parent2a8e784989b9053ce609a38a9d384a77ce5badaa
signaturelock-open Commit is signed but in an unrecognized format.

spirv: make locals generic pointers

Taking the address of a local variable should result in a generic pointer - too much code breaks if we do not do this. We cannot lower locals into the generic storage class directly though, so instead, lower the variables into the Function storage class implicitly, and convert the pointer to a generic pointer. Also Correct OpInboundsAccessChain generation (we only need the one index).

1 files changed, 36 insertions(+), 15 deletions(-)

src/codegen/spirv.zig+36-15
......@@ -1306,12 +1306,11 @@ pub const DeclGen = struct {
13061306 };
13071307
13081308 const result_id = self.spv.allocId();
1309 const indexes = [_]IdRef{index};
1310 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
1309 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
13111310 .id_result_type = spv_ptr_ty,
13121311 .id_result = result_id,
13131312 .base = slice_ptr,
1314 .indexes = &indexes,
1313 .element = index,
13151314 });
13161315 return result_id;
13171316 }
......@@ -1340,12 +1339,11 @@ pub const DeclGen = struct {
13401339
13411340 const elem_ptr = blk: {
13421341 const result_id = self.spv.allocId();
1343 const indexes = [_]IdRef{index};
1344 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
1342 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
13451343 .id_result_type = ptr_ty_id,
13461344 .id_result = result_id,
13471345 .base = slice_ptr,
1348 .indexes = &indexes,
1346 .element = index,
13491347 });
13501348 break :blk result_id;
13511349 };
......@@ -1448,22 +1446,45 @@ pub const DeclGen = struct {
14481446 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
14491447 if (self.liveness.isUnused(inst)) return null;
14501448 const ty = self.air.typeOfIndex(inst);
1451 const result_type_id = try self.resolveTypeId(ty);
1449 const result_ty_ref = try self.resolveType(ty, .direct);
1450 const result_ty_id = self.typeId(result_ty_ref);
14521451 const result_id = self.spv.allocId();
14531452
1454 // Rather than generating into code here, we're just going to generate directly into the functions section so that
1455 // variable declarations appear in the first block of the function.
14561453 const storage_class = spirvStorageClass(ty.ptrAddressSpace());
1457 const section = if (storage_class == .Function or storage_class == .Generic)
1458 &self.func.prologue
1459 else
1460 &self.spv.sections.types_globals_constants;
14611454
1455 const ptr_ty_id = switch (storage_class) {
1456 .Generic => blk: {
1457 const payload = try self.spv.arena.create(SpvType.Payload.Pointer);
1458 payload.* = self.spv.typeRefType(result_ty_ref).payload(.pointer).*;
1459 payload.storage_class = .Function;
1460 break :blk try self.spv.resolveTypeId(SpvType.initPayload(&payload.base));
1461 },
1462 else => result_ty_id,
1463 };
1464 const actual_storage_class = switch (storage_class) {
1465 .Generic, .Function => .Function,
1466 else => storage_class,
1467 };
1468 const section = switch (storage_class) {
1469 // SPIR-V requires that OpVariable declarations for locals go into the first block, so we are just going to
1470 // directly generate them into func.prologue instead of the body.
1471 .Generic, .Function => &self.func.prologue,
1472 else => &self.spv.sections.types_globals_constants,
1473 };
14621474 try section.emit(self.spv.gpa, .OpVariable, .{
1463 .id_result_type = result_type_id,
1475 .id_result_type = ptr_ty_id,
14641476 .id_result = result_id,
1465 .storage_class = storage_class,
1477 .storage_class = actual_storage_class,
14661478 });
1479 if (storage_class == .Generic) {
1480 const casted_result_id = self.spv.allocId();
1481 try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{
1482 .id_result_type = result_ty_id,
1483 .id_result = casted_result_id,
1484 .pointer = result_id,
1485 });
1486 return casted_result_id;
1487 }
14671488 return result_id;
14681489 }
14691490