authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2024-02-01 19:38:23+03:30
committergravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2024-02-05 11:55:14+03:30
logb41aad019364b2c99934339d70aa4f37d945f248
tree276d1ace6840a8e25eccb838e744b8e3c2231333
parentafa779335186acf10f79848775afaf55698d8d88

spirv: emit vectors whenever we can


2 files changed, 59 insertions(+), 7 deletions(-)

src/codegen/spirv.zig+52-7
......@@ -744,6 +744,30 @@ const DeclGen = struct {
744744 return try self.load(ty, ptr_composite_id, .{});
745745 }
746746
747 /// Construct a vector at runtime.
748 /// ty must be an vector type.
749 /// Constituents should be in `indirect` representation (as the elements of an vector should be).
750 /// Result is in `direct` representation.
751 fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef {
752 // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'
753 // operands are not constant.
754 // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349
755 // For now, just initialize the struct by setting the fields manually...
756 // TODO: Make this OpCompositeConstruct when we can
757 const mod = self.module;
758 const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function });
759 const ptr_elem_ty_ref = try self.ptrType(ty.elemType2(mod), .Function);
760 for (constituents, 0..) |constitent_id, index| {
761 const ptr_id = try self.accessChain(ptr_elem_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))});
762 try self.func.body.emit(self.spv.gpa, .OpStore, .{
763 .pointer = ptr_id,
764 .object = constitent_id,
765 });
766 }
767
768 return try self.load(ty, ptr_composite_id, .{});
769 }
770
747771 /// Construct an array at runtime.
748772 /// ty must be an array type.
749773 /// Constituents should be in `indirect` representation (as the elements of an array should be).
......@@ -963,13 +987,16 @@ const DeclGen = struct {
963987 }
964988
965989 switch (tag) {
966 inline .array_type => if (array_type.sentinel != .none) {
967 constituents[constituents.len - 1] = try self.constant(elem_ty, Value.fromInterned(array_type.sentinel), .indirect);
990 inline .array_type => {
991 if (array_type.sentinel != .none) {
992 const sentinel = Value.fromInterned(array_type.sentinel);
993 constituents[constituents.len - 1] = try self.constant(elem_ty, sentinel, .indirect);
994 }
995 return self.constructArray(ty, constituents);
968996 },
969 else => {},
997 inline .vector_type => return self.constructVector(ty, constituents),
998 else => unreachable,
970999 }
971
972 return try self.constructArray(ty, constituents);
9731000 },
9741001 .struct_type => {
9751002 const struct_type = mod.typeToStruct(ty).?;
......@@ -1492,8 +1519,14 @@ const DeclGen = struct {
14921519
14931520 const elem_ty = ty.childType(mod);
14941521 const elem_ty_ref = try self.resolveType(elem_ty, .indirect);
1522 const len = ty.vectorLen(mod);
1523 const is_scalar = elem_ty.isNumeric(mod) or elem_ty.toIntern() == .bool_type;
1524
1525 const ty_ref = if (is_scalar and len > 1 and len <= 4)
1526 try self.spv.vectorType(ty.vectorLen(mod), elem_ty_ref)
1527 else
1528 try self.spv.arrayType(ty.vectorLen(mod), elem_ty_ref);
14951529
1496 const ty_ref = try self.spv.arrayType(ty.vectorLen(mod), elem_ty_ref);
14971530 try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
14981531 return ty_ref;
14991532 },
......@@ -3688,7 +3721,19 @@ const DeclGen = struct {
36883721 constituents[0..index],
36893722 );
36903723 },
3691 .Vector, .Array => {
3724 .Vector => {
3725 const n_elems = result_ty.vectorLen(mod);
3726 const elem_ids = try self.gpa.alloc(IdRef, n_elems);
3727 defer self.gpa.free(elem_ids);
3728
3729 for (elements, 0..) |element, i| {
3730 const id = try self.resolve(element);
3731 elem_ids[i] = try self.convertToIndirect(result_ty.childType(mod), id);
3732 }
3733
3734 return try self.constructVector(result_ty, elem_ids);
3735 },
3736 .Array => {
36923737 const array_info = result_ty.arrayInfo(mod);
36933738 const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod));
36943739 const elem_ids = try self.gpa.alloc(IdRef, n_elems);
src/codegen/spirv/Module.zig+7
......@@ -508,6 +508,13 @@ pub fn intType(self: *Module, signedness: std.builtin.Signedness, bits: u16) !Ca
508508 } });
509509}
510510
511pub fn vectorType(self: *Module, len: u32, elem_ty_ref: CacheRef) !CacheRef {
512 return try self.resolve(.{ .vector_type = .{
513 .component_type = elem_ty_ref,
514 .component_count = len,
515 } });
516}
517
511518pub fn arrayType(self: *Module, len: u32, elem_ty_ref: CacheRef) !CacheRef {
512519 const len_ty_ref = try self.resolve(.{ .int_type = .{
513520 .signedness = .unsigned,