Skip to content

Commit 8a0a6b7

Browse files
Vexuandrewrk
authored andcommitted
port packed vector elem ptr logic from stage1
Closes #12812 Closes #13925
1 parent 0d92fcf commit 8a0a6b7

18 files changed

+257
-60
lines changed

src/Air.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,10 @@ pub const Inst = struct {
737737
/// Uses the `ty_pl` field.
738738
save_err_return_trace_index,
739739

740+
/// Store an element to a vector pointer at an index.
741+
/// Uses the `vector_store_elem` field.
742+
vector_store_elem,
743+
740744
pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag {
741745
switch (op) {
742746
.lt => return if (optimized) .cmp_lt_optimized else .cmp_lt,
@@ -814,6 +818,11 @@ pub const Inst = struct {
814818
operand: Ref,
815819
operation: std.builtin.ReduceOp,
816820
},
821+
vector_store_elem: struct {
822+
vector_ptr: Ref,
823+
// Index into a different array.
824+
payload: u32,
825+
},
817826

818827
// Make sure we don't accidentally add a field to make this union
819828
// bigger than expected. Note that in Debug builds, Zig is allowed
@@ -1177,6 +1186,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
11771186
.set_union_tag,
11781187
.prefetch,
11791188
.set_err_return_trace,
1189+
.vector_store_elem,
11801190
=> return Type.void,
11811191

11821192
.ptrtoint,

src/Liveness.zig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ pub fn categorizeOperand(
212212
return .write;
213213
},
214214

215+
.vector_store_elem => {
216+
const o = air_datas[inst].vector_store_elem;
217+
const extra = air.extraData(Air.Bin, o.payload).data;
218+
if (o.vector_ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
219+
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
220+
if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 2, .none);
221+
return .write;
222+
},
223+
215224
.arg,
216225
.alloc,
217226
.ret_ptr,
@@ -824,6 +833,12 @@ fn analyzeInst(
824833
return trackOperands(a, new_set, inst, main_tomb, .{ o.lhs, o.rhs, .none });
825834
},
826835

836+
.vector_store_elem => {
837+
const o = inst_datas[inst].vector_store_elem;
838+
const extra = a.air.extraData(Air.Bin, o.payload).data;
839+
return trackOperands(a, new_set, inst, main_tomb, .{ o.vector_ptr, extra.lhs, extra.rhs });
840+
},
841+
827842
.arg,
828843
.alloc,
829844
.ret_ptr,

src/Sema.zig

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25952,6 +25952,30 @@ fn storePtr2(
2595225952

2595325953
try sema.requireRuntimeBlock(block, src, runtime_src);
2595425954
try sema.queueFullTypeResolution(elem_ty);
25955+
25956+
if (ptr_ty.ptrInfo().data.vector_index == .runtime) {
25957+
const ptr_inst = Air.refToIndex(ptr).?;
25958+
const air_tags = sema.air_instructions.items(.tag);
25959+
if (air_tags[ptr_inst] == .ptr_elem_ptr) {
25960+
const ty_pl = sema.air_instructions.items(.data)[ptr_inst].ty_pl;
25961+
const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data;
25962+
_ = try block.addInst(.{
25963+
.tag = .vector_store_elem,
25964+
.data = .{ .vector_store_elem = .{
25965+
.vector_ptr = bin_op.lhs,
25966+
.payload = try block.sema.addExtra(Air.Bin{
25967+
.lhs = bin_op.rhs,
25968+
.rhs = operand,
25969+
}),
25970+
} },
25971+
});
25972+
return;
25973+
}
25974+
return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
25975+
ptr_ty.fmt(sema.mod),
25976+
});
25977+
}
25978+
2595525979
if (is_ret) {
2595625980
_ = try block.addBinOp(.store, ptr, operand);
2595725981
} else {
@@ -27827,6 +27851,19 @@ fn analyzeLoad(
2782727851
}
2782827852
}
2782927853

27854+
if (ptr_ty.ptrInfo().data.vector_index == .runtime) {
27855+
const ptr_inst = Air.refToIndex(ptr).?;
27856+
const air_tags = sema.air_instructions.items(.tag);
27857+
if (air_tags[ptr_inst] == .ptr_elem_ptr) {
27858+
const ty_pl = sema.air_instructions.items(.data)[ptr_inst].ty_pl;
27859+
const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data;
27860+
return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);
27861+
}
27862+
return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
27863+
ptr_ty.fmt(sema.mod),
27864+
});
27865+
}
27866+
2783027867
return block.addTyOp(.load, elem_ty, ptr);
2783127868
}
2783227869

@@ -32697,23 +32734,24 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3269732734
const target = sema.mod.getTarget();
3269832735
const parent_ty = ptr_ty.childType();
3269932736

32737+
const VI = Type.Payload.Pointer.Data.VectorIndex;
32738+
3270032739
const vector_info: struct {
32701-
host_size: u16,
32702-
bit_offset: u16,
32703-
alignment: u32,
32740+
host_size: u16 = 0,
32741+
alignment: u32 = 0,
32742+
vector_index: VI = .none,
3270432743
} = if (parent_ty.tag() == .vector) blk: {
3270532744
const elem_bits = elem_ty.bitSize(target);
32706-
const is_packed = elem_bits != 0 and (elem_bits & (elem_bits - 1)) != 0;
32707-
// TODO: runtime-known index
32708-
assert(!is_packed or offset != null);
32709-
const is_packed_with_offset = is_packed and offset != null and offset.? != 0;
32710-
const target_offset = if (is_packed_with_offset) (if (target.cpu.arch.endian() == .Big) (parent_ty.vectorLen() - 1 - offset.?) else offset.?) else 0;
32745+
if (elem_bits == 0) break :blk .{};
32746+
const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
32747+
if (!is_packed) break :blk .{};
32748+
3271132749
break :blk .{
32712-
.host_size = if (is_packed_with_offset) @intCast(u16, parent_ty.abiSize(target)) else 0,
32713-
.bit_offset = if (is_packed_with_offset) @intCast(u16, elem_bits * target_offset) else 0,
32714-
.alignment = if (is_packed_with_offset) @intCast(u16, parent_ty.abiAlignment(target)) else 0,
32750+
.host_size = @intCast(u16, parent_ty.arrayLen()),
32751+
.alignment = @intCast(u16, parent_ty.abiAlignment(target)),
32752+
.vector_index = if (offset) |some| @intToEnum(VI, some) else .runtime,
3271532753
};
32716-
} else .{ .host_size = 0, .bit_offset = 0, .alignment = 0 };
32754+
} else .{};
3271732755

3271832756
const alignment: u32 = a: {
3271932757
// Calculate the new pointer alignment.
@@ -32741,6 +32779,6 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
3274132779
.@"volatile" = ptr_info.@"volatile",
3274232780
.@"align" = alignment,
3274332781
.host_size = vector_info.host_size,
32744-
.bit_offset = vector_info.bit_offset,
32782+
.vector_index = vector_info.vector_index,
3274532783
});
3274632784
}

src/arch/aarch64/CodeGen.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
873873

874874
.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
875875
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
876+
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),
876877

877878
.wasm_memory_size => unreachable,
878879
.wasm_memory_grow => unreachable,

src/arch/arm/CodeGen.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
783783

784784
.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
785785
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
786+
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),
786787

787788
.wasm_memory_size => unreachable,
788789
.wasm_memory_grow => unreachable,

src/arch/riscv64/CodeGen.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
697697

698698
.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
699699
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
700+
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),
700701

701702
.wasm_memory_size => unreachable,
702703
.wasm_memory_grow => unreachable,

src/arch/sparc64/CodeGen.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
714714

715715
.is_named_enum_value => @panic("TODO implement is_named_enum_value"),
716716
.error_set_has_value => @panic("TODO implement error_set_has_value"),
717+
.vector_store_elem => @panic("TODO implement vector_store_elem"),
717718

718719
.wasm_memory_size => unreachable,
719720
.wasm_memory_grow => unreachable,

src/arch/wasm/CodeGen.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,6 +1971,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19711971
.is_named_enum_value,
19721972
.error_set_has_value,
19731973
.addrspace_cast,
1974+
.vector_store_elem,
19741975
=> |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
19751976

19761977
.add_optimized,
@@ -2213,6 +2214,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
22132214
const ptr_ty = func.air.typeOf(bin_op.lhs);
22142215
const ptr_info = ptr_ty.ptrInfo().data;
22152216
const ty = ptr_ty.childType();
2217+
22162218
if (ptr_info.host_size == 0) {
22172219
try func.store(lhs, rhs, ty, 0);
22182220
} else {

src/arch/x86_64/CodeGen.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
785785

786786
.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
787787
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
788+
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),
788789

789790
.wasm_memory_size => unreachable,
790791
.wasm_memory_grow => unreachable,

src/codegen/c.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,6 +2908,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
29082908

29092909
.is_named_enum_value => return f.fail("TODO: C backend: implement is_named_enum_value", .{}),
29102910
.error_set_has_value => return f.fail("TODO: C backend: implement error_set_has_value", .{}),
2911+
.vector_store_elem => return f.fail("TODO: C backend: implement vector_store_elem", .{}),
29112912
// zig fmt: on
29122913
};
29132914
if (result_value == .local) {

0 commit comments

Comments
 (0)