aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-05-18 22:02:55 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-06-10 20:47:53 -0700
commit7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2 (patch)
treef07c76f10c294cdfa7cc302097278ac4ff720c65 /src/InternPool.zig
parent607737d841bc2279cbe5fee68a0a546b9a5a802e (diff)
downloadzig-7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2.tar.gz
zig-7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2.zip
compiler: eliminate legacy Type.Tag.pointer
Now pointer types are stored only in InternPool.
Diffstat (limited to 'src/InternPool.zig')
-rw-r--r--src/InternPool.zig55
1 files changed, 30 insertions, 25 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index bf48aeda84..81035bffc5 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -186,17 +186,11 @@ pub const Key = union(enum) {
pub const PtrType = struct {
elem_type: Index,
sentinel: Index = .none,
- /// 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.
- ///
- /// Please don't change this to u32 or u29. If you want to save bits,
- /// migrate the rest of the codebase to use the `Alignment` type rather
- /// than using byte units. The LLVM backend can only handle `c_uint`
- /// byte units; we can emit a semantic analysis error if alignment that
- /// overflows that amount is attempted to be used, but it shouldn't
- /// affect the other backends.
- alignment: u64 = 0,
+ /// `none` indicates the ABI alignment of the pointee_type. In this
+ /// case, this field *must* be set to `none`, otherwise the
+ /// `InternPool` equality and hashing functions will return incorrect
+ /// results.
+ alignment: Alignment = .none,
/// 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.
@@ -378,15 +372,11 @@ pub const Key = union(enum) {
/// Tells whether a parameter is noalias. See `paramIsNoalias` helper
/// method for accessing this.
noalias_bits: u32,
- /// If zero use default target function code alignment.
- ///
- /// Please don't change this to u32 or u29. If you want to save bits,
- /// migrate the rest of the codebase to use the `Alignment` type rather
- /// than using byte units. The LLVM backend can only handle `c_uint`
- /// byte units; we can emit a semantic analysis error if alignment that
- /// overflows that amount is attempted to be used, but it shouldn't
- /// affect the other backends.
- alignment: u64,
+ /// `none` indicates the function has the default alignment for
+ /// function code on the target. In this case, this field *must* be set
+ /// to `none`, otherwise the `InternPool` equality and hashing
+ /// functions will return incorrect results.
+ alignment: Alignment,
cc: std.builtin.CallingConvention,
is_var_args: bool,
is_generic: bool,
@@ -1500,6 +1490,13 @@ pub const Alignment = enum(u6) {
none = std.math.maxInt(u6),
_,
+ pub fn toByteUnitsOptional(a: Alignment) ?u64 {
+ return switch (a) {
+ .none => null,
+ _ => @as(u64, 1) << @enumToInt(a),
+ };
+ }
+
pub fn toByteUnits(a: Alignment, default: u64) u64 {
return switch (a) {
.none => default,
@@ -1509,8 +1506,14 @@ pub const Alignment = enum(u6) {
pub fn fromByteUnits(n: u64) Alignment {
if (n == 0) return .none;
+ assert(std.math.isPowerOfTwo(n));
return @intToEnum(Alignment, @ctz(n));
}
+
+ pub fn fromNonzeroByteUnits(n: u64) Alignment {
+ assert(n != 0);
+ return fromByteUnits(n);
+ }
};
/// Used for non-sentineled arrays that have length fitting in u32, as well as
@@ -1773,7 +1776,7 @@ 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.toByteUnits(0),
+ .alignment = ptr_info.flags.alignment,
.size = ptr_info.flags.size,
.is_const = ptr_info.flags.is_const,
.is_volatile = ptr_info.flags.is_volatile,
@@ -2013,7 +2016,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType {
.return_type = type_function.data.return_type,
.comptime_bits = type_function.data.comptime_bits,
.noalias_bits = type_function.data.noalias_bits,
- .alignment = type_function.data.flags.alignment.toByteUnits(0),
+ .alignment = type_function.data.flags.alignment,
.cc = type_function.data.flags.cc,
.is_var_args = type_function.data.flags.is_var_args,
.is_generic = type_function.data.flags.is_generic,
@@ -2100,16 +2103,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
return @intToEnum(Index, ip.items.len - 1);
}
+ const is_allowzero = ptr_type.is_allowzero or ptr_type.size == .C;
+
ip.items.appendAssumeCapacity(.{
.tag = .type_pointer,
.data = try ip.addExtra(gpa, Pointer{
.child = ptr_type.elem_type,
.sentinel = ptr_type.sentinel,
.flags = .{
- .alignment = Alignment.fromByteUnits(ptr_type.alignment),
+ .alignment = ptr_type.alignment,
.is_const = ptr_type.is_const,
.is_volatile = ptr_type.is_volatile,
- .is_allowzero = ptr_type.is_allowzero,
+ .is_allowzero = is_allowzero,
.size = ptr_type.size,
.address_space = ptr_type.address_space,
.vector_index = ptr_type.vector_index,
@@ -2316,7 +2321,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
.comptime_bits = func_type.comptime_bits,
.noalias_bits = func_type.noalias_bits,
.flags = .{
- .alignment = Alignment.fromByteUnits(func_type.alignment),
+ .alignment = func_type.alignment,
.cc = func_type.cc,
.is_var_args = func_type.is_var_args,
.is_generic = func_type.is_generic,