Skip to content

Commit

Permalink
port packed vector elem ptr logic from stage1
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexu committed Dec 15, 2022
1 parent 88b49ed commit 4580534
Show file tree
Hide file tree
Showing 18 changed files with 277 additions and 60 deletions.
10 changes: 10 additions & 0 deletions src/Air.zig
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,10 @@ pub const Inst = struct {
/// Uses the `ty_pl` field.
save_err_return_trace_index,

/// Store an element to a vector pointer at an index.
/// Uses the `vector_store_elem` field.
vector_store_elem,

pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag {
switch (op) {
.lt => return if (optimized) .cmp_lt_optimized else .cmp_lt,
Expand Down Expand Up @@ -814,6 +818,11 @@ pub const Inst = struct {
operand: Ref,
operation: std.builtin.ReduceOp,
},
vector_store_elem: struct {
vector_ptr: Ref,
// Index into a different array.
payload: u32,
},

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

.ptrtoint,
Expand Down
15 changes: 15 additions & 0 deletions src/Liveness.zig
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,15 @@ pub fn categorizeOperand(
return .write;
},

.vector_store_elem => {
const o = air_datas[inst].vector_store_elem;
const extra = air.extraData(Air.Bin, o.payload).data;
if (o.vector_ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 2, .none);
return .write;
},

.arg,
.alloc,
.ret_ptr,
Expand Down Expand Up @@ -824,6 +833,12 @@ fn analyzeInst(
return trackOperands(a, new_set, inst, main_tomb, .{ o.lhs, o.rhs, .none });
},

.vector_store_elem => {
const o = inst_datas[inst].vector_store_elem;
const extra = a.air.extraData(Air.Bin, o.payload).data;
return trackOperands(a, new_set, inst, main_tomb, .{ o.vector_ptr, extra.lhs, extra.rhs });
},

.arg,
.alloc,
.ret_ptr,
Expand Down
64 changes: 51 additions & 13 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25952,6 +25952,30 @@ fn storePtr2(

try sema.requireRuntimeBlock(block, src, runtime_src);
try sema.queueFullTypeResolution(elem_ty);

if (ptr_ty.ptrInfo().data.vector_index == .runtime) {
const ptr_inst = Air.refToIndex(ptr).?;
const air_tags = sema.air_instructions.items(.tag);
if (air_tags[ptr_inst] == .ptr_elem_ptr) {
const ty_pl = sema.air_instructions.items(.data)[ptr_inst].ty_pl;
const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data;
_ = try block.addInst(.{
.tag = .vector_store_elem,
.data = .{ .vector_store_elem = .{
.vector_ptr = bin_op.lhs,
.payload = try block.sema.addExtra(Air.Bin{
.lhs = bin_op.rhs,
.rhs = operand,
}),
} },
});
return;
}
return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
ptr_ty.fmt(sema.mod),
});
}

if (is_ret) {
_ = try block.addBinOp(.store, ptr, operand);
} else {
Expand Down Expand Up @@ -27827,6 +27851,19 @@ fn analyzeLoad(
}
}

if (ptr_ty.ptrInfo().data.vector_index == .runtime) {
const ptr_inst = Air.refToIndex(ptr).?;
const air_tags = sema.air_instructions.items(.tag);
if (air_tags[ptr_inst] == .ptr_elem_ptr) {
const ty_pl = sema.air_instructions.items(.data)[ptr_inst].ty_pl;
const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data;
return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);
}
return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
ptr_ty.fmt(sema.mod),
});
}

return block.addTyOp(.load, elem_ty, ptr);
}

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

const VI = Type.Payload.Pointer.Data.VectorIndex;

const vector_info: struct {
host_size: u16,
bit_offset: u16,
alignment: u32,
host_size: u16 = 0,
alignment: u32 = 0,
vector_index: VI = .none,
} = if (parent_ty.tag() == .vector) blk: {
const elem_bits = elem_ty.bitSize(target);
const is_packed = elem_bits != 0 and (elem_bits & (elem_bits - 1)) != 0;
// TODO: runtime-known index
assert(!is_packed or offset != null);
const is_packed_with_offset = is_packed and offset != null and offset.? != 0;
const target_offset = if (is_packed_with_offset) (if (target.cpu.arch.endian() == .Big) (parent_ty.vectorLen() - 1 - offset.?) else offset.?) else 0;
if (elem_bits == 0) break :blk .{};
const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
if (!is_packed) break :blk .{};

break :blk .{
.host_size = if (is_packed_with_offset) @intCast(u16, parent_ty.abiSize(target)) else 0,
.bit_offset = if (is_packed_with_offset) @intCast(u16, elem_bits * target_offset) else 0,
.alignment = if (is_packed_with_offset) @intCast(u16, parent_ty.abiAlignment(target)) else 0,
.host_size = @intCast(u16, parent_ty.arrayLen()),
.alignment = @intCast(u16, parent_ty.abiAlignment(target)),
.vector_index = if (offset) |some| @intToEnum(VI, some) else .runtime,
};
} else .{ .host_size = 0, .bit_offset = 0, .alignment = 0 };
} else .{};

const alignment: u32 = a: {
// Calculate the new pointer alignment.
Expand Down Expand Up @@ -32741,6 +32779,6 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
.@"volatile" = ptr_info.@"volatile",
.@"align" = alignment,
.host_size = vector_info.host_size,
.bit_offset = vector_info.bit_offset,
.vector_index = vector_info.vector_index,
});
}
1 change: 1 addition & 0 deletions src/arch/aarch64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {

.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),

.wasm_memory_size => unreachable,
.wasm_memory_grow => unreachable,
Expand Down
1 change: 1 addition & 0 deletions src/arch/arm/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {

.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),

.wasm_memory_size => unreachable,
.wasm_memory_grow => unreachable,
Expand Down
1 change: 1 addition & 0 deletions src/arch/riscv64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {

.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),

.wasm_memory_size => unreachable,
.wasm_memory_grow => unreachable,
Expand Down
1 change: 1 addition & 0 deletions src/arch/sparc64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {

.is_named_enum_value => @panic("TODO implement is_named_enum_value"),
.error_set_has_value => @panic("TODO implement error_set_has_value"),
.vector_store_elem => @panic("TODO implement vector_store_elem"),

.wasm_memory_size => unreachable,
.wasm_memory_grow => unreachable,
Expand Down
12 changes: 12 additions & 0 deletions src/arch/wasm/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1971,6 +1971,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.is_named_enum_value,
.error_set_has_value,
.addrspace_cast,
.vector_store_elem,
=> |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),

.add_optimized,
Expand Down Expand Up @@ -2213,6 +2214,12 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ptr_ty = func.air.typeOf(bin_op.lhs);
const ptr_info = ptr_ty.ptrInfo().data;
const ty = ptr_ty.childType();

assert(ptr_info.vector_index != .runtime);
if (ptr_info.vector_index != .none) {
return func.fail("TODO: airStore for pointers with a vector index", .{});
}

if (ptr_info.host_size == 0) {
try func.store(lhs, rhs, ty, 0);
} else {
Expand Down Expand Up @@ -2369,6 +2376,11 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
try func.store(new_local, operand, ty, 0);
break :result new_local;
}

assert(ptr_info.vector_index != .runtime);
if (ptr_info.vector_index != .none) {
return func.fail("TODO: airLoad for pointers with a vector index", .{});
}

if (ptr_info.host_size == 0) {
const stack_loaded = try func.load(operand, ty, 0);
Expand Down
1 change: 1 addition & 0 deletions src/arch/x86_64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {

.is_named_enum_value => return self.fail("TODO implement is_named_enum_value", .{}),
.error_set_has_value => return self.fail("TODO implement error_set_has_value", .{}),
.vector_store_elem => return self.fail("TODO implement vector_store_elem", .{}),

.wasm_memory_size => unreachable,
.wasm_memory_grow => unreachable,
Expand Down
11 changes: 11 additions & 0 deletions src/codegen/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2908,6 +2908,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,

.is_named_enum_value => return f.fail("TODO: C backend: implement is_named_enum_value", .{}),
.error_set_has_value => return f.fail("TODO: C backend: implement error_set_has_value", .{}),
.vector_store_elem => return f.fail("TODO: C backend: implement vector_store_elem", .{}),
// zig fmt: on
};
if (result_value == .local) {
Expand Down Expand Up @@ -3194,6 +3195,11 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {

const local = try f.allocLocal(inst, src_ty);

assert(ptr_info.vector_index != .runtime);
if (ptr_info.vector_index != .none) {
return f.fail("TODO: airLoad for pointers with a vector index", .{});
}

if (need_memcpy) {
try writer.writeAll("memcpy(");
if (!is_array) try writer.writeByte('&');
Expand Down Expand Up @@ -3438,6 +3444,11 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue {
const need_memcpy = !is_aligned or is_array;
const writer = f.object.writer();

assert(ptr_info.vector_index != .runtime);
if (ptr_info.vector_index != .none) {
return f.fail("TODO: airStore for pointers with a vector index", .{});
}

if (need_memcpy) {
// For this memcpy to safely work we need the rhs to have the same
// underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
Expand Down
Loading

0 comments on commit 4580534

Please sign in to comment.