diff options
| author | Robin Voetter <robin@voetter.nl> | 2023-10-07 18:53:33 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2023-10-15 13:59:55 +0200 |
| commit | 89b1dafa7808d22eab78ea486f158f794da46a2c (patch) | |
| tree | 7f743c2d4604f622d6c6da6f29254dc98cd61eb2 /src | |
| parent | 28dda3bf898cc338eb0040f3f21799eda1e25be0 (diff) | |
| download | zig-89b1dafa7808d22eab78ea486f158f794da46a2c.tar.gz zig-89b1dafa7808d22eab78ea486f158f794da46a2c.zip | |
spirv: aggregate_init for structs
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/spirv.zig | 45 |
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); } |
