| 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,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 | }, | ||
| 9335 | 9326 | ||
| 9336 | .src => { | 9327 | .src => { |
| 9337 | // Incorporate the source location into the source hash, so that | 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,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, |
| 5625 | 5624 | ||
| 5626 | _: u17 = 0, | 5625 | _: u23 = 0, |
| 5627 | 5626 | ||
| 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 | } |
| 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 | pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void { | 11869 | pub 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 | } |
| 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 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { | 6508 | fn 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 the | 710 | /// 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.md | 711 | /// 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. |
| 714 | stack_alignment: Alignment = .@"16", | 714 | stack_alignment: Alignment = .@"16", |
| 715 | 715 | ||
| 716 | // For each individual Wasm valtype we store a seperate free list which | 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,6 +11,7 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking); |
| 11 | const wip_mir_log = std.log.scoped(.wip_mir); | 11 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 12 | const math = std.math; | 12 | const math = std.math; |
| 13 | const mem = std.mem; | 13 | const mem = std.mem; |
| 14 | const target_util = @import("../../target.zig"); | ||
| 14 | const trace = @import("../../tracy.zig").trace; | 15 | const trace = @import("../../tracy.zig").trace; |
| 15 | 16 | ||
| 16 | const Air = @import("../../Air.zig"); | 17 | const 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 | |||
| 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 | } |