mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
spirv: air aggregate_init for array
This commit is contained in:
parent
8d49b2ef4e
commit
26c279cca2
@ -438,6 +438,8 @@ pub const DeclGen = struct {
|
||||
|
||||
/// Construct a struct at runtime.
|
||||
/// result_ty_ref must be a struct type.
|
||||
/// Constituents should be in `indirect` representation (as the elements of a struct should be).
|
||||
/// Result is in `direct` representation.
|
||||
fn constructStruct(self: *DeclGen, result_ty_ref: CacheRef, constituents: []const IdRef) !IdRef {
|
||||
// The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'
|
||||
// operands are not constant.
|
||||
@ -474,6 +476,8 @@ pub const DeclGen = struct {
|
||||
|
||||
/// Construct a struct at runtime.
|
||||
/// result_ty_ref must be an array type.
|
||||
/// Constituents should be in `indirect` representation (as the elements of an array should be).
|
||||
/// Result is in `direct` representation.
|
||||
fn constructArray(self: *DeclGen, result_ty_ref: CacheRef, constituents: []const IdRef) !IdRef {
|
||||
// The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which'
|
||||
// operands are not constant.
|
||||
@ -1682,6 +1686,7 @@ pub const DeclGen = struct {
|
||||
.not => try self.airNot(inst),
|
||||
|
||||
.array_to_slice => try self.airArrayToSlice(inst),
|
||||
.aggregate_init => try self.airAggregateInit(inst),
|
||||
|
||||
.slice_ptr => try self.airSliceField(inst, 0),
|
||||
.slice_len => try self.airSliceField(inst, 1),
|
||||
@ -2430,6 +2435,8 @@ pub const DeclGen = struct {
|
||||
}
|
||||
|
||||
fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
if (self.liveness.isUnused(inst)) return null;
|
||||
|
||||
const mod = self.module;
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const array_ptr_ty = self.typeOf(ty_op.operand);
|
||||
@ -2453,6 +2460,40 @@ pub const DeclGen = struct {
|
||||
return try self.constructStruct(slice_ty_ref, &.{ elem_ptr_id, len_id });
|
||||
}
|
||||
|
||||
fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
if (self.liveness.isUnused(inst)) return null;
|
||||
|
||||
const mod = self.module;
|
||||
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);
|
||||
const len: usize = @intCast(result_ty.arrayLen(mod));
|
||||
const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
|
||||
|
||||
switch (result_ty.zigTypeTag(mod)) {
|
||||
.Vector => unreachable, // TODO
|
||||
.Struct => unreachable, // TODO
|
||||
.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);
|
||||
elem_ids[i] = try self.convertToIndirect(array_info.elem_type, id);
|
||||
}
|
||||
|
||||
if (array_info.sentinel) |sentinel_val| {
|
||||
elem_ids[n_elems - 1] = try self.constant(array_info.elem_type, sentinel_val, .indirect);
|
||||
}
|
||||
|
||||
return try self.constructArray(result_ty_ref, elem_ids);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {
|
||||
if (self.liveness.isUnused(inst)) return null;
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user