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
29022902 .breakpoint,
29032903 .disable_instrumentation,
29042904 .set_float_mode,
2905 .set_align_stack,
29062905 .branch_hint,
29072906 => break :b true,
29082907 else => break :b false,
......@@ -9324,14 +9323,6 @@ fn builtinCall(
93249323 });
93259324 return rvalue(gz, ri, .void_value, node);
93269325 },
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
93369327 .src => {
93379328 // 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.
909909 .wasm_memory_size,
910910 .splat,
911911 .set_float_mode,
912 .set_align_stack,
913912 .type_info,
914913 .work_item_id,
915914 .work_group_size,
lib/std/zig/BuiltinFn.zig-9
......@@ -82,7 +82,6 @@ pub const Tag = enum {
8282 rem,
8383 return_address,
8484 select,
85 set_align_stack,
8685 set_eval_branch_quota,
8786 set_float_mode,
8887 set_runtime_safety,
......@@ -744,14 +743,6 @@ pub const list = list: {
744743 .param_count = 4,
745744 },
746745 },
747 .{
748 "@setAlignStack",
749 .{
750 .tag = .set_align_stack,
751 .param_count = 1,
752 .illegal_outside_function = true,
753 },
754 },
755746 .{
756747 "@setEvalBranchQuota",
757748 .{
lib/std/zig/Zir.zig-4
......@@ -1982,9 +1982,6 @@ pub const Inst = struct {
19821982 /// Implement builtin `@setFloatMode`.
19831983 /// `operand` is payload index to `UnNode`.
19841984 set_float_mode,
1985 /// Implement builtin `@setAlignStack`.
1986 /// `operand` is payload index to `UnNode`.
1987 set_align_stack,
19881985 /// Implements the `@errorCast` builtin.
19891986 /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
19901987 error_cast,
......@@ -4012,7 +4009,6 @@ fn findDeclsInner(
40124009 .wasm_memory_grow,
40134010 .prefetch,
40144011 .set_float_mode,
4015 .set_align_stack,
40164012 .error_cast,
40174013 .await_nosuspend,
40184014 .breakpoint,
src/InternPool.zig+1-21
......@@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) {
56185618 branch_hint: std.builtin.BranchHint,
56195619 is_noinline: bool,
56205620 calls_or_awaits_errorable_fn: bool,
5621 stack_alignment: Alignment,
56225621 /// True if this function has an inferred error set.
56235622 inferred_error_set: bool,
56245623 disable_instrumentation: bool,
56255624
5626 _: u17 = 0,
5625 _: u23 = 0,
56275626
56285627 pub const State = enum(u2) {
56295628 /// The runtime function has never been referenced.
......@@ -8696,7 +8695,6 @@ pub fn getFuncDecl(
86968695 .branch_hint = .none,
86978696 .is_noinline = key.is_noinline,
86988697 .calls_or_awaits_errorable_fn = false,
8699 .stack_alignment = .none,
87008698 .inferred_error_set = false,
87018699 .disable_instrumentation = false,
87028700 },
......@@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes(
88008798 .branch_hint = .none,
88018799 .is_noinline = key.is_noinline,
88028800 .calls_or_awaits_errorable_fn = false,
8803 .stack_alignment = .none,
88048801 .inferred_error_set = true,
88058802 .disable_instrumentation = false,
88068803 },
......@@ -8992,7 +8989,6 @@ pub fn getFuncInstance(
89928989 .branch_hint = .none,
89938990 .is_noinline = arg.is_noinline,
89948991 .calls_or_awaits_errorable_fn = false,
8995 .stack_alignment = .none,
89968992 .inferred_error_set = false,
89978993 .disable_instrumentation = false,
89988994 },
......@@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes(
90929088 .branch_hint = .none,
90939089 .is_noinline = arg.is_noinline,
90949090 .calls_or_awaits_errorable_fn = false,
9095 .stack_alignment = .none,
90969091 .inferred_error_set = true,
90979092 .disable_instrumentation = false,
90989093 },
......@@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
1187111866 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
1187211867}
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
1188911869pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void {
1189011870 const unwrapped_func = func.unwrap(ip);
1189111871 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
src/Sema.zig-34
......@@ -1326,11 +1326,6 @@ fn analyzeBodyInner(
13261326 i += 1;
13271327 continue;
13281328 },
1329 .set_align_stack => {
1330 try sema.zirSetAlignStack(block, extended);
1331 i += 1;
1332 continue;
1333 },
13341329 .breakpoint => {
13351330 if (!block.is_comptime) {
13361331 _ = try block.addNoOp(.breakpoint);
......@@ -6510,35 +6505,6 @@ pub fn analyzeExport(
65106505 });
65116506}
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
65426508fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
65436509 const pt = sema.pt;
65446510 const zcu = pt.zcu;
src/Zcu.zig+1-1
......@@ -3592,7 +3592,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
35923592 else => false,
35933593 },
35943594 .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
35963596 else => false,
35973597 },
35983598 .stage2_aarch64 => switch (cc) {
src/arch/wasm/CodeGen.zig+1-1
......@@ -710,7 +710,7 @@ stack_size: u32 = 0,
710710/// The stack alignment, which is 16 bytes by default. This is specified by the
711711/// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md
712712/// 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.
714714stack_alignment: Alignment = .@"16",
715715
716716// 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);
1111const wip_mir_log = std.log.scoped(.wip_mir);
1212const math = std.math;
1313const mem = std.mem;
14const target_util = @import("../../target.zig");
1415const trace = @import("../../tracy.zig").trace;
1516
1617const Air = @import("../../Air.zig");
......@@ -872,7 +873,7 @@ pub fn generate(
872873 @intFromEnum(FrameIndex.stack_frame),
873874 FrameAlloc.init(.{
874875 .size = 0,
875 .alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"),
876 .alignment = target_util.stackAlignment(function.target.*, fn_type.fnCallingConvention(zcu)),
876877 }),
877878 );
878879 function.frame_allocs.set(
src/print_zir.zig-1
......@@ -567,7 +567,6 @@ const Writer = struct {
567567 .c_undef,
568568 .c_include,
569569 .set_float_mode,
570 .set_align_stack,
571570 .wasm_memory_size,
572571 .int_from_error,
573572 .error_from_int,
src/target.zig+16
......@@ -607,3 +607,19 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
607607 },
608608 };
609609}
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}