aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-10-07 18:53:33 +0200
committerRobin Voetter <robin@voetter.nl>2023-10-15 13:59:55 +0200
commit89b1dafa7808d22eab78ea486f158f794da46a2c (patch)
tree7f743c2d4604f622d6c6da6f29254dc98cd61eb2 /src
parent28dda3bf898cc338eb0040f3f21799eda1e25be0 (diff)
downloadzig-89b1dafa7808d22eab78ea486f158f794da46a2c.tar.gz
zig-89b1dafa7808d22eab78ea486f158f794da46a2c.zip
spirv: aggregate_init for structs
Diffstat (limited to 'src')
-rw-r--r--src/codegen/spirv.zig45
1 files changed, 42 insertions, 3 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 3a751fed68..2fdec5675f 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -2725,6 +2725,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
+ const ip = &mod.intern_pool;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const result_ty = self.typeOfIndex(inst);
const result_ty_ref = try self.resolveType(result_ty, .direct);
@@ -2733,15 +2734,53 @@ const DeclGen = struct {
switch (result_ty.zigTypeTag(mod)) {
.Vector => unreachable, // TODO
- .Struct => unreachable, // TODO
+ .Struct => {
+ if (mod.typeToPackedStruct(result_ty)) |struct_type| {
+ _ = struct_type;
+ unreachable; // TODO
+ }
+
+ const constituents = try self.gpa.alloc(IdRef, elements.len);
+ defer self.gpa.free(constituents);
+ var index: usize = 0;
+
+ switch (ip.indexToKey(result_ty.toIntern())) {
+ .anon_struct_type => |tuple| {
+ for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {
+ if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
+ assert(field_ty.toType().hasRuntimeBits(mod));
+
+ const id = try self.resolve(element);
+ constituents[index] = try self.convertToIndirect(field_ty.toType(), id);
+ index += 1;
+ }
+ },
+ .struct_type => |struct_type| {
+ var it = struct_type.iterateRuntimeOrder(ip);
+ for (elements, 0..) |element, i| {
+ const field_index = it.next().?;
+ if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
+ const field_ty = struct_type.field_types.get(ip)[field_index].toType();
+ assert(field_ty.hasRuntimeBitsIgnoreComptime(mod));
+
+ const id = try self.resolve(element);
+ constituents[index] = try self.convertToIndirect(field_ty, id);
+ index += 1;
+ }
+ },
+ else => unreachable,
+ }
+
+ return try self.constructStruct(result_ty_ref, constituents[0..index]);
+ },
.Array => {
const array_info = result_ty.arrayInfo(mod);
const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(mod));
const elem_ids = try self.gpa.alloc(IdRef, n_elems);
defer self.gpa.free(elem_ids);
- for (elements, 0..) |elem_inst, i| {
- const id = try self.resolve(elem_inst);
+ for (elements, 0..) |element, i| {
+ const id = try self.resolve(element);
elem_ids[i] = try self.convertToIndirect(array_info.elem_type, id);
}