| author | |
| committer | |
| log | ec19086aa0491024622c444b0d9310560de9e6f0 |
| tree | 000cb85a1af4bf6fe1cb6d8dc40e3f1817e7e2dd |
| parent | bc797a97b1f7476b620567ff32b7a396ebdb4c9c |
| signature |
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: #2120911 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 | 2902 | .breakpoint, |
| 2903 | 2903 | .disable_instrumentation, |
| 2904 | 2904 | .set_float_mode, |
| 2905 | .set_align_stack, | |
| 2906 | 2905 | .branch_hint, |
| 2907 | 2906 | => break :b true, |
| 2908 | 2907 | else => break :b false, |
| ... | ... | @@ -9324,14 +9323,6 @@ fn builtinCall( |
| 9324 | 9323 | }); |
| 9325 | 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 | }, | |
| 9335 | 9326 | |
| 9336 | 9327 | .src => { |
| 9337 | 9328 | // 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 | 909 | .wasm_memory_size, |
| 910 | 910 | .splat, |
| 911 | 911 | .set_float_mode, |
| 912 | .set_align_stack, | |
| 913 | 912 | .type_info, |
| 914 | 913 | .work_item_id, |
| 915 | 914 | .work_group_size, |
lib/std/zig/BuiltinFn.zig-9| ... | ... | @@ -82,7 +82,6 @@ pub const Tag = enum { |
| 82 | 82 | rem, |
| 83 | 83 | return_address, |
| 84 | 84 | select, |
| 85 | set_align_stack, | |
| 86 | 85 | set_eval_branch_quota, |
| 87 | 86 | set_float_mode, |
| 88 | 87 | set_runtime_safety, |
| ... | ... | @@ -744,14 +743,6 @@ pub const list = list: { |
| 744 | 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 | 747 | "@setEvalBranchQuota", |
| 757 | 748 | .{ |
lib/std/zig/Zir.zig-4| ... | ... | @@ -1982,9 +1982,6 @@ pub const Inst = struct { |
| 1982 | 1982 | /// Implement builtin `@setFloatMode`. |
| 1983 | 1983 | /// `operand` is payload index to `UnNode`. |
| 1984 | 1984 | set_float_mode, |
| 1985 | /// Implement builtin `@setAlignStack`. | |
| 1986 | /// `operand` is payload index to `UnNode`. | |
| 1987 | set_align_stack, | |
| 1988 | 1985 | /// Implements the `@errorCast` builtin. |
| 1989 | 1986 | /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand. |
| 1990 | 1987 | error_cast, |
| ... | ... | @@ -4012,7 +4009,6 @@ fn findDeclsInner( |
| 4012 | 4009 | .wasm_memory_grow, |
| 4013 | 4010 | .prefetch, |
| 4014 | 4011 | .set_float_mode, |
| 4015 | .set_align_stack, | |
| 4016 | 4012 | .error_cast, |
| 4017 | 4013 | .await_nosuspend, |
| 4018 | 4014 | .breakpoint, |
src/InternPool.zig+1-21| ... | ... | @@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) { |
| 5618 | 5618 | branch_hint: std.builtin.BranchHint, |
| 5619 | 5619 | is_noinline: bool, |
| 5620 | 5620 | calls_or_awaits_errorable_fn: bool, |
| 5621 | stack_alignment: Alignment, | |
| 5622 | 5621 | /// True if this function has an inferred error set. |
| 5623 | 5622 | inferred_error_set: bool, |
| 5624 | 5623 | disable_instrumentation: bool, |
| 5625 | 5624 | |
| 5626 | _: u17 = 0, | |
| 5625 | _: u23 = 0, | |
| 5627 | 5626 | |
| 5628 | 5627 | pub const State = enum(u2) { |
| 5629 | 5628 | /// The runtime function has never been referenced. |
| ... | ... | @@ -8696,7 +8695,6 @@ pub fn getFuncDecl( |
| 8696 | 8695 | .branch_hint = .none, |
| 8697 | 8696 | .is_noinline = key.is_noinline, |
| 8698 | 8697 | .calls_or_awaits_errorable_fn = false, |
| 8699 | .stack_alignment = .none, | |
| 8700 | 8698 | .inferred_error_set = false, |
| 8701 | 8699 | .disable_instrumentation = false, |
| 8702 | 8700 | }, |
| ... | ... | @@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes( |
| 8800 | 8798 | .branch_hint = .none, |
| 8801 | 8799 | .is_noinline = key.is_noinline, |
| 8802 | 8800 | .calls_or_awaits_errorable_fn = false, |
| 8803 | .stack_alignment = .none, | |
| 8804 | 8801 | .inferred_error_set = true, |
| 8805 | 8802 | .disable_instrumentation = false, |
| 8806 | 8803 | }, |
| ... | ... | @@ -8992,7 +8989,6 @@ pub fn getFuncInstance( |
| 8992 | 8989 | .branch_hint = .none, |
| 8993 | 8990 | .is_noinline = arg.is_noinline, |
| 8994 | 8991 | .calls_or_awaits_errorable_fn = false, |
| 8995 | .stack_alignment = .none, | |
| 8996 | 8992 | .inferred_error_set = false, |
| 8997 | 8993 | .disable_instrumentation = false, |
| 8998 | 8994 | }, |
| ... | ... | @@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes( |
| 9092 | 9088 | .branch_hint = .none, |
| 9093 | 9089 | .is_noinline = arg.is_noinline, |
| 9094 | 9090 | .calls_or_awaits_errorable_fn = false, |
| 9095 | .stack_alignment = .none, | |
| 9096 | 9091 | .inferred_error_set = true, |
| 9097 | 9092 | .disable_instrumentation = false, |
| 9098 | 9093 | }, |
| ... | ... | @@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis { |
| 11871 | 11866 | return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered); |
| 11872 | 11867 | } |
| 11873 | 11868 | |
| 11874 | pub 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 | ||
| 11889 | 11869 | pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void { |
| 11890 | 11870 | const unwrapped_func = func.unwrap(ip); |
| 11891 | 11871 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; |
src/Sema.zig-34| ... | ... | @@ -1326,11 +1326,6 @@ fn analyzeBodyInner( |
| 1326 | 1326 | i += 1; |
| 1327 | 1327 | continue; |
| 1328 | 1328 | }, |
| 1329 | .set_align_stack => { | |
| 1330 | try sema.zirSetAlignStack(block, extended); | |
| 1331 | i += 1; | |
| 1332 | continue; | |
| 1333 | }, | |
| 1334 | 1329 | .breakpoint => { |
| 1335 | 1330 | if (!block.is_comptime) { |
| 1336 | 1331 | _ = try block.addNoOp(.breakpoint); |
| ... | ... | @@ -6510,35 +6505,6 @@ pub fn analyzeExport( |
| 6510 | 6505 | }); |
| 6511 | 6506 | } |
| 6512 | 6507 | |
| 6513 | fn 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 | ||
| 6542 | 6508 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { |
| 6543 | 6509 | const pt = sema.pt; |
| 6544 | 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 | 3592 | else => false, |
| 3593 | 3593 | }, |
| 3594 | 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 | 3596 | else => false, |
| 3597 | 3597 | }, |
| 3598 | 3598 | .stage2_aarch64 => switch (cc) { |
src/arch/wasm/CodeGen.zig+1-1| ... | ... | @@ -710,7 +710,7 @@ stack_size: u32 = 0, |
| 710 | 710 | /// The stack alignment, which is 16 bytes by default. This is specified by the |
| 711 | 711 | /// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md |
| 712 | 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. | |
| 714 | 714 | stack_alignment: Alignment = .@"16", |
| 715 | 715 | |
| 716 | 716 | // 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 | 11 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 12 | 12 | const math = std.math; |
| 13 | 13 | const mem = std.mem; |
| 14 | const target_util = @import("../../target.zig"); | |
| 14 | 15 | const trace = @import("../../tracy.zig").trace; |
| 15 | 16 | |
| 16 | 17 | const Air = @import("../../Air.zig"); |
| ... | ... | @@ -872,7 +873,7 @@ pub fn generate( |
| 872 | 873 | @intFromEnum(FrameIndex.stack_frame), |
| 873 | 874 | FrameAlloc.init(.{ |
| 874 | 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 | 879 | function.frame_allocs.set( |
src/print_zir.zig-1| ... | ... | @@ -567,7 +567,6 @@ const Writer = struct { |
| 567 | 567 | .c_undef, |
| 568 | 568 | .c_include, |
| 569 | 569 | .set_float_mode, |
| 570 | .set_align_stack, | |
| 571 | 570 | .wasm_memory_size, |
| 572 | 571 | .int_from_error, |
| 573 | 572 | .error_from_int, |
src/target.zig+16| ... | ... | @@ -607,3 +607,19 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt |
| 607 | 607 | }, |
| 608 | 608 | }; |
| 609 | 609 | } |
| 610 | ||
| 611 | pub 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 | } |