mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
stage2: migrate many pointer types to the InternPool
This commit is contained in:
parent
70a4b76aca
commit
9ec0017f46
11 changed files with 157 additions and 90 deletions
14
src/Air.zig
14
src/Air.zig
|
|
@ -1427,8 +1427,11 @@ pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type {
|
|||
const inst_index = ref_int - ref_start_index;
|
||||
const air_tags = air.instructions.items(.tag);
|
||||
const air_datas = air.instructions.items(.data);
|
||||
assert(air_tags[inst_index] == .const_ty);
|
||||
return air_datas[inst_index].ty;
|
||||
return switch (air_tags[inst_index]) {
|
||||
.const_ty => air_datas[inst_index].ty,
|
||||
.interned => air_datas[inst_index].interned.toType(),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the requested data, as well as the new index which is at the start of the
|
||||
|
|
@ -1492,6 +1495,7 @@ pub fn value(air: Air, inst: Inst.Ref, mod: *const Module) ?Value {
|
|||
switch (air.instructions.items(.tag)[inst_index]) {
|
||||
.constant => return air.values[air_datas[inst_index].ty_pl.payload],
|
||||
.const_ty => unreachable,
|
||||
.interned => return air_datas[inst_index].interned.toValue(),
|
||||
else => return air.typeOfIndex(inst_index, mod.intern_pool).onePossibleValue(mod),
|
||||
}
|
||||
}
|
||||
|
|
@ -1717,8 +1721,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: InternPool) bool {
|
|||
=> false,
|
||||
|
||||
.assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0,
|
||||
.load => air.typeOf(data.ty_op.operand, ip).isVolatilePtr(),
|
||||
.slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtr(),
|
||||
.atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtr(),
|
||||
.load => air.typeOf(data.ty_op.operand, ip).isVolatilePtrIp(ip),
|
||||
.slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtrIp(ip),
|
||||
.atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtrIp(ip),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ pub const Key = union(enum) {
|
|||
/// If zero use pointee_type.abiAlignment()
|
||||
/// When creating pointer types, if alignment is equal to pointee type
|
||||
/// abi alignment, this value should be set to 0 instead.
|
||||
alignment: u16 = 0,
|
||||
alignment: u64 = 0,
|
||||
/// If this is non-zero it means the pointer points to a sub-byte
|
||||
/// range of data, which is backed by a "host integer" with this
|
||||
/// number of bytes.
|
||||
|
|
@ -90,9 +90,9 @@ pub const Key = union(enum) {
|
|||
/// an appropriate value for this field.
|
||||
address_space: std.builtin.AddressSpace = .generic,
|
||||
|
||||
pub const VectorIndex = enum(u32) {
|
||||
none = std.math.maxInt(u32),
|
||||
runtime = std.math.maxInt(u32) - 1,
|
||||
pub const VectorIndex = enum(u16) {
|
||||
none = std.math.maxInt(u16),
|
||||
runtime = std.math.maxInt(u16) - 1,
|
||||
_,
|
||||
};
|
||||
};
|
||||
|
|
@ -806,16 +806,33 @@ pub const Pointer = struct {
|
|||
sentinel: Index,
|
||||
flags: Flags,
|
||||
packed_offset: PackedOffset,
|
||||
vector_index: VectorIndex,
|
||||
|
||||
/// Stored as a power-of-two, with one special value to indicate none.
|
||||
pub const Alignment = enum(u6) {
|
||||
none = std.math.maxInt(u6),
|
||||
_,
|
||||
|
||||
pub fn toByteUnits(a: Alignment, default: u64) u64 {
|
||||
return switch (a) {
|
||||
.none => default,
|
||||
_ => @as(u64, 1) << @enumToInt(a),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fromByteUnits(n: u64) Alignment {
|
||||
if (n == 0) return .none;
|
||||
return @intToEnum(Alignment, @ctz(n));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Flags = packed struct(u32) {
|
||||
alignment: u16,
|
||||
size: Size,
|
||||
alignment: Alignment,
|
||||
is_const: bool,
|
||||
is_volatile: bool,
|
||||
is_allowzero: bool,
|
||||
size: Size,
|
||||
address_space: AddressSpace,
|
||||
_: u7 = undefined,
|
||||
vector_index: VectorIndex,
|
||||
};
|
||||
|
||||
pub const PackedOffset = packed struct(u32) {
|
||||
|
|
@ -928,13 +945,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
|
|||
return .{ .ptr_type = .{
|
||||
.elem_type = ptr_info.child,
|
||||
.sentinel = ptr_info.sentinel,
|
||||
.alignment = ptr_info.flags.alignment,
|
||||
.alignment = ptr_info.flags.alignment.toByteUnits(0),
|
||||
.size = ptr_info.flags.size,
|
||||
.is_const = ptr_info.flags.is_const,
|
||||
.is_volatile = ptr_info.flags.is_volatile,
|
||||
.is_allowzero = ptr_info.flags.is_allowzero,
|
||||
.address_space = ptr_info.flags.address_space,
|
||||
.vector_index = ptr_info.vector_index,
|
||||
.vector_index = ptr_info.flags.vector_index,
|
||||
.host_size = ptr_info.packed_offset.host_size,
|
||||
.bit_offset = ptr_info.packed_offset.bit_offset,
|
||||
} };
|
||||
|
|
@ -1003,18 +1020,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
|
|||
.child = ptr_type.elem_type,
|
||||
.sentinel = ptr_type.sentinel,
|
||||
.flags = .{
|
||||
.alignment = ptr_type.alignment,
|
||||
.alignment = Pointer.Alignment.fromByteUnits(ptr_type.alignment),
|
||||
.is_const = ptr_type.is_const,
|
||||
.is_volatile = ptr_type.is_volatile,
|
||||
.is_allowzero = ptr_type.is_allowzero,
|
||||
.size = ptr_type.size,
|
||||
.address_space = ptr_type.address_space,
|
||||
.vector_index = ptr_type.vector_index,
|
||||
},
|
||||
.packed_offset = .{
|
||||
.host_size = ptr_type.host_size,
|
||||
.bit_offset = ptr_type.bit_offset,
|
||||
},
|
||||
.vector_index = ptr_type.vector_index,
|
||||
}),
|
||||
});
|
||||
},
|
||||
|
|
|
|||
42
src/Sema.zig
42
src/Sema.zig
|
|
@ -8400,7 +8400,7 @@ fn analyzeOptionalPayloadPtr(
|
|||
const child_type = opt_type.optionalChild(mod);
|
||||
const child_pointer = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = child_type,
|
||||
.mutable = !optional_ptr_ty.isConstPtr(),
|
||||
.mutable = !optional_ptr_ty.isConstPtr(mod),
|
||||
.@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
|
||||
|
|
@ -8594,7 +8594,7 @@ fn analyzeErrUnionPayloadPtr(
|
|||
const payload_ty = err_union_ty.errorUnionPayload();
|
||||
const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = payload_ty,
|
||||
.mutable = !operand_ty.isConstPtr(),
|
||||
.mutable = !operand_ty.isConstPtr(mod),
|
||||
.@"addrspace" = operand_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
|
||||
|
|
@ -10147,7 +10147,7 @@ fn zirSwitchCapture(
|
|||
const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = field_ty,
|
||||
.mutable = operand_ptr_ty.ptrIsMutable(mod),
|
||||
.@"volatile" = operand_ptr_ty.isVolatilePtr(),
|
||||
.@"volatile" = operand_ptr_ty.isVolatilePtr(mod),
|
||||
.@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
return sema.addConstant(
|
||||
|
|
@ -10166,7 +10166,7 @@ fn zirSwitchCapture(
|
|||
const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = field_ty,
|
||||
.mutable = operand_ptr_ty.ptrIsMutable(mod),
|
||||
.@"volatile" = operand_ptr_ty.isVolatilePtr(),
|
||||
.@"volatile" = operand_ptr_ty.isVolatilePtr(mod),
|
||||
.@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
return block.addStructFieldPtr(operand_ptr, field_index, ptr_field_ty);
|
||||
|
|
@ -15292,10 +15292,10 @@ fn zirCmpEq(
|
|||
}
|
||||
|
||||
// comparing null with optionals
|
||||
if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr())) {
|
||||
if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr(mod))) {
|
||||
return sema.analyzeIsNull(block, src, rhs, op == .neq);
|
||||
}
|
||||
if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr())) {
|
||||
if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr(mod))) {
|
||||
return sema.analyzeIsNull(block, src, lhs, op == .neq);
|
||||
}
|
||||
|
||||
|
|
@ -22254,7 +22254,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
|
|||
const target = sema.mod.getTarget();
|
||||
const mod = sema.mod;
|
||||
|
||||
if (dest_ty.isConstPtr()) {
|
||||
if (dest_ty.isConstPtr(mod)) {
|
||||
return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});
|
||||
}
|
||||
|
||||
|
|
@ -22452,7 +22452,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
|
|||
const dest_ptr_ty = sema.typeOf(dest_ptr);
|
||||
try checkMemOperand(sema, block, dest_src, dest_ptr_ty);
|
||||
|
||||
if (dest_ptr_ty.isConstPtr()) {
|
||||
if (dest_ptr_ty.isConstPtr(mod)) {
|
||||
return sema.fail(block, dest_src, "cannot memset constant pointer", .{});
|
||||
}
|
||||
|
||||
|
|
@ -24206,7 +24206,7 @@ fn fieldPtr(
|
|||
const result_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = slice_ptr_ty,
|
||||
.mutable = attr_ptr_ty.ptrIsMutable(mod),
|
||||
.@"volatile" = attr_ptr_ty.isVolatilePtr(),
|
||||
.@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
|
||||
.@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
|
||||
|
|
@ -24227,7 +24227,7 @@ fn fieldPtr(
|
|||
const result_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = Type.usize,
|
||||
.mutable = attr_ptr_ty.ptrIsMutable(mod),
|
||||
.@"volatile" = attr_ptr_ty.isVolatilePtr(),
|
||||
.@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
|
||||
.@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
|
||||
|
|
@ -24897,7 +24897,7 @@ fn unionFieldPtr(
|
|||
const ptr_field_ty = try Type.ptr(arena, sema.mod, .{
|
||||
.pointee_type = field.ty,
|
||||
.mutable = union_ptr_ty.ptrIsMutable(mod),
|
||||
.@"volatile" = union_ptr_ty.isVolatilePtr(),
|
||||
.@"volatile" = union_ptr_ty.isVolatilePtr(mod),
|
||||
.@"addrspace" = union_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?);
|
||||
|
|
@ -25239,7 +25239,7 @@ fn tupleFieldPtr(
|
|||
const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = field_ty,
|
||||
.mutable = tuple_ptr_ty.ptrIsMutable(mod),
|
||||
.@"volatile" = tuple_ptr_ty.isVolatilePtr(),
|
||||
.@"volatile" = tuple_ptr_ty.isVolatilePtr(mod),
|
||||
.@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),
|
||||
});
|
||||
|
||||
|
|
@ -25767,7 +25767,7 @@ fn coerceExtra(
|
|||
}
|
||||
|
||||
// coercion from C pointer
|
||||
if (inst_ty.isCPtr()) src_c_ptr: {
|
||||
if (inst_ty.isCPtr(mod)) src_c_ptr: {
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :src_c_ptr;
|
||||
// In this case we must add a safety check because the C pointer
|
||||
// could be null.
|
||||
|
|
@ -27255,7 +27255,7 @@ fn storePtr2(
|
|||
) CompileError!void {
|
||||
const mod = sema.mod;
|
||||
const ptr_ty = sema.typeOf(ptr);
|
||||
if (ptr_ty.isConstPtr())
|
||||
if (ptr_ty.isConstPtr(mod))
|
||||
return sema.fail(block, ptr_src, "cannot assign to constant", .{});
|
||||
|
||||
const elem_ty = ptr_ty.childType(mod);
|
||||
|
|
@ -29843,7 +29843,7 @@ fn analyzeSlice(
|
|||
const result = try block.addBitCast(return_ty, new_ptr);
|
||||
if (block.wantSafety()) {
|
||||
// requirement: slicing C ptr is non-null
|
||||
if (ptr_ptr_child_ty.isCPtr()) {
|
||||
if (ptr_ptr_child_ty.isCPtr(mod)) {
|
||||
const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
|
||||
try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
|
||||
}
|
||||
|
|
@ -29902,7 +29902,7 @@ fn analyzeSlice(
|
|||
try sema.requireRuntimeBlock(block, src, runtime_src);
|
||||
if (block.wantSafety()) {
|
||||
// requirement: slicing C ptr is non-null
|
||||
if (ptr_ptr_child_ty.isCPtr()) {
|
||||
if (ptr_ptr_child_ty.isCPtr(mod)) {
|
||||
const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
|
||||
try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
|
||||
}
|
||||
|
|
@ -30720,7 +30720,7 @@ fn resolvePeerTypes(
|
|||
err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);
|
||||
}
|
||||
}
|
||||
seen_const = seen_const or chosen_ty.isConstPtr();
|
||||
seen_const = seen_const or chosen_ty.isConstPtr(mod);
|
||||
chosen = candidate;
|
||||
chosen_i = candidate_i + 1;
|
||||
continue;
|
||||
|
|
@ -30876,12 +30876,12 @@ fn resolvePeerTypes(
|
|||
.Optional => {
|
||||
const opt_child_ty = candidate_ty.optionalChild(mod);
|
||||
if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) {
|
||||
seen_const = seen_const or opt_child_ty.isConstPtr();
|
||||
seen_const = seen_const or opt_child_ty.isConstPtr(mod);
|
||||
any_are_null = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
seen_const = seen_const or chosen_ty.isConstPtr();
|
||||
seen_const = seen_const or chosen_ty.isConstPtr(mod);
|
||||
any_are_null = false;
|
||||
chosen = candidate;
|
||||
chosen_i = candidate_i + 1;
|
||||
|
|
@ -30924,7 +30924,7 @@ fn resolvePeerTypes(
|
|||
.Vector => continue,
|
||||
else => {},
|
||||
},
|
||||
.Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) {
|
||||
.Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr(mod) and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) {
|
||||
if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(mod), candidate_ty, target, src, src)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -31023,7 +31023,7 @@ fn resolvePeerTypes(
|
|||
var info = chosen_ty.ptrInfo(mod);
|
||||
info.sentinel = chosen_child_ty.sentinel(mod);
|
||||
info.size = .Slice;
|
||||
info.mutable = !(seen_const or chosen_child_ty.isConstPtr());
|
||||
info.mutable = !(seen_const or chosen_child_ty.isConstPtr(mod));
|
||||
info.pointee_type = chosen_child_ty.elemType2(mod);
|
||||
|
||||
const new_ptr_ty = try Type.ptr(sema.arena, mod, info);
|
||||
|
|
|
|||
|
|
@ -3430,9 +3430,10 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
|
|||
}
|
||||
|
||||
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const slice_ty = self.typeOf(bin_op.lhs);
|
||||
const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
|
||||
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const ptr_ty = slice_ty.slicePtrFieldType(&buf);
|
||||
|
||||
|
|
@ -3496,9 +3497,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
|||
}
|
||||
|
||||
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const ptr_ty = self.typeOf(bin_op.lhs);
|
||||
const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
|
||||
const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
|
||||
const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
|
||||
const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
|
||||
|
||||
|
|
@ -3869,7 +3871,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
|
|||
break :result MCValue.none;
|
||||
|
||||
const ptr = try self.resolveInst(ty_op.operand);
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
|
||||
if (self.liveness.isUnused(inst) and !is_volatile)
|
||||
break :result MCValue.dead;
|
||||
|
||||
|
|
|
|||
|
|
@ -2428,9 +2428,10 @@ fn ptrElemVal(
|
|||
}
|
||||
|
||||
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const slice_ty = self.typeOf(bin_op.lhs);
|
||||
const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
|
||||
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
|
||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||
const ptr_ty = slice_ty.slicePtrFieldType(&buf);
|
||||
|
||||
|
|
@ -2527,9 +2528,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
|||
}
|
||||
|
||||
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const ptr_ty = self.typeOf(bin_op.lhs);
|
||||
const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
|
||||
const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
|
||||
const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
|
||||
const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
|
||||
|
||||
|
|
@ -2738,7 +2740,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
|
|||
break :result MCValue.none;
|
||||
|
||||
const ptr = try self.resolveInst(ty_op.operand);
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
|
||||
if (self.liveness.isUnused(inst) and !is_volatile)
|
||||
break :result MCValue.dead;
|
||||
|
||||
|
|
|
|||
|
|
@ -1536,7 +1536,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
|
|||
break :result MCValue.none;
|
||||
|
||||
const ptr = try self.resolveInst(ty_op.operand);
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
|
||||
if (self.liveness.isUnused(inst) and !is_volatile)
|
||||
break :result MCValue.dead;
|
||||
|
||||
|
|
|
|||
|
|
@ -1827,7 +1827,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
|
|||
break :result MCValue.none;
|
||||
|
||||
const ptr = try self.resolveInst(ty_op.operand);
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
|
||||
const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
|
||||
if (self.liveness.isUnused(inst) and !is_volatile)
|
||||
break :result MCValue.dead;
|
||||
|
||||
|
|
|
|||
|
|
@ -6117,7 +6117,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
|
|||
try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
|
||||
try f.renderType(writer, ty);
|
||||
try writer.writeByte(')');
|
||||
if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
|
||||
if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
|
||||
try writer.writeAll(" *)");
|
||||
try f.writeCValue(writer, ptr, .Other);
|
||||
try writer.writeAll(", ");
|
||||
|
|
@ -6159,7 +6159,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
|
|||
try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
|
||||
try f.renderType(writer, ty);
|
||||
try writer.writeByte(')');
|
||||
if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
|
||||
if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
|
||||
try writer.writeAll(" *)");
|
||||
try f.writeCValue(writer, ptr, .Other);
|
||||
try writer.writeAll(", ");
|
||||
|
|
@ -6221,7 +6221,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
if (use_atomic) try writer.writeAll("zig_atomic(");
|
||||
try f.renderType(writer, ty);
|
||||
if (use_atomic) try writer.writeByte(')');
|
||||
if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
|
||||
if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
|
||||
try writer.writeAll(" *)");
|
||||
try f.writeCValue(writer, ptr, .Other);
|
||||
try writer.writeAll(", ");
|
||||
|
|
@ -6265,7 +6265,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
try writer.writeAll(", (zig_atomic(");
|
||||
try f.renderType(writer, ty);
|
||||
try writer.writeByte(')');
|
||||
if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
|
||||
if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
|
||||
try writer.writeAll(" *)");
|
||||
try f.writeCValue(writer, ptr, .Other);
|
||||
try writer.writeAll(", ");
|
||||
|
|
@ -6299,7 +6299,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
|
|||
try writer.writeAll("zig_atomic_store((zig_atomic(");
|
||||
try f.renderType(writer, ty);
|
||||
try writer.writeByte(')');
|
||||
if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
|
||||
if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
|
||||
try writer.writeAll(" *)");
|
||||
try f.writeCValue(writer, ptr, .Other);
|
||||
try writer.writeAll(", ");
|
||||
|
|
@ -6365,7 +6365,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
|
|||
return .none;
|
||||
}
|
||||
|
||||
if (elem_abi_size > 1 or dest_ty.isVolatilePtr()) {
|
||||
if (elem_abi_size > 1 or dest_ty.isVolatilePtr(mod)) {
|
||||
// For the assignment in this loop, the array pointer needs to get
|
||||
// casted to a regular pointer, otherwise an error like this occurs:
|
||||
// error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable
|
||||
|
|
|
|||
|
|
@ -7046,7 +7046,7 @@ pub const FuncGen = struct {
|
|||
const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType(mod));
|
||||
const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
|
||||
load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
|
||||
load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr()));
|
||||
load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod)));
|
||||
break :blk load_inst;
|
||||
};
|
||||
const modified_vector = self.builder.buildInsertElement(loaded_vector, operand, index, "");
|
||||
|
|
@ -8221,7 +8221,7 @@ pub const FuncGen = struct {
|
|||
const usize_llvm_ty = try self.dg.lowerType(Type.usize);
|
||||
const len = usize_llvm_ty.constInt(operand_size, .False);
|
||||
const dest_ptr_align = ptr_ty.ptrAlignment(mod);
|
||||
_ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr());
|
||||
_ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
|
||||
if (safety and mod.comp.bin_file.options.valgrind) {
|
||||
self.valgrindMarkUndef(dest_ptr, len);
|
||||
}
|
||||
|
|
@ -8497,7 +8497,7 @@ pub const FuncGen = struct {
|
|||
const dest_ptr_align = ptr_ty.ptrAlignment(mod);
|
||||
const u8_llvm_ty = self.context.intType(8);
|
||||
const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
|
||||
const is_volatile = ptr_ty.isVolatilePtr();
|
||||
const is_volatile = ptr_ty.isVolatilePtr(mod);
|
||||
|
||||
if (self.air.value(bin_op.rhs, mod)) |elem_val| {
|
||||
if (elem_val.isUndefDeep()) {
|
||||
|
|
@ -8621,7 +8621,7 @@ pub const FuncGen = struct {
|
|||
const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
|
||||
const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
|
||||
const mod = self.dg.module;
|
||||
const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
|
||||
const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);
|
||||
_ = self.builder.buildMemCpy(
|
||||
dest_ptr,
|
||||
dest_ptr_ty.ptrAlignment(mod),
|
||||
|
|
@ -9894,7 +9894,7 @@ pub const FuncGen = struct {
|
|||
if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null;
|
||||
|
||||
const ptr_alignment = info.alignment(mod);
|
||||
const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
|
||||
const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr(mod));
|
||||
|
||||
assert(info.vector_index != .runtime);
|
||||
if (info.vector_index != .none) {
|
||||
|
|
|
|||
|
|
@ -1689,7 +1689,7 @@ pub const DeclGen = struct {
|
|||
const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect);
|
||||
const result_id = self.spv.allocId();
|
||||
const access = spec.MemoryAccess.Extended{
|
||||
.Volatile = ptr_ty.isVolatilePtr(),
|
||||
.Volatile = ptr_ty.isVolatilePtr(mod),
|
||||
};
|
||||
try self.func.body.emit(self.spv.gpa, .OpLoad, .{
|
||||
.id_result_type = self.typeId(indirect_value_ty_ref),
|
||||
|
|
@ -1705,7 +1705,7 @@ pub const DeclGen = struct {
|
|||
const value_ty = ptr_ty.childType(mod);
|
||||
const indirect_value_id = try self.convertToIndirect(value_ty, value_id);
|
||||
const access = spec.MemoryAccess.Extended{
|
||||
.Volatile = ptr_ty.isVolatilePtr(),
|
||||
.Volatile = ptr_ty.isVolatilePtr(mod),
|
||||
};
|
||||
try self.func.body.emit(self.spv.gpa, .OpStore, .{
|
||||
.pointer = ptr_id,
|
||||
|
|
@ -2464,9 +2464,10 @@ pub const DeclGen = struct {
|
|||
}
|
||||
|
||||
fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
const mod = self.module;
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const slice_ty = self.typeOf(bin_op.lhs);
|
||||
if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
|
||||
if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
|
||||
|
||||
const slice_id = try self.resolve(bin_op.lhs);
|
||||
const index_id = try self.resolve(bin_op.rhs);
|
||||
|
|
@ -2479,9 +2480,10 @@ pub const DeclGen = struct {
|
|||
}
|
||||
|
||||
fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
const mod = self.module;
|
||||
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
|
||||
const slice_ty = self.typeOf(bin_op.lhs);
|
||||
if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
|
||||
if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
|
||||
|
||||
const slice_id = try self.resolve(bin_op.lhs);
|
||||
const index_id = try self.resolve(bin_op.rhs);
|
||||
|
|
@ -2781,10 +2783,11 @@ pub const DeclGen = struct {
|
|||
}
|
||||
|
||||
fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
|
||||
const mod = self.module;
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const ptr_ty = self.typeOf(ty_op.operand);
|
||||
const operand = try self.resolve(ty_op.operand);
|
||||
if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
|
||||
if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
|
||||
|
||||
return try self.load(ptr_ty, operand);
|
||||
}
|
||||
|
|
|
|||
95
src/type.zig
95
src/type.zig
|
|
@ -193,7 +193,7 @@ pub const Type = struct {
|
|||
.Frame,
|
||||
=> false,
|
||||
|
||||
.Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr()),
|
||||
.Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr(mod)),
|
||||
.Optional => {
|
||||
if (!is_equality_cmp) return false;
|
||||
return ty.optionalChild(mod).isSelfComparable(mod, is_equality_cmp);
|
||||
|
|
@ -3012,38 +3012,59 @@ pub const Type = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn isConstPtr(self: Type) bool {
|
||||
return switch (self.tag()) {
|
||||
.pointer => !self.castTag(.pointer).?.data.mutable,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isVolatilePtr(self: Type) bool {
|
||||
return switch (self.tag()) {
|
||||
.pointer => {
|
||||
const payload = self.castTag(.pointer).?.data;
|
||||
return payload.@"volatile";
|
||||
pub fn isConstPtr(ty: Type, mod: *const Module) bool {
|
||||
return switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.pointer => !ty.castTag(.pointer).?.data.mutable,
|
||||
else => false,
|
||||
},
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isAllowzeroPtr(self: Type, mod: *const Module) bool {
|
||||
return switch (self.tag()) {
|
||||
.pointer => {
|
||||
const payload = self.castTag(.pointer).?.data;
|
||||
return payload.@"allowzero";
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_type| ptr_type.is_const,
|
||||
else => false,
|
||||
},
|
||||
else => return self.zigTypeTag(mod) == .Optional,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isCPtr(self: Type) bool {
|
||||
return switch (self.tag()) {
|
||||
.pointer => self.castTag(.pointer).?.data.size == .C,
|
||||
pub fn isVolatilePtr(ty: Type, mod: *const Module) bool {
|
||||
return isVolatilePtrIp(ty, mod.intern_pool);
|
||||
}
|
||||
|
||||
else => return false,
|
||||
pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool {
|
||||
return switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.pointer => ty.castTag(.pointer).?.data.@"volatile",
|
||||
else => false,
|
||||
},
|
||||
else => switch (ip.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_type| ptr_type.is_volatile,
|
||||
else => false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool {
|
||||
return switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.pointer => ty.castTag(.pointer).?.data.@"allowzero",
|
||||
else => ty.zigTypeTag(mod) == .Optional,
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_type| ptr_type.is_allowzero,
|
||||
else => false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isCPtr(ty: Type, mod: *const Module) bool {
|
||||
return switch (ty.ip_index) {
|
||||
.none => switch (ty.tag()) {
|
||||
.pointer => ty.castTag(.pointer).?.data.size == .C,
|
||||
else => false,
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.ptr_type => |ptr_type| ptr_type.size == .C,
|
||||
else => false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -5063,7 +5084,7 @@ pub const Type = struct {
|
|||
return .{
|
||||
.pointee_type = p.elem_type.toType(),
|
||||
.sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
|
||||
.@"align" = p.alignment,
|
||||
.@"align" = @intCast(u32, p.alignment),
|
||||
.@"addrspace" = p.address_space,
|
||||
.bit_offset = p.bit_offset,
|
||||
.host_size = p.host_size,
|
||||
|
|
@ -5248,6 +5269,24 @@ pub const Type = struct {
|
|||
}
|
||||
}
|
||||
|
||||
if (d.pointee_type.ip_index != .none and
|
||||
(d.sentinel == null or d.sentinel.?.ip_index != .none))
|
||||
{
|
||||
return mod.ptrType(.{
|
||||
.elem_type = d.pointee_type.ip_index,
|
||||
.sentinel = if (d.sentinel) |s| s.ip_index else .none,
|
||||
.alignment = d.@"align",
|
||||
.host_size = d.host_size,
|
||||
.bit_offset = d.bit_offset,
|
||||
.vector_index = d.vector_index,
|
||||
.size = d.size,
|
||||
.is_const = !d.mutable,
|
||||
.is_volatile = d.@"volatile",
|
||||
.is_allowzero = d.@"allowzero",
|
||||
.address_space = d.@"addrspace",
|
||||
});
|
||||
}
|
||||
|
||||
return Type.Tag.pointer.create(arena, d);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue