aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-09-28 02:10:25 +0100
committermlugg <mlugg@mlugg.co.uk>2024-10-19 19:08:59 +0100
commit51706af908e0c6acb822ef36760b7fe31faf62a6 (patch)
treed814bcfcfd83ebc5fd50da11f18a9a6427a54859 /src/InternPool.zig
parent8573836892ba1b7cd34d377b46258930161256c3 (diff)
downloadzig-51706af908e0c6acb822ef36760b7fe31faf62a6.tar.gz
zig-51706af908e0c6acb822ef36760b7fe31faf62a6.zip
compiler: introduce new `CallingConvention`
This commit begins implementing accepted proposal #21209 by making `std.builtin.CallingConvention` a tagged union. The stage1 dance here is a little convoluted. This commit introduces the new type as `NewCallingConvention`, keeping the old `CallingConvention` around. The compiler uses `std.builtin.NewCallingConvention` exclusively, but when fetching the type from `std` when running the compiler (e.g. with `getBuiltinType`), the name `CallingConvention` is used. This allows a prior build of Zig to be used to build this commit. The next commit will update `zig1.wasm`, and then the compiler and standard library can be updated to completely replace `CallingConvention` with `NewCallingConvention`. The second half of #21209 is to remove `@setAlignStack`, which will be implemented in another commit after updating `zig1.wasm`.
Diffstat (limited to 'src/InternPool.zig')
-rw-r--r--src/InternPool.zig105
1 files changed, 92 insertions, 13 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index 4315855d83..11fee424ec 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -1988,7 +1988,7 @@ pub const Key = union(enum) {
/// Tells whether a parameter is noalias. See `paramIsNoalias` helper
/// method for accessing this.
noalias_bits: u32,
- cc: std.builtin.CallingConvention,
+ cc: std.builtin.NewCallingConvention,
is_var_args: bool,
is_generic: bool,
is_noinline: bool,
@@ -2011,10 +2011,10 @@ pub const Key = union(enum) {
a.return_type == b.return_type and
a.comptime_bits == b.comptime_bits and
a.noalias_bits == b.noalias_bits and
- a.cc == b.cc and
a.is_var_args == b.is_var_args and
a.is_generic == b.is_generic and
- a.is_noinline == b.is_noinline;
+ a.is_noinline == b.is_noinline and
+ std.meta.eql(a.cc, b.cc);
}
pub fn hash(self: FuncType, hasher: *Hash, ip: *const InternPool) void {
@@ -5444,7 +5444,7 @@ pub const Tag = enum(u8) {
flags: Flags,
pub const Flags = packed struct(u32) {
- cc: std.builtin.CallingConvention,
+ cc: PackedCallingConvention,
is_var_args: bool,
is_generic: bool,
has_comptime_bits: bool,
@@ -5453,7 +5453,7 @@ pub const Tag = enum(u8) {
cc_is_generic: bool,
section_is_generic: bool,
addrspace_is_generic: bool,
- _: u16 = 0,
+ _: u6 = 0,
};
};
@@ -6912,7 +6912,7 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
.return_type = type_function.data.return_type,
.comptime_bits = comptime_bits,
.noalias_bits = noalias_bits,
- .cc = type_function.data.flags.cc,
+ .cc = type_function.data.flags.cc.unpack(),
.is_var_args = type_function.data.flags.is_var_args,
.is_noinline = type_function.data.flags.is_noinline,
.cc_is_generic = type_function.data.flags.cc_is_generic,
@@ -8526,7 +8526,7 @@ pub const GetFuncTypeKey = struct {
comptime_bits: u32 = 0,
noalias_bits: u32 = 0,
/// `null` means generic.
- cc: ?std.builtin.CallingConvention = .Unspecified,
+ cc: ?std.builtin.NewCallingConvention = .auto,
is_var_args: bool = false,
is_generic: bool = false,
is_noinline: bool = false,
@@ -8564,7 +8564,7 @@ pub fn getFuncType(
.params_len = params_len,
.return_type = key.return_type,
.flags = .{
- .cc = key.cc orelse .Unspecified,
+ .cc = .pack(key.cc orelse .auto),
.is_var_args = key.is_var_args,
.has_comptime_bits = key.comptime_bits != 0,
.has_noalias_bits = key.noalias_bits != 0,
@@ -8668,7 +8668,7 @@ pub const GetFuncDeclKey = struct {
rbrace_line: u32,
lbrace_column: u32,
rbrace_column: u32,
- cc: ?std.builtin.CallingConvention,
+ cc: ?std.builtin.NewCallingConvention,
is_noinline: bool,
};
@@ -8733,7 +8733,7 @@ pub const GetFuncDeclIesKey = struct {
comptime_bits: u32,
bare_return_type: Index,
/// null means generic.
- cc: ?std.builtin.CallingConvention,
+ cc: ?std.builtin.NewCallingConvention,
/// null means generic.
alignment: ?Alignment,
section_is_generic: bool,
@@ -8818,7 +8818,7 @@ pub fn getFuncDeclIes(
.params_len = params_len,
.return_type = error_union_type,
.flags = .{
- .cc = key.cc orelse .Unspecified,
+ .cc = .pack(key.cc orelse .auto),
.is_var_args = key.is_var_args,
.has_comptime_bits = key.comptime_bits != 0,
.has_noalias_bits = key.noalias_bits != 0,
@@ -8948,7 +8948,7 @@ pub const GetFuncInstanceKey = struct {
comptime_args: []const Index,
noalias_bits: u32,
bare_return_type: Index,
- cc: std.builtin.CallingConvention,
+ cc: std.builtin.NewCallingConvention,
alignment: Alignment,
section: OptionalNullTerminatedString,
is_noinline: bool,
@@ -9110,7 +9110,7 @@ pub fn getFuncInstanceIes(
.params_len = params_len,
.return_type = error_union_type,
.flags = .{
- .cc = arg.cc,
+ .cc = .pack(arg.cc),
.is_var_args = false,
.has_comptime_bits = false,
.has_noalias_bits = arg.noalias_bits != 0,
@@ -12224,3 +12224,82 @@ pub fn getErrorValue(
pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
}
+
+const PackedCallingConvention = packed struct(u18) {
+ tag: std.builtin.NewCallingConvention.Tag,
+ /// May be ignored depending on `tag`.
+ incoming_stack_alignment: Alignment,
+ /// Interpretation depends on `tag`.
+ extra: u4,
+
+ fn pack(cc: std.builtin.NewCallingConvention) PackedCallingConvention {
+ return switch (cc) {
+ inline else => |pl, tag| switch (@TypeOf(pl)) {
+ void => .{
+ .tag = tag,
+ .incoming_stack_alignment = .none, // unused
+ .extra = 0, // unused
+ },
+ std.builtin.NewCallingConvention.CommonOptions => .{
+ .tag = tag,
+ .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
+ .extra = 0, // unused
+ },
+ std.builtin.NewCallingConvention.X86RegparmOptions => .{
+ .tag = tag,
+ .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
+ .extra = pl.register_params,
+ },
+ std.builtin.NewCallingConvention.ArmInterruptOptions => .{
+ .tag = tag,
+ .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
+ .extra = @intFromEnum(pl.type),
+ },
+ std.builtin.NewCallingConvention.MipsInterruptOptions => .{
+ .tag = tag,
+ .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
+ .extra = @intFromEnum(pl.mode),
+ },
+ std.builtin.NewCallingConvention.RiscvInterruptOptions => .{
+ .tag = tag,
+ .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
+ .extra = @intFromEnum(pl.level),
+ },
+ else => comptime unreachable,
+ },
+ };
+ }
+
+ fn unpack(cc: PackedCallingConvention) std.builtin.NewCallingConvention {
+ @setEvalBranchQuota(400_000);
+ return switch (cc.tag) {
+ inline else => |tag| @unionInit(
+ std.builtin.NewCallingConvention,
+ @tagName(tag),
+ switch (std.meta.FieldType(std.builtin.NewCallingConvention, tag)) {
+ void => {},
+ std.builtin.NewCallingConvention.CommonOptions => .{
+ .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
+ },
+ std.builtin.NewCallingConvention.X86RegparmOptions => .{
+ .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
+ .register_params = @intCast(cc.extra),
+ },
+ std.builtin.NewCallingConvention.ArmInterruptOptions => .{
+ .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
+ .type = @enumFromInt(cc.extra),
+ },
+ std.builtin.NewCallingConvention.MipsInterruptOptions => .{
+ .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
+ .mode = @enumFromInt(cc.extra),
+ },
+ std.builtin.NewCallingConvention.RiscvInterruptOptions => .{
+ .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
+ .level = @enumFromInt(cc.extra),
+ },
+ else => comptime unreachable,
+ },
+ ),
+ };
+ }
+};