mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Revert "stage2: implement @prefetch"
This reverts commit d48e4245b68bf25c7f41804a5012ac157a5ee546. I have no idea why this is failing Drone CI, but in a branch, reverting this commit solved the problem.
This commit is contained in:
parent
4938fb8f5c
commit
f423b5949b
@ -643,12 +643,12 @@ pub const PrefetchOptions = struct {
|
||||
/// The cache that the prefetch should be preformed on.
|
||||
cache: Cache = .data,
|
||||
|
||||
pub const Rw = enum(u1) {
|
||||
pub const Rw = enum {
|
||||
read,
|
||||
write,
|
||||
};
|
||||
|
||||
pub const Cache = enum(u1) {
|
||||
pub const Cache = enum {
|
||||
instruction,
|
||||
data,
|
||||
};
|
||||
|
||||
12
src/Air.zig
12
src/Air.zig
@ -515,11 +515,6 @@ pub const Inst = struct {
|
||||
/// is a `Ref`. Length of the array is given by the vector type.
|
||||
vector_init,
|
||||
|
||||
/// Communicates an intent to load memory.
|
||||
/// Result is always unused.
|
||||
/// Uses the `prefetch` field.
|
||||
prefetch,
|
||||
|
||||
pub fn fromCmpOp(op: std.math.CompareOperator) Tag {
|
||||
return switch (op) {
|
||||
.lt => .cmp_lt,
|
||||
@ -591,12 +586,6 @@ pub const Inst = struct {
|
||||
ptr: Ref,
|
||||
order: std.builtin.AtomicOrder,
|
||||
},
|
||||
prefetch: struct {
|
||||
ptr: Ref,
|
||||
rw: std.builtin.PrefetchOptions.Rw,
|
||||
locality: u2,
|
||||
cache: std.builtin.PrefetchOptions.Cache,
|
||||
},
|
||||
|
||||
// Make sure we don't accidentally add a field to make this union
|
||||
// bigger than expected. Note that in Debug builds, Zig is allowed
|
||||
@ -834,7 +823,6 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
|
||||
.memset,
|
||||
.memcpy,
|
||||
.set_union_tag,
|
||||
.prefetch,
|
||||
=> return Type.initTag(.void),
|
||||
|
||||
.ptrtoint,
|
||||
|
||||
@ -342,11 +342,6 @@ fn analyzeInst(
|
||||
return trackOperands(a, new_set, inst, main_tomb, .{ operand, .none, .none });
|
||||
},
|
||||
|
||||
.prefetch => {
|
||||
const prefetch = inst_datas[inst].prefetch;
|
||||
return trackOperands(a, new_set, inst, main_tomb, .{ prefetch.ptr, .none, .none });
|
||||
},
|
||||
|
||||
.call => {
|
||||
const inst_data = inst_datas[inst].pl_op;
|
||||
const callee = inst_data.operand;
|
||||
|
||||
120
src/Sema.zig
120
src/Sema.zig
@ -10316,53 +10316,49 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = inst_data.src();
|
||||
const obj_ty = try sema.resolveType(block, src, inst_data.operand);
|
||||
const gpa = sema.gpa;
|
||||
|
||||
switch (obj_ty.zigTypeTag()) {
|
||||
.Struct => return structInitEmpty(sema, block, obj_ty, src, src),
|
||||
.Array => return arrayInitEmpty(sema, obj_ty),
|
||||
.Struct => {
|
||||
// This logic must be synchronized with that in `zirStructInit`.
|
||||
const struct_ty = try sema.resolveTypeFields(block, src, obj_ty);
|
||||
const struct_obj = struct_ty.castTag(.@"struct").?.data;
|
||||
|
||||
// The init values to use for the struct instance.
|
||||
const field_inits = try gpa.alloc(Air.Inst.Ref, struct_obj.fields.count());
|
||||
defer gpa.free(field_inits);
|
||||
|
||||
var root_msg: ?*Module.ErrorMsg = null;
|
||||
|
||||
for (struct_obj.fields.values()) |field, i| {
|
||||
if (field.default_val.tag() == .unreachable_value) {
|
||||
const field_name = struct_obj.fields.keys()[i];
|
||||
const template = "missing struct field: {s}";
|
||||
const args = .{field_name};
|
||||
if (root_msg) |msg| {
|
||||
try sema.errNote(block, src, msg, template, args);
|
||||
} else {
|
||||
root_msg = try sema.errMsg(block, src, template, args);
|
||||
}
|
||||
} else {
|
||||
field_inits[i] = try sema.addConstant(field.ty, field.default_val);
|
||||
}
|
||||
}
|
||||
return sema.finishStructInit(block, src, field_inits, root_msg, struct_obj, struct_ty, false);
|
||||
},
|
||||
.Array => {
|
||||
if (obj_ty.sentinel()) |sentinel| {
|
||||
const val = try Value.Tag.empty_array_sentinel.create(sema.arena, sentinel);
|
||||
return sema.addConstant(obj_ty, val);
|
||||
} else {
|
||||
return sema.addConstant(obj_ty, Value.initTag(.empty_array));
|
||||
}
|
||||
},
|
||||
.Void => return sema.addConstant(obj_ty, Value.void),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn structInitEmpty(sema: *Sema, block: *Block, obj_ty: Type, dest_src: LazySrcLoc, init_src: LazySrcLoc) CompileError!Air.Inst.Ref {
|
||||
const gpa = sema.gpa;
|
||||
// This logic must be synchronized with that in `zirStructInit`.
|
||||
const struct_ty = try sema.resolveTypeFields(block, dest_src, obj_ty);
|
||||
const struct_obj = struct_ty.castTag(.@"struct").?.data;
|
||||
|
||||
// The init values to use for the struct instance.
|
||||
const field_inits = try gpa.alloc(Air.Inst.Ref, struct_obj.fields.count());
|
||||
defer gpa.free(field_inits);
|
||||
|
||||
var root_msg: ?*Module.ErrorMsg = null;
|
||||
|
||||
for (struct_obj.fields.values()) |field, i| {
|
||||
if (field.default_val.tag() == .unreachable_value) {
|
||||
const field_name = struct_obj.fields.keys()[i];
|
||||
const template = "missing struct field: {s}";
|
||||
const args = .{field_name};
|
||||
if (root_msg) |msg| {
|
||||
try sema.errNote(block, init_src, msg, template, args);
|
||||
} else {
|
||||
root_msg = try sema.errMsg(block, init_src, template, args);
|
||||
}
|
||||
} else {
|
||||
field_inits[i] = try sema.addConstant(field.ty, field.default_val);
|
||||
}
|
||||
}
|
||||
return sema.finishStructInit(block, dest_src, field_inits, root_msg, struct_obj, struct_ty, false);
|
||||
}
|
||||
|
||||
fn arrayInitEmpty(sema: *Sema, obj_ty: Type) CompileError!Air.Inst.Ref {
|
||||
if (obj_ty.sentinel()) |sentinel| {
|
||||
const val = try Value.Tag.empty_array_sentinel.create(sema.arena, sentinel);
|
||||
return sema.addConstant(obj_ty, val);
|
||||
} else {
|
||||
return sema.addConstant(obj_ty, Value.initTag(.empty_array));
|
||||
}
|
||||
}
|
||||
|
||||
fn zirUnionInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
@ -12330,38 +12326,8 @@ fn zirPrefetch(
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
|
||||
const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
|
||||
const opts_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
|
||||
const options_ty = try sema.getBuiltinType(block, opts_src, "PrefetchOptions");
|
||||
const ptr = sema.resolveInst(extra.lhs);
|
||||
try sema.checkPtrType(block, ptr_src, sema.typeOf(ptr));
|
||||
const options = try sema.coerce(block, options_ty, sema.resolveInst(extra.rhs), opts_src);
|
||||
|
||||
const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src);
|
||||
const rw_val = try sema.resolveConstValue(block, opts_src, rw);
|
||||
const rw_tag = rw_val.toEnum(std.builtin.PrefetchOptions.Rw);
|
||||
|
||||
const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src);
|
||||
const locality_val = try sema.resolveConstValue(block, opts_src, locality);
|
||||
const locality_int = @intCast(u2, locality_val.toUnsignedInt());
|
||||
|
||||
const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src);
|
||||
const cache_val = try sema.resolveConstValue(block, opts_src, cache);
|
||||
const cache_tag = cache_val.toEnum(std.builtin.PrefetchOptions.Cache);
|
||||
|
||||
if (!block.is_comptime) {
|
||||
_ = try block.addInst(.{
|
||||
.tag = .prefetch,
|
||||
.data = .{ .prefetch = .{
|
||||
.ptr = ptr,
|
||||
.rw = rw_tag,
|
||||
.locality = locality_int,
|
||||
.cache = cache_tag,
|
||||
} },
|
||||
});
|
||||
}
|
||||
|
||||
return Air.Inst.Ref.void_value;
|
||||
const src: LazySrcLoc = .{ .node_offset = extra.node };
|
||||
return sema.fail(block, src, "TODO: implement Sema.zirPrefetch", .{});
|
||||
}
|
||||
|
||||
fn zirBuiltinExtern(
|
||||
@ -13821,11 +13787,6 @@ fn coerce(
|
||||
},
|
||||
.Array => switch (inst_ty.zigTypeTag()) {
|
||||
.Vector => return sema.coerceVectorInMemory(block, dest_ty, dest_ty_src, inst, inst_src),
|
||||
.Struct => {
|
||||
if (inst == .empty_struct) {
|
||||
return arrayInitEmpty(sema, dest_ty);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.Vector => switch (inst_ty.zigTypeTag()) {
|
||||
@ -13833,11 +13794,6 @@ fn coerce(
|
||||
.Vector => return sema.coerceVectors(block, dest_ty, dest_ty_src, inst, inst_src),
|
||||
else => {},
|
||||
},
|
||||
.Struct => {
|
||||
if (inst == .empty_struct) {
|
||||
return structInitEmpty(sema, block, dest_ty, dest_ty_src, inst_src);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
|
||||
@ -595,7 +595,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.error_name => try self.airErrorName(inst),
|
||||
.splat => try self.airSplat(inst),
|
||||
.vector_init => try self.airVectorInit(inst),
|
||||
.prefetch => try self.airPrefetch(inst),
|
||||
|
||||
.atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),
|
||||
.atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),
|
||||
@ -2598,11 +2597,6 @@ fn airVectorInit(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return bt.finishAir(result);
|
||||
}
|
||||
|
||||
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
|
||||
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
|
||||
}
|
||||
|
||||
fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
|
||||
// First section of indexes correspond to a set number of constant values.
|
||||
const ref_int = @enumToInt(inst);
|
||||
|
||||
@ -586,7 +586,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.error_name => try self.airErrorName(inst),
|
||||
.splat => try self.airSplat(inst),
|
||||
.vector_init => try self.airVectorInit(inst),
|
||||
.prefetch => try self.airPrefetch(inst),
|
||||
|
||||
.atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),
|
||||
.atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),
|
||||
@ -3694,11 +3693,6 @@ fn airVectorInit(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return bt.finishAir(result);
|
||||
}
|
||||
|
||||
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
|
||||
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
|
||||
}
|
||||
|
||||
fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
|
||||
// First section of indexes correspond to a set number of constant values.
|
||||
const ref_int = @enumToInt(inst);
|
||||
|
||||
@ -574,7 +574,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.error_name => try self.airErrorName(inst),
|
||||
.splat => try self.airSplat(inst),
|
||||
.vector_init => try self.airVectorInit(inst),
|
||||
.prefetch => try self.airPrefetch(inst),
|
||||
|
||||
.atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),
|
||||
.atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),
|
||||
@ -2097,11 +2096,6 @@ fn airVectorInit(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return bt.finishAir(result);
|
||||
}
|
||||
|
||||
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
|
||||
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
|
||||
}
|
||||
|
||||
fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
|
||||
// First section of indexes correspond to a set number of constant values.
|
||||
const ref_int = @enumToInt(inst);
|
||||
|
||||
@ -1297,9 +1297,6 @@ fn copyLocal(self: *Self, value: WValue, ty: Type) InnerError!WValue {
|
||||
fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
const air_tags = self.air.instructions.items(.tag);
|
||||
return switch (air_tags[inst]) {
|
||||
.constant => unreachable,
|
||||
.const_ty => unreachable,
|
||||
|
||||
.add => self.airBinOp(inst, .add),
|
||||
.addwrap => self.airWrapBinOp(inst, .add),
|
||||
.sub => self.airBinOp(inst, .sub),
|
||||
@ -1333,6 +1330,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.bool_to_int => self.airBoolToInt(inst),
|
||||
.call => self.airCall(inst),
|
||||
.cond_br => self.airCondBr(inst),
|
||||
.constant => unreachable,
|
||||
.dbg_stmt => WValue.none,
|
||||
.intcast => self.airIntcast(inst),
|
||||
.float_to_int => self.airFloatToInt(inst),
|
||||
@ -1360,9 +1358,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.ret => self.airRet(inst),
|
||||
.ret_ptr => self.airRetPtr(inst),
|
||||
.ret_load => self.airRetLoad(inst),
|
||||
.splat => self.airSplat(inst),
|
||||
.vector_init => self.airVectorInit(inst),
|
||||
.prefetch => self.airPrefetch(inst),
|
||||
|
||||
.slice => self.airSlice(inst),
|
||||
.slice_len => self.airSliceLen(inst),
|
||||
@ -1387,55 +1382,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.unwrap_errunion_err => self.airUnwrapErrUnionError(inst),
|
||||
.wrap_errunion_payload => self.airWrapErrUnionPayload(inst),
|
||||
.wrap_errunion_err => self.airWrapErrUnionErr(inst),
|
||||
|
||||
.add_sat,
|
||||
.sub_sat,
|
||||
.mul_sat,
|
||||
.div_float,
|
||||
.div_floor,
|
||||
.div_exact,
|
||||
.rem,
|
||||
.mod,
|
||||
.max,
|
||||
.min,
|
||||
.assembly,
|
||||
.shl_exact,
|
||||
.shl_sat,
|
||||
.ret_addr,
|
||||
.clz,
|
||||
.ctz,
|
||||
.popcount,
|
||||
.is_err_ptr,
|
||||
.is_non_err_ptr,
|
||||
.fptrunc,
|
||||
.fpext,
|
||||
.unwrap_errunion_payload_ptr,
|
||||
.unwrap_errunion_err_ptr,
|
||||
.set_union_tag,
|
||||
.get_union_tag,
|
||||
.ptr_slice_len_ptr,
|
||||
.ptr_slice_ptr_ptr,
|
||||
.int_to_float,
|
||||
.memcpy,
|
||||
.cmpxchg_weak,
|
||||
.cmpxchg_strong,
|
||||
.fence,
|
||||
.atomic_load,
|
||||
.atomic_store_unordered,
|
||||
.atomic_store_monotonic,
|
||||
.atomic_store_release,
|
||||
.atomic_store_seq_cst,
|
||||
.atomic_rmw,
|
||||
.tag_name,
|
||||
.error_name,
|
||||
|
||||
// For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248
|
||||
// is implemented in the frontend before implementing them here in the wasm backend.
|
||||
.add_with_overflow,
|
||||
.sub_with_overflow,
|
||||
.mul_with_overflow,
|
||||
.shl_with_overflow,
|
||||
=> |tag| self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
|
||||
else => |tag| self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
|
||||
};
|
||||
}
|
||||
|
||||
@ -3264,7 +3211,7 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
|
||||
if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
|
||||
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
@ -3275,7 +3222,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
return self.fail("TODO: Implement wasm airSplat", .{});
|
||||
}
|
||||
|
||||
fn airVectorInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
fn airVectorInit(self: *Self, inst: Air.Inst.Index) !void {
|
||||
if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
|
||||
|
||||
const vector_ty = self.air.typeOfIndex(inst);
|
||||
@ -3287,12 +3234,6 @@ fn airVectorInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
return self.fail("TODO: Wasm backend: implement airVectorInit", .{});
|
||||
}
|
||||
|
||||
fn airPrefetch(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
|
||||
_ = prefetch;
|
||||
return WValue{ .none = {} };
|
||||
}
|
||||
|
||||
fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
|
||||
assert(operand_ty.hasCodeGenBits());
|
||||
assert(op == .eq or op == .neq);
|
||||
|
||||
@ -638,7 +638,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.error_name => try self.airErrorName(inst),
|
||||
.splat => try self.airSplat(inst),
|
||||
.vector_init => try self.airVectorInit(inst),
|
||||
.prefetch => try self.airPrefetch(inst),
|
||||
|
||||
.atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),
|
||||
.atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),
|
||||
@ -3747,11 +3746,6 @@ fn airVectorInit(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return bt.finishAir(result);
|
||||
}
|
||||
|
||||
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
|
||||
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
|
||||
}
|
||||
|
||||
fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
|
||||
// First section of indexes correspond to a set number of constant values.
|
||||
const ref_int = @enumToInt(inst);
|
||||
|
||||
@ -1278,7 +1278,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
|
||||
.error_name => try airErrorName(f, inst),
|
||||
.splat => try airSplat(f, inst),
|
||||
.vector_init => try airVectorInit(f, inst),
|
||||
.prefetch => try airPrefetch(f, inst),
|
||||
|
||||
.int_to_float,
|
||||
.float_to_int,
|
||||
@ -3090,18 +3089,6 @@ fn airVectorInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
return f.fail("TODO: C backend: implement airVectorInit", .{});
|
||||
}
|
||||
|
||||
fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const prefetch = f.air.instructions.items(.data)[inst].prefetch;
|
||||
const ptr = try f.resolveInst(prefetch.ptr);
|
||||
const writer = f.object.writer();
|
||||
try writer.writeAll("zig_prefetch(");
|
||||
try f.writeCValue(writer, ptr);
|
||||
try writer.print(", {d}, {d});\n", .{
|
||||
@enumToInt(prefetch.rw), prefetch.locality,
|
||||
});
|
||||
return CValue.none;
|
||||
}
|
||||
|
||||
fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
|
||||
return switch (order) {
|
||||
.Unordered => "memory_order_relaxed",
|
||||
|
||||
@ -2073,7 +2073,6 @@ pub const FuncGen = struct {
|
||||
.error_name => try self.airErrorName(inst),
|
||||
.splat => try self.airSplat(inst),
|
||||
.vector_init => try self.airVectorInit(inst),
|
||||
.prefetch => try self.airPrefetch(inst),
|
||||
|
||||
.atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),
|
||||
.atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),
|
||||
@ -4385,67 +4384,6 @@ pub const FuncGen = struct {
|
||||
return vector;
|
||||
}
|
||||
|
||||
fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
|
||||
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
|
||||
|
||||
comptime assert(@enumToInt(std.builtin.PrefetchOptions.Rw.read) == 0);
|
||||
comptime assert(@enumToInt(std.builtin.PrefetchOptions.Rw.write) == 1);
|
||||
|
||||
// TODO these two asserts should be able to be comptime because the type is a u2
|
||||
assert(prefetch.locality >= 0);
|
||||
assert(prefetch.locality <= 3);
|
||||
|
||||
comptime assert(@enumToInt(std.builtin.PrefetchOptions.Cache.instruction) == 0);
|
||||
comptime assert(@enumToInt(std.builtin.PrefetchOptions.Cache.data) == 1);
|
||||
|
||||
// LLVM fails during codegen of instruction cache prefetchs for these architectures.
|
||||
// This is an LLVM bug as the prefetch intrinsic should be a noop if not supported
|
||||
// by the target.
|
||||
// To work around this, don't emit llvm.prefetch in this case.
|
||||
// See https://bugs.llvm.org/show_bug.cgi?id=21037
|
||||
const target = self.dg.module.getTarget();
|
||||
switch (prefetch.cache) {
|
||||
.instruction => switch (target.cpu.arch) {
|
||||
.x86_64, .i386 => return null,
|
||||
.arm, .armeb, .thumb, .thumbeb => {
|
||||
switch (prefetch.rw) {
|
||||
.write => return null,
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.data => {},
|
||||
}
|
||||
|
||||
const llvm_u8 = self.context.intType(8);
|
||||
const llvm_ptr_u8 = llvm_u8.pointerType(0);
|
||||
const llvm_u32 = self.context.intType(32);
|
||||
|
||||
const llvm_fn_name = "llvm.prefetch.p0i8";
|
||||
const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
|
||||
// declare void @llvm.prefetch(i8*, i32, i32, i32)
|
||||
const llvm_void = self.context.voidType();
|
||||
const param_types = [_]*const llvm.Type{
|
||||
llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32,
|
||||
};
|
||||
const fn_type = llvm.functionType(llvm_void, ¶m_types, param_types.len, .False);
|
||||
break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
|
||||
};
|
||||
|
||||
const ptr = try self.resolveInst(prefetch.ptr);
|
||||
const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, "");
|
||||
|
||||
const params = [_]*const llvm.Value{
|
||||
ptr_u8,
|
||||
llvm_u32.constInt(@enumToInt(prefetch.rw), .False),
|
||||
llvm_u32.constInt(prefetch.locality, .False),
|
||||
llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
|
||||
};
|
||||
_ = self.builder.buildCall(fn_val, ¶ms, params.len, .C, .Auto, "");
|
||||
return null;
|
||||
}
|
||||
|
||||
fn getErrorNameTable(self: *FuncGen) !*const llvm.Value {
|
||||
if (self.dg.object.error_name_table) |table| {
|
||||
return table;
|
||||
|
||||
@ -74,12 +74,6 @@
|
||||
#define zig_frame_address() 0
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
|
||||
#else
|
||||
#define zig_prefetch(addr, rw, locality)
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
|
||||
#include <stdatomic.h>
|
||||
#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
|
||||
|
||||
@ -226,7 +226,6 @@ const Writer = struct {
|
||||
.cmpxchg_weak, .cmpxchg_strong => try w.writeCmpxchg(s, inst),
|
||||
.fence => try w.writeFence(s, inst),
|
||||
.atomic_load => try w.writeAtomicLoad(s, inst),
|
||||
.prefetch => try w.writePrefetch(s, inst),
|
||||
.atomic_store_unordered => try w.writeAtomicStore(s, inst, .Unordered),
|
||||
.atomic_store_monotonic => try w.writeAtomicStore(s, inst, .Monotonic),
|
||||
.atomic_store_release => try w.writeAtomicStore(s, inst, .Release),
|
||||
@ -351,15 +350,6 @@ const Writer = struct {
|
||||
try s.print(", {s}", .{@tagName(atomic_load.order)});
|
||||
}
|
||||
|
||||
fn writePrefetch(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const prefetch = w.air.instructions.items(.data)[inst].prefetch;
|
||||
|
||||
try w.writeOperand(s, inst, 0, prefetch.ptr);
|
||||
try s.print(", {s}, {d}, {s}", .{
|
||||
@tagName(prefetch.rw), prefetch.locality, @tagName(prefetch.cache),
|
||||
});
|
||||
}
|
||||
|
||||
fn writeAtomicStore(
|
||||
w: *Writer,
|
||||
s: anytype,
|
||||
|
||||
@ -10,7 +10,6 @@ test {
|
||||
_ = @import("behavior/fn_in_struct_in_comptime.zig");
|
||||
_ = @import("behavior/hasdecl.zig");
|
||||
_ = @import("behavior/hasfield.zig");
|
||||
_ = @import("behavior/prefetch.zig");
|
||||
_ = @import("behavior/pub_enum.zig");
|
||||
_ = @import("behavior/type_info.zig");
|
||||
_ = @import("behavior/type.zig");
|
||||
@ -179,6 +178,7 @@ test {
|
||||
_ = @import("behavior/optional_stage1.zig");
|
||||
_ = @import("behavior/pointers_stage1.zig");
|
||||
_ = @import("behavior/popcount_stage1.zig");
|
||||
_ = @import("behavior/prefetch.zig");
|
||||
_ = @import("behavior/ptrcast_stage1.zig");
|
||||
_ = @import("behavior/reflection.zig");
|
||||
_ = @import("behavior/saturating_arithmetic_stage1.zig");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user