authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-10-14 07:57:11+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-10-19 19:15:23+01:00
logec19086aa0491024622c444b0d9310560de9e6f0
tree000cb85a1af4bf6fe1cb6d8dc40e3f1817e7e2dd
parentbc797a97b1f7476b620567ff32b7a396ebdb4c9c
signaturelock-open Commit is signed but in an unrecognized format.

compiler: remove @setAlignStack

This commit finishes implementing #21209 by removing the `@setAlignStack` builtin in favour of `CallingConvention` payloads. The x86_64 backend is updated to use the stack alignment given in the calling convention (the LLVM backend was already updated in a previous commit). Resolves: #21209

11 files changed, 21 insertions(+), 82 deletions(-)

lib/std/zig/AstGen.zig-9
...@@ -2902,7 +2902,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2902,7 +2902,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2902 .breakpoint,2902 .breakpoint,
2903 .disable_instrumentation,2903 .disable_instrumentation,
2904 .set_float_mode,2904 .set_float_mode,
2905 .set_align_stack,
2906 .branch_hint,2905 .branch_hint,
2907 => break :b true,2906 => break :b true,
2908 else => break :b false,2907 else => break :b false,
...@@ -9324,14 +9323,6 @@ fn builtinCall(...@@ -9324,14 +9323,6 @@ fn builtinCall(
9324 });9323 });
9325 return rvalue(gz, ri, .void_value, node);9324 return rvalue(gz, ri, .void_value, node);
9326 },9325 },
9327 .set_align_stack => {
9328 const order = try expr(gz, scope, coerced_align_ri, params[0]);
9329 _ = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
9330 .node = gz.nodeIndexToRelative(node),
9331 .operand = order,
9332 });
9333 return rvalue(gz, ri, .void_value, node);
9334 },
93359326
9336 .src => {9327 .src => {
9337 // Incorporate the source location into the source hash, so that9328 // Incorporate the source location into the source hash, so that
lib/std/zig/AstRlAnnotate.zig-1
...@@ -909,7 +909,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast....@@ -909,7 +909,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
909 .wasm_memory_size,909 .wasm_memory_size,
910 .splat,910 .splat,
911 .set_float_mode,911 .set_float_mode,
912 .set_align_stack,
913 .type_info,912 .type_info,
914 .work_item_id,913 .work_item_id,
915 .work_group_size,914 .work_group_size,
lib/std/zig/BuiltinFn.zig-9
...@@ -82,7 +82,6 @@ pub const Tag = enum {...@@ -82,7 +82,6 @@ pub const Tag = enum {
82 rem,82 rem,
83 return_address,83 return_address,
84 select,84 select,
85 set_align_stack,
86 set_eval_branch_quota,85 set_eval_branch_quota,
87 set_float_mode,86 set_float_mode,
88 set_runtime_safety,87 set_runtime_safety,
...@@ -744,14 +743,6 @@ pub const list = list: {...@@ -744,14 +743,6 @@ pub const list = list: {
744 .param_count = 4,743 .param_count = 4,
745 },744 },
746 },745 },
747 .{
748 "@setAlignStack",
749 .{
750 .tag = .set_align_stack,
751 .param_count = 1,
752 .illegal_outside_function = true,
753 },
754 },
755 .{746 .{
756 "@setEvalBranchQuota",747 "@setEvalBranchQuota",
757 .{748 .{
lib/std/zig/Zir.zig-4
...@@ -1982,9 +1982,6 @@ pub const Inst = struct {...@@ -1982,9 +1982,6 @@ pub const Inst = struct {
1982 /// Implement builtin `@setFloatMode`.1982 /// Implement builtin `@setFloatMode`.
1983 /// `operand` is payload index to `UnNode`.1983 /// `operand` is payload index to `UnNode`.
1984 set_float_mode,1984 set_float_mode,
1985 /// Implement builtin `@setAlignStack`.
1986 /// `operand` is payload index to `UnNode`.
1987 set_align_stack,
1988 /// Implements the `@errorCast` builtin.1985 /// Implements the `@errorCast` builtin.
1989 /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.1986 /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
1990 error_cast,1987 error_cast,
...@@ -4012,7 +4009,6 @@ fn findDeclsInner(...@@ -4012,7 +4009,6 @@ fn findDeclsInner(
4012 .wasm_memory_grow,4009 .wasm_memory_grow,
4013 .prefetch,4010 .prefetch,
4014 .set_float_mode,4011 .set_float_mode,
4015 .set_align_stack,
4016 .error_cast,4012 .error_cast,
4017 .await_nosuspend,4013 .await_nosuspend,
4018 .breakpoint,4014 .breakpoint,
src/InternPool.zig+1-21
...@@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) {...@@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) {
5618 branch_hint: std.builtin.BranchHint,5618 branch_hint: std.builtin.BranchHint,
5619 is_noinline: bool,5619 is_noinline: bool,
5620 calls_or_awaits_errorable_fn: bool,5620 calls_or_awaits_errorable_fn: bool,
5621 stack_alignment: Alignment,
5622 /// True if this function has an inferred error set.5621 /// True if this function has an inferred error set.
5623 inferred_error_set: bool,5622 inferred_error_set: bool,
5624 disable_instrumentation: bool,5623 disable_instrumentation: bool,
56255624
5626 _: u17 = 0,5625 _: u23 = 0,
56275626
5628 pub const State = enum(u2) {5627 pub const State = enum(u2) {
5629 /// The runtime function has never been referenced.5628 /// The runtime function has never been referenced.
...@@ -8696,7 +8695,6 @@ pub fn getFuncDecl(...@@ -8696,7 +8695,6 @@ pub fn getFuncDecl(
8696 .branch_hint = .none,8695 .branch_hint = .none,
8697 .is_noinline = key.is_noinline,8696 .is_noinline = key.is_noinline,
8698 .calls_or_awaits_errorable_fn = false,8697 .calls_or_awaits_errorable_fn = false,
8699 .stack_alignment = .none,
8700 .inferred_error_set = false,8698 .inferred_error_set = false,
8701 .disable_instrumentation = false,8699 .disable_instrumentation = false,
8702 },8700 },
...@@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes(...@@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes(
8800 .branch_hint = .none,8798 .branch_hint = .none,
8801 .is_noinline = key.is_noinline,8799 .is_noinline = key.is_noinline,
8802 .calls_or_awaits_errorable_fn = false,8800 .calls_or_awaits_errorable_fn = false,
8803 .stack_alignment = .none,
8804 .inferred_error_set = true,8801 .inferred_error_set = true,
8805 .disable_instrumentation = false,8802 .disable_instrumentation = false,
8806 },8803 },
...@@ -8992,7 +8989,6 @@ pub fn getFuncInstance(...@@ -8992,7 +8989,6 @@ pub fn getFuncInstance(
8992 .branch_hint = .none,8989 .branch_hint = .none,
8993 .is_noinline = arg.is_noinline,8990 .is_noinline = arg.is_noinline,
8994 .calls_or_awaits_errorable_fn = false,8991 .calls_or_awaits_errorable_fn = false,
8995 .stack_alignment = .none,
8996 .inferred_error_set = false,8992 .inferred_error_set = false,
8997 .disable_instrumentation = false,8993 .disable_instrumentation = false,
8998 },8994 },
...@@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes(...@@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes(
9092 .branch_hint = .none,9088 .branch_hint = .none,
9093 .is_noinline = arg.is_noinline,9089 .is_noinline = arg.is_noinline,
9094 .calls_or_awaits_errorable_fn = false,9090 .calls_or_awaits_errorable_fn = false,
9095 .stack_alignment = .none,
9096 .inferred_error_set = true,9091 .inferred_error_set = true,
9097 .disable_instrumentation = false,9092 .disable_instrumentation = false,
9098 },9093 },
...@@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {...@@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
11871 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);11866 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
11872}11867}
1187311868
11874pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
11875 const unwrapped_func = func.unwrap(ip);
11876 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11877 extra_mutex.lock();
11878 defer extra_mutex.unlock();
11879
11880 const analysis_ptr = ip.funcAnalysisPtr(func);
11881 var analysis = analysis_ptr.*;
11882 analysis.stack_alignment = switch (analysis.stack_alignment) {
11883 .none => new_stack_alignment,
11884 else => |old_stack_alignment| old_stack_alignment.maxStrict(new_stack_alignment),
11885 };
11886 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11887}
11888
11889pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void {11869pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void {
11890 const unwrapped_func = func.unwrap(ip);11870 const unwrapped_func = func.unwrap(ip);
11891 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;11871 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
src/Sema.zig-34
...@@ -1326,11 +1326,6 @@ fn analyzeBodyInner(...@@ -1326,11 +1326,6 @@ fn analyzeBodyInner(
1326 i += 1;1326 i += 1;
1327 continue;1327 continue;
1328 },1328 },
1329 .set_align_stack => {
1330 try sema.zirSetAlignStack(block, extended);
1331 i += 1;
1332 continue;
1333 },
1334 .breakpoint => {1329 .breakpoint => {
1335 if (!block.is_comptime) {1330 if (!block.is_comptime) {
1336 _ = try block.addNoOp(.breakpoint);1331 _ = try block.addNoOp(.breakpoint);
...@@ -6510,35 +6505,6 @@ pub fn analyzeExport(...@@ -6510,35 +6505,6 @@ pub fn analyzeExport(
6510 });6505 });
6511}6506}
65126507
6513fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6514 const pt = sema.pt;
6515 const zcu = pt.zcu;
6516 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6517 const operand_src = block.builtinCallArgSrc(extra.node, 0);
6518 const src = block.nodeOffset(extra.node);
6519 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
6520
6521 const func = switch (sema.owner.unwrap()) {
6522 .func => |func| func,
6523 .cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}),
6524 };
6525
6526 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
6527 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
6528 alignment.toByteUnits().?,
6529 });
6530 }
6531
6532 switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) {
6533 .naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
6534 .@"inline" => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
6535 else => {},
6536 }
6537
6538 zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
6539 sema.allow_memoize = false;
6540}
6541
6542fn zirDisableInstrumentation(sema: *Sema) CompileError!void {6508fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
6543 const pt = sema.pt;6509 const pt = sema.pt;
6544 const zcu = pt.zcu;6510 const zcu = pt.zcu;
src/Zcu.zig+1-1
...@@ -3592,7 +3592,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu...@@ -3592,7 +3592,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
3592 else => false,3592 else => false,
3593 },3593 },
3594 .stage2_x86_64 => switch (cc) {3594 .stage2_x86_64 => switch (cc) {
3595 .x86_64_sysv, .x86_64_win, .naked => true,3595 .x86_64_sysv, .x86_64_win, .naked => true, // stack alignment supported
3596 else => false,3596 else => false,
3597 },3597 },
3598 .stage2_aarch64 => switch (cc) {3598 .stage2_aarch64 => switch (cc) {
src/arch/wasm/CodeGen.zig+1-1
...@@ -710,7 +710,7 @@ stack_size: u32 = 0,...@@ -710,7 +710,7 @@ stack_size: u32 = 0,
710/// The stack alignment, which is 16 bytes by default. This is specified by the710/// The stack alignment, which is 16 bytes by default. This is specified by the
711/// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md711/// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md
712/// and also what the llvm backend will emit.712/// and also what the llvm backend will emit.
713/// However, local variables or the usage of `@setAlignStack` can overwrite this default.713/// However, local variables or the usage of `incoming_stack_alignment` in a `CallingConvention` can overwrite this default.
714stack_alignment: Alignment = .@"16",714stack_alignment: Alignment = .@"16",
715715
716// For each individual Wasm valtype we store a seperate free list which716// For each individual Wasm valtype we store a seperate free list which
src/arch/x86_64/CodeGen.zig+2-1
...@@ -11,6 +11,7 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking);...@@ -11,6 +11,7 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking);
11const wip_mir_log = std.log.scoped(.wip_mir);11const wip_mir_log = std.log.scoped(.wip_mir);
12const math = std.math;12const math = std.math;
13const mem = std.mem;13const mem = std.mem;
14const target_util = @import("../../target.zig");
14const trace = @import("../../tracy.zig").trace;15const trace = @import("../../tracy.zig").trace;
1516
16const Air = @import("../../Air.zig");17const Air = @import("../../Air.zig");
...@@ -872,7 +873,7 @@ pub fn generate(...@@ -872,7 +873,7 @@ pub fn generate(
872 @intFromEnum(FrameIndex.stack_frame),873 @intFromEnum(FrameIndex.stack_frame),
873 FrameAlloc.init(.{874 FrameAlloc.init(.{
874 .size = 0,875 .size = 0,
875 .alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"),876 .alignment = target_util.stackAlignment(function.target.*, fn_type.fnCallingConvention(zcu)),
876 }),877 }),
877 );878 );
878 function.frame_allocs.set(879 function.frame_allocs.set(
src/print_zir.zig-1
...@@ -567,7 +567,6 @@ const Writer = struct {...@@ -567,7 +567,6 @@ const Writer = struct {
567 .c_undef,567 .c_undef,
568 .c_include,568 .c_include,
569 .set_float_mode,569 .set_float_mode,
570 .set_align_stack,
571 .wasm_memory_size,570 .wasm_memory_size,
572 .int_from_error,571 .int_from_error,
573 .error_from_int,572 .error_from_int,
src/target.zig+16
...@@ -607,3 +607,19 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt...@@ -607,3 +607,19 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
607 },607 },
608 };608 };
609}609}
610
611pub fn stackAlignment(target: std.Target, cc: std.builtin.CallingConvention) u64 {
612 switch (cc) {
613 inline else => |payload| switch (@TypeOf(payload)) {
614 std.builtin.CallingConvention.CommonOptions,
615 std.builtin.CallingConvention.X86RegparmOptions,
616 std.builtin.CallingConvention.ArmInterruptOptions,
617 std.builtin.CallingConvention.MipsInterruptOptions,
618 std.builtin.CallingConvention.RiscvInterruptOptions,
619 => if (payload.incoming_stack_alignment) |a| return a,
620 void => {},
621 else => comptime unreachable,
622 },
623 }
624 return target.stackAlignment();
625}