authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-05 16:32:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:28-07:00
log9ec0017f460854300004ab263bf585c2d376d1fb
treedf586141cc238241a5ce4d9898a119c217baf78c
parent70a4b76acaef8d4062f4d5317af398929ea6c9c4

stage2: migrate many pointer types to the InternPool


11 files changed, 152 insertions(+), 85 deletions(-)

src/Air.zig+9-5
......@@ -1427,8 +1427,11 @@ pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type {
14271427 const inst_index = ref_int - ref_start_index;
14281428 const air_tags = air.instructions.items(.tag);
14291429 const air_datas = air.instructions.items(.data);
1430 assert(air_tags[inst_index] == .const_ty);
1431 return air_datas[inst_index].ty;
1430 return switch (air_tags[inst_index]) {
1431 .const_ty => air_datas[inst_index].ty,
1432 .interned => air_datas[inst_index].interned.toType(),
1433 else => unreachable,
1434 };
14321435}
14331436
14341437/// 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 {
14921495 switch (air.instructions.items(.tag)[inst_index]) {
14931496 .constant => return air.values[air_datas[inst_index].ty_pl.payload],
14941497 .const_ty => unreachable,
1498 .interned => return air_datas[inst_index].interned.toValue(),
14951499 else => return air.typeOfIndex(inst_index, mod.intern_pool).onePossibleValue(mod),
14961500 }
14971501}
......@@ -1717,8 +1721,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: InternPool) bool {
17171721 => false,
17181722
17191723 .assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0,
1720 .load => air.typeOf(data.ty_op.operand, ip).isVolatilePtr(),
1721 .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtr(),
1722 .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtr(),
1724 .load => air.typeOf(data.ty_op.operand, ip).isVolatilePtrIp(ip),
1725 .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtrIp(ip),
1726 .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtrIp(ip),
17231727 };
17241728}
src/InternPool.zig+29-12
......@@ -73,7 +73,7 @@ pub const Key = union(enum) {
7373 /// If zero use pointee_type.abiAlignment()
7474 /// When creating pointer types, if alignment is equal to pointee type
7575 /// abi alignment, this value should be set to 0 instead.
76 alignment: u16 = 0,
76 alignment: u64 = 0,
7777 /// If this is non-zero it means the pointer points to a sub-byte
7878 /// range of data, which is backed by a "host integer" with this
7979 /// number of bytes.
......@@ -90,9 +90,9 @@ pub const Key = union(enum) {
9090 /// an appropriate value for this field.
9191 address_space: std.builtin.AddressSpace = .generic,
9292
93 pub const VectorIndex = enum(u32) {
94 none = std.math.maxInt(u32),
95 runtime = std.math.maxInt(u32) - 1,
93 pub const VectorIndex = enum(u16) {
94 none = std.math.maxInt(u16),
95 runtime = std.math.maxInt(u16) - 1,
9696 _,
9797 };
9898 };
......@@ -806,16 +806,33 @@ pub const Pointer = struct {
806806 sentinel: Index,
807807 flags: Flags,
808808 packed_offset: PackedOffset,
809 vector_index: VectorIndex,
809
810 /// Stored as a power-of-two, with one special value to indicate none.
811 pub const Alignment = enum(u6) {
812 none = std.math.maxInt(u6),
813 _,
814
815 pub fn toByteUnits(a: Alignment, default: u64) u64 {
816 return switch (a) {
817 .none => default,
818 _ => @as(u64, 1) << @enumToInt(a),
819 };
820 }
821
822 pub fn fromByteUnits(n: u64) Alignment {
823 if (n == 0) return .none;
824 return @intToEnum(Alignment, @ctz(n));
825 }
826 };
810827
811828 pub const Flags = packed struct(u32) {
812 alignment: u16,
829 size: Size,
830 alignment: Alignment,
813831 is_const: bool,
814832 is_volatile: bool,
815833 is_allowzero: bool,
816 size: Size,
817834 address_space: AddressSpace,
818 _: u7 = undefined,
835 vector_index: VectorIndex,
819836 };
820837
821838 pub const PackedOffset = packed struct(u32) {
......@@ -928,13 +945,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
928945 return .{ .ptr_type = .{
929946 .elem_type = ptr_info.child,
930947 .sentinel = ptr_info.sentinel,
931 .alignment = ptr_info.flags.alignment,
948 .alignment = ptr_info.flags.alignment.toByteUnits(0),
932949 .size = ptr_info.flags.size,
933950 .is_const = ptr_info.flags.is_const,
934951 .is_volatile = ptr_info.flags.is_volatile,
935952 .is_allowzero = ptr_info.flags.is_allowzero,
936953 .address_space = ptr_info.flags.address_space,
937 .vector_index = ptr_info.vector_index,
954 .vector_index = ptr_info.flags.vector_index,
938955 .host_size = ptr_info.packed_offset.host_size,
939956 .bit_offset = ptr_info.packed_offset.bit_offset,
940957 } };
......@@ -1003,18 +1020,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
10031020 .child = ptr_type.elem_type,
10041021 .sentinel = ptr_type.sentinel,
10051022 .flags = .{
1006 .alignment = ptr_type.alignment,
1023 .alignment = Pointer.Alignment.fromByteUnits(ptr_type.alignment),
10071024 .is_const = ptr_type.is_const,
10081025 .is_volatile = ptr_type.is_volatile,
10091026 .is_allowzero = ptr_type.is_allowzero,
10101027 .size = ptr_type.size,
10111028 .address_space = ptr_type.address_space,
1029 .vector_index = ptr_type.vector_index,
10121030 },
10131031 .packed_offset = .{
10141032 .host_size = ptr_type.host_size,
10151033 .bit_offset = ptr_type.bit_offset,
10161034 },
1017 .vector_index = ptr_type.vector_index,
10181035 }),
10191036 });
10201037 },
src/Sema.zig+21-21
......@@ -8400,7 +8400,7 @@ fn analyzeOptionalPayloadPtr(
84008400 const child_type = opt_type.optionalChild(mod);
84018401 const child_pointer = try Type.ptr(sema.arena, sema.mod, .{
84028402 .pointee_type = child_type,
8403 .mutable = !optional_ptr_ty.isConstPtr(),
8403 .mutable = !optional_ptr_ty.isConstPtr(mod),
84048404 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod),
84058405 });
84068406
......@@ -8594,7 +8594,7 @@ fn analyzeErrUnionPayloadPtr(
85948594 const payload_ty = err_union_ty.errorUnionPayload();
85958595 const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{
85968596 .pointee_type = payload_ty,
8597 .mutable = !operand_ty.isConstPtr(),
8597 .mutable = !operand_ty.isConstPtr(mod),
85988598 .@"addrspace" = operand_ty.ptrAddressSpace(mod),
85998599 });
86008600
......@@ -10147,7 +10147,7 @@ fn zirSwitchCapture(
1014710147 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
1014810148 .pointee_type = field_ty,
1014910149 .mutable = operand_ptr_ty.ptrIsMutable(mod),
10150 .@"volatile" = operand_ptr_ty.isVolatilePtr(),
10150 .@"volatile" = operand_ptr_ty.isVolatilePtr(mod),
1015110151 .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),
1015210152 });
1015310153 return sema.addConstant(
......@@ -10166,7 +10166,7 @@ fn zirSwitchCapture(
1016610166 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
1016710167 .pointee_type = field_ty,
1016810168 .mutable = operand_ptr_ty.ptrIsMutable(mod),
10169 .@"volatile" = operand_ptr_ty.isVolatilePtr(),
10169 .@"volatile" = operand_ptr_ty.isVolatilePtr(mod),
1017010170 .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod),
1017110171 });
1017210172 return block.addStructFieldPtr(operand_ptr, field_index, ptr_field_ty);
......@@ -15292,10 +15292,10 @@ fn zirCmpEq(
1529215292 }
1529315293
1529415294 // comparing null with optionals
15295 if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr())) {
15295 if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr(mod))) {
1529615296 return sema.analyzeIsNull(block, src, rhs, op == .neq);
1529715297 }
15298 if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr())) {
15298 if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr(mod))) {
1529915299 return sema.analyzeIsNull(block, src, lhs, op == .neq);
1530015300 }
1530115301
......@@ -22254,7 +22254,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2225422254 const target = sema.mod.getTarget();
2225522255 const mod = sema.mod;
2225622256
22257 if (dest_ty.isConstPtr()) {
22257 if (dest_ty.isConstPtr(mod)) {
2225822258 return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{});
2225922259 }
2226022260
......@@ -22452,7 +22452,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2245222452 const dest_ptr_ty = sema.typeOf(dest_ptr);
2245322453 try checkMemOperand(sema, block, dest_src, dest_ptr_ty);
2245422454
22455 if (dest_ptr_ty.isConstPtr()) {
22455 if (dest_ptr_ty.isConstPtr(mod)) {
2245622456 return sema.fail(block, dest_src, "cannot memset constant pointer", .{});
2245722457 }
2245822458
......@@ -24206,7 +24206,7 @@ fn fieldPtr(
2420624206 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
2420724207 .pointee_type = slice_ptr_ty,
2420824208 .mutable = attr_ptr_ty.ptrIsMutable(mod),
24209 .@"volatile" = attr_ptr_ty.isVolatilePtr(),
24209 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
2421024210 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),
2421124211 });
2421224212
......@@ -24227,7 +24227,7 @@ fn fieldPtr(
2422724227 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
2422824228 .pointee_type = Type.usize,
2422924229 .mutable = attr_ptr_ty.ptrIsMutable(mod),
24230 .@"volatile" = attr_ptr_ty.isVolatilePtr(),
24230 .@"volatile" = attr_ptr_ty.isVolatilePtr(mod),
2423124231 .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod),
2423224232 });
2423324233
......@@ -24897,7 +24897,7 @@ fn unionFieldPtr(
2489724897 const ptr_field_ty = try Type.ptr(arena, sema.mod, .{
2489824898 .pointee_type = field.ty,
2489924899 .mutable = union_ptr_ty.ptrIsMutable(mod),
24900 .@"volatile" = union_ptr_ty.isVolatilePtr(),
24900 .@"volatile" = union_ptr_ty.isVolatilePtr(mod),
2490124901 .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod),
2490224902 });
2490324903 const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?);
......@@ -25239,7 +25239,7 @@ fn tupleFieldPtr(
2523925239 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
2524025240 .pointee_type = field_ty,
2524125241 .mutable = tuple_ptr_ty.ptrIsMutable(mod),
25242 .@"volatile" = tuple_ptr_ty.isVolatilePtr(),
25242 .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod),
2524325243 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod),
2524425244 });
2524525245
......@@ -25767,7 +25767,7 @@ fn coerceExtra(
2576725767 }
2576825768
2576925769 // coercion from C pointer
25770 if (inst_ty.isCPtr()) src_c_ptr: {
25770 if (inst_ty.isCPtr(mod)) src_c_ptr: {
2577125771 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :src_c_ptr;
2577225772 // In this case we must add a safety check because the C pointer
2577325773 // could be null.
......@@ -27255,7 +27255,7 @@ fn storePtr2(
2725527255) CompileError!void {
2725627256 const mod = sema.mod;
2725727257 const ptr_ty = sema.typeOf(ptr);
27258 if (ptr_ty.isConstPtr())
27258 if (ptr_ty.isConstPtr(mod))
2725927259 return sema.fail(block, ptr_src, "cannot assign to constant", .{});
2726027260
2726127261 const elem_ty = ptr_ty.childType(mod);
......@@ -29843,7 +29843,7 @@ fn analyzeSlice(
2984329843 const result = try block.addBitCast(return_ty, new_ptr);
2984429844 if (block.wantSafety()) {
2984529845 // requirement: slicing C ptr is non-null
29846 if (ptr_ptr_child_ty.isCPtr()) {
29846 if (ptr_ptr_child_ty.isCPtr(mod)) {
2984729847 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
2984829848 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
2984929849 }
......@@ -29902,7 +29902,7 @@ fn analyzeSlice(
2990229902 try sema.requireRuntimeBlock(block, src, runtime_src);
2990329903 if (block.wantSafety()) {
2990429904 // requirement: slicing C ptr is non-null
29905 if (ptr_ptr_child_ty.isCPtr()) {
29905 if (ptr_ptr_child_ty.isCPtr(mod)) {
2990629906 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
2990729907 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
2990829908 }
......@@ -30720,7 +30720,7 @@ fn resolvePeerTypes(
3072030720 err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty);
3072130721 }
3072230722 }
30723 seen_const = seen_const or chosen_ty.isConstPtr();
30723 seen_const = seen_const or chosen_ty.isConstPtr(mod);
3072430724 chosen = candidate;
3072530725 chosen_i = candidate_i + 1;
3072630726 continue;
......@@ -30876,12 +30876,12 @@ fn resolvePeerTypes(
3087630876 .Optional => {
3087730877 const opt_child_ty = candidate_ty.optionalChild(mod);
3087830878 if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) {
30879 seen_const = seen_const or opt_child_ty.isConstPtr();
30879 seen_const = seen_const or opt_child_ty.isConstPtr(mod);
3088030880 any_are_null = true;
3088130881 continue;
3088230882 }
3088330883
30884 seen_const = seen_const or chosen_ty.isConstPtr();
30884 seen_const = seen_const or chosen_ty.isConstPtr(mod);
3088530885 any_are_null = false;
3088630886 chosen = candidate;
3088730887 chosen_i = candidate_i + 1;
......@@ -30924,7 +30924,7 @@ fn resolvePeerTypes(
3092430924 .Vector => continue,
3092530925 else => {},
3092630926 },
30927 .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) {
30927 .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr(mod) and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) {
3092830928 if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(mod), candidate_ty, target, src, src)) {
3092930929 continue;
3093030930 }
......@@ -31023,7 +31023,7 @@ fn resolvePeerTypes(
3102331023 var info = chosen_ty.ptrInfo(mod);
3102431024 info.sentinel = chosen_child_ty.sentinel(mod);
3102531025 info.size = .Slice;
31026 info.mutable = !(seen_const or chosen_child_ty.isConstPtr());
31026 info.mutable = !(seen_const or chosen_child_ty.isConstPtr(mod));
3102731027 info.pointee_type = chosen_child_ty.elemType2(mod);
3102831028
3102931029 const new_ptr_ty = try Type.ptr(sema.arena, mod, info);
src/arch/aarch64/CodeGen.zig+5-3
......@@ -3430,9 +3430,10 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
34303430}
34313431
34323432fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
3433 const mod = self.bin_file.options.module.?;
34333434 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
34343435 const slice_ty = self.typeOf(bin_op.lhs);
3435 const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
3436 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
34363437 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
34373438 const ptr_ty = slice_ty.slicePtrFieldType(&buf);
34383439
......@@ -3496,9 +3497,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
34963497}
34973498
34983499fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
3500 const mod = self.bin_file.options.module.?;
34993501 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
35003502 const ptr_ty = self.typeOf(bin_op.lhs);
3501 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
3503 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
35023504 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
35033505 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
35043506
......@@ -3869,7 +3871,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
38693871 break :result MCValue.none;
38703872
38713873 const ptr = try self.resolveInst(ty_op.operand);
3872 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
3874 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
38733875 if (self.liveness.isUnused(inst) and !is_volatile)
38743876 break :result MCValue.dead;
38753877
src/arch/arm/CodeGen.zig+5-3
......@@ -2428,9 +2428,10 @@ fn ptrElemVal(
24282428}
24292429
24302430fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2431 const mod = self.bin_file.options.module.?;
24312432 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
24322433 const slice_ty = self.typeOf(bin_op.lhs);
2433 const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
2434 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
24342435 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
24352436 const ptr_ty = slice_ty.slicePtrFieldType(&buf);
24362437
......@@ -2527,9 +2528,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
25272528}
25282529
25292530fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
2531 const mod = self.bin_file.options.module.?;
25302532 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
25312533 const ptr_ty = self.typeOf(bin_op.lhs);
2532 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
2534 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
25332535 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
25342536 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
25352537
......@@ -2738,7 +2740,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
27382740 break :result MCValue.none;
27392741
27402742 const ptr = try self.resolveInst(ty_op.operand);
2741 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
2743 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
27422744 if (self.liveness.isUnused(inst) and !is_volatile)
27432745 break :result MCValue.dead;
27442746
src/arch/riscv64/CodeGen.zig+1-1
......@@ -1536,7 +1536,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
15361536 break :result MCValue.none;
15371537
15381538 const ptr = try self.resolveInst(ty_op.operand);
1539 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
1539 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
15401540 if (self.liveness.isUnused(inst) and !is_volatile)
15411541 break :result MCValue.dead;
15421542
src/arch/sparc64/CodeGen.zig+1-1
......@@ -1827,7 +1827,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
18271827 break :result MCValue.none;
18281828
18291829 const ptr = try self.resolveInst(ty_op.operand);
1830 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr();
1830 const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod);
18311831 if (self.liveness.isUnused(inst) and !is_volatile)
18321832 break :result MCValue.dead;
18331833
src/codegen/c.zig+6-6
......@@ -6117,7 +6117,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
61176117 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
61186118 try f.renderType(writer, ty);
61196119 try writer.writeByte(')');
6120 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6120 if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
61216121 try writer.writeAll(" *)");
61226122 try f.writeCValue(writer, ptr, .Other);
61236123 try writer.writeAll(", ");
......@@ -6159,7 +6159,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
61596159 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
61606160 try f.renderType(writer, ty);
61616161 try writer.writeByte(')');
6162 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6162 if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
61636163 try writer.writeAll(" *)");
61646164 try f.writeCValue(writer, ptr, .Other);
61656165 try writer.writeAll(", ");
......@@ -6221,7 +6221,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
62216221 if (use_atomic) try writer.writeAll("zig_atomic(");
62226222 try f.renderType(writer, ty);
62236223 if (use_atomic) try writer.writeByte(')');
6224 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6224 if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
62256225 try writer.writeAll(" *)");
62266226 try f.writeCValue(writer, ptr, .Other);
62276227 try writer.writeAll(", ");
......@@ -6265,7 +6265,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
62656265 try writer.writeAll(", (zig_atomic(");
62666266 try f.renderType(writer, ty);
62676267 try writer.writeByte(')');
6268 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6268 if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
62696269 try writer.writeAll(" *)");
62706270 try f.writeCValue(writer, ptr, .Other);
62716271 try writer.writeAll(", ");
......@@ -6299,7 +6299,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
62996299 try writer.writeAll("zig_atomic_store((zig_atomic(");
63006300 try f.renderType(writer, ty);
63016301 try writer.writeByte(')');
6302 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6302 if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile");
63036303 try writer.writeAll(" *)");
63046304 try f.writeCValue(writer, ptr, .Other);
63056305 try writer.writeAll(", ");
......@@ -6365,7 +6365,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
63656365 return .none;
63666366 }
63676367
6368 if (elem_abi_size > 1 or dest_ty.isVolatilePtr()) {
6368 if (elem_abi_size > 1 or dest_ty.isVolatilePtr(mod)) {
63696369 // For the assignment in this loop, the array pointer needs to get
63706370 // casted to a regular pointer, otherwise an error like this occurs:
63716371 // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable
src/codegen/llvm.zig+5-5
......@@ -7046,7 +7046,7 @@ pub const FuncGen = struct {
70467046 const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType(mod));
70477047 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
70487048 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
7049 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr()));
7049 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod)));
70507050 break :blk load_inst;
70517051 };
70527052 const modified_vector = self.builder.buildInsertElement(loaded_vector, operand, index, "");
......@@ -8221,7 +8221,7 @@ pub const FuncGen = struct {
82218221 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
82228222 const len = usize_llvm_ty.constInt(operand_size, .False);
82238223 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8224 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr());
8224 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
82258225 if (safety and mod.comp.bin_file.options.valgrind) {
82268226 self.valgrindMarkUndef(dest_ptr, len);
82278227 }
......@@ -8497,7 +8497,7 @@ pub const FuncGen = struct {
84978497 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
84988498 const u8_llvm_ty = self.context.intType(8);
84998499 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
8500 const is_volatile = ptr_ty.isVolatilePtr();
8500 const is_volatile = ptr_ty.isVolatilePtr(mod);
85018501
85028502 if (self.air.value(bin_op.rhs, mod)) |elem_val| {
85038503 if (elem_val.isUndefDeep()) {
......@@ -8621,7 +8621,7 @@ pub const FuncGen = struct {
86218621 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
86228622 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
86238623 const mod = self.dg.module;
8624 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
8624 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);
86258625 _ = self.builder.buildMemCpy(
86268626 dest_ptr,
86278627 dest_ptr_ty.ptrAlignment(mod),
......@@ -9894,7 +9894,7 @@ pub const FuncGen = struct {
98949894 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null;
98959895
98969896 const ptr_alignment = info.alignment(mod);
9897 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
9897 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr(mod));
98989898
98999899 assert(info.vector_index != .runtime);
99009900 if (info.vector_index != .none) {
src/codegen/spirv.zig+8-5
......@@ -1689,7 +1689,7 @@ pub const DeclGen = struct {
16891689 const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect);
16901690 const result_id = self.spv.allocId();
16911691 const access = spec.MemoryAccess.Extended{
1692 .Volatile = ptr_ty.isVolatilePtr(),
1692 .Volatile = ptr_ty.isVolatilePtr(mod),
16931693 };
16941694 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
16951695 .id_result_type = self.typeId(indirect_value_ty_ref),
......@@ -1705,7 +1705,7 @@ pub const DeclGen = struct {
17051705 const value_ty = ptr_ty.childType(mod);
17061706 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);
17071707 const access = spec.MemoryAccess.Extended{
1708 .Volatile = ptr_ty.isVolatilePtr(),
1708 .Volatile = ptr_ty.isVolatilePtr(mod),
17091709 };
17101710 try self.func.body.emit(self.spv.gpa, .OpStore, .{
17111711 .pointer = ptr_id,
......@@ -2464,9 +2464,10 @@ pub const DeclGen = struct {
24642464 }
24652465
24662466 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2467 const mod = self.module;
24672468 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
24682469 const slice_ty = self.typeOf(bin_op.lhs);
2469 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
2470 if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
24702471
24712472 const slice_id = try self.resolve(bin_op.lhs);
24722473 const index_id = try self.resolve(bin_op.rhs);
......@@ -2479,9 +2480,10 @@ pub const DeclGen = struct {
24792480 }
24802481
24812482 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2483 const mod = self.module;
24822484 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
24832485 const slice_ty = self.typeOf(bin_op.lhs);
2484 if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
2486 if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
24852487
24862488 const slice_id = try self.resolve(bin_op.lhs);
24872489 const index_id = try self.resolve(bin_op.rhs);
......@@ -2781,10 +2783,11 @@ pub const DeclGen = struct {
27812783 }
27822784
27832785 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2786 const mod = self.module;
27842787 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
27852788 const ptr_ty = self.typeOf(ty_op.operand);
27862789 const operand = try self.resolve(ty_op.operand);
2787 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
2790 if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
27882791
27892792 return try self.load(ptr_ty, operand);
27902793 }
src/type.zig+62-23
......@@ -193,7 +193,7 @@ pub const Type = struct {
193193 .Frame,
194194 => false,
195195
196 .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr()),
196 .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr(mod)),
197197 .Optional => {
198198 if (!is_equality_cmp) return false;
199199 return ty.optionalChild(mod).isSelfComparable(mod, is_equality_cmp);
......@@ -3012,38 +3012,59 @@ pub const Type = struct {
30123012 }
30133013 }
30143014
3015 pub fn isConstPtr(self: Type) bool {
3016 return switch (self.tag()) {
3017 .pointer => !self.castTag(.pointer).?.data.mutable,
3018 else => false,
3015 pub fn isConstPtr(ty: Type, mod: *const Module) bool {
3016 return switch (ty.ip_index) {
3017 .none => switch (ty.tag()) {
3018 .pointer => !ty.castTag(.pointer).?.data.mutable,
3019 else => false,
3020 },
3021 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3022 .ptr_type => |ptr_type| ptr_type.is_const,
3023 else => false,
3024 },
30193025 };
30203026 }
30213027
3022 pub fn isVolatilePtr(self: Type) bool {
3023 return switch (self.tag()) {
3024 .pointer => {
3025 const payload = self.castTag(.pointer).?.data;
3026 return payload.@"volatile";
3028 pub fn isVolatilePtr(ty: Type, mod: *const Module) bool {
3029 return isVolatilePtrIp(ty, mod.intern_pool);
3030 }
3031
3032 pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool {
3033 return switch (ty.ip_index) {
3034 .none => switch (ty.tag()) {
3035 .pointer => ty.castTag(.pointer).?.data.@"volatile",
3036 else => false,
3037 },
3038 else => switch (ip.indexToKey(ty.ip_index)) {
3039 .ptr_type => |ptr_type| ptr_type.is_volatile,
3040 else => false,
30273041 },
3028 else => false,
30293042 };
30303043 }
30313044
3032 pub fn isAllowzeroPtr(self: Type, mod: *const Module) bool {
3033 return switch (self.tag()) {
3034 .pointer => {
3035 const payload = self.castTag(.pointer).?.data;
3036 return payload.@"allowzero";
3045 pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool {
3046 return switch (ty.ip_index) {
3047 .none => switch (ty.tag()) {
3048 .pointer => ty.castTag(.pointer).?.data.@"allowzero",
3049 else => ty.zigTypeTag(mod) == .Optional,
3050 },
3051 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3052 .ptr_type => |ptr_type| ptr_type.is_allowzero,
3053 else => false,
30373054 },
3038 else => return self.zigTypeTag(mod) == .Optional,
30393055 };
30403056 }
30413057
3042 pub fn isCPtr(self: Type) bool {
3043 return switch (self.tag()) {
3044 .pointer => self.castTag(.pointer).?.data.size == .C,
3045
3046 else => return false,
3058 pub fn isCPtr(ty: Type, mod: *const Module) bool {
3059 return switch (ty.ip_index) {
3060 .none => switch (ty.tag()) {
3061 .pointer => ty.castTag(.pointer).?.data.size == .C,
3062 else => false,
3063 },
3064 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3065 .ptr_type => |ptr_type| ptr_type.size == .C,
3066 else => false,
3067 },
30473068 };
30483069 }
30493070
......@@ -5063,7 +5084,7 @@ pub const Type = struct {
50635084 return .{
50645085 .pointee_type = p.elem_type.toType(),
50655086 .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
5066 .@"align" = p.alignment,
5087 .@"align" = @intCast(u32, p.alignment),
50675088 .@"addrspace" = p.address_space,
50685089 .bit_offset = p.bit_offset,
50695090 .host_size = p.host_size,
......@@ -5248,6 +5269,24 @@ pub const Type = struct {
52485269 }
52495270 }
52505271
5272 if (d.pointee_type.ip_index != .none and
5273 (d.sentinel == null or d.sentinel.?.ip_index != .none))
5274 {
5275 return mod.ptrType(.{
5276 .elem_type = d.pointee_type.ip_index,
5277 .sentinel = if (d.sentinel) |s| s.ip_index else .none,
5278 .alignment = d.@"align",
5279 .host_size = d.host_size,
5280 .bit_offset = d.bit_offset,
5281 .vector_index = d.vector_index,
5282 .size = d.size,
5283 .is_const = !d.mutable,
5284 .is_volatile = d.@"volatile",
5285 .is_allowzero = d.@"allowzero",
5286 .address_space = d.@"addrspace",
5287 });
5288 }
5289
52515290 return Type.Tag.pointer.create(arena, d);
52525291 }
52535292