mirror of
https://github.com/ziglang/zig.git
synced 2024-11-30 00:52:52 +00:00
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
This commit is contained in:
parent
bc797a97b1
commit
ec19086aa0
@ -2902,7 +2902,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
|
||||
.breakpoint,
|
||||
.disable_instrumentation,
|
||||
.set_float_mode,
|
||||
.set_align_stack,
|
||||
.branch_hint,
|
||||
=> break :b true,
|
||||
else => break :b false,
|
||||
@ -9324,14 +9323,6 @@ fn builtinCall(
|
||||
});
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
},
|
||||
.set_align_stack => {
|
||||
const order = try expr(gz, scope, coerced_align_ri, params[0]);
|
||||
_ = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.operand = order,
|
||||
});
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
},
|
||||
|
||||
.src => {
|
||||
// Incorporate the source location into the source hash, so that
|
||||
|
@ -909,7 +909,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
||||
.wasm_memory_size,
|
||||
.splat,
|
||||
.set_float_mode,
|
||||
.set_align_stack,
|
||||
.type_info,
|
||||
.work_item_id,
|
||||
.work_group_size,
|
||||
|
@ -82,7 +82,6 @@ pub const Tag = enum {
|
||||
rem,
|
||||
return_address,
|
||||
select,
|
||||
set_align_stack,
|
||||
set_eval_branch_quota,
|
||||
set_float_mode,
|
||||
set_runtime_safety,
|
||||
@ -744,14 +743,6 @@ pub const list = list: {
|
||||
.param_count = 4,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@setAlignStack",
|
||||
.{
|
||||
.tag = .set_align_stack,
|
||||
.param_count = 1,
|
||||
.illegal_outside_function = true,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@setEvalBranchQuota",
|
||||
.{
|
||||
|
@ -1982,9 +1982,6 @@ pub const Inst = struct {
|
||||
/// Implement builtin `@setFloatMode`.
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
set_float_mode,
|
||||
/// Implement builtin `@setAlignStack`.
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
set_align_stack,
|
||||
/// Implements the `@errorCast` builtin.
|
||||
/// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
|
||||
error_cast,
|
||||
@ -4012,7 +4009,6 @@ fn findDeclsInner(
|
||||
.wasm_memory_grow,
|
||||
.prefetch,
|
||||
.set_float_mode,
|
||||
.set_align_stack,
|
||||
.error_cast,
|
||||
.await_nosuspend,
|
||||
.breakpoint,
|
||||
|
@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) {
|
||||
branch_hint: std.builtin.BranchHint,
|
||||
is_noinline: bool,
|
||||
calls_or_awaits_errorable_fn: bool,
|
||||
stack_alignment: Alignment,
|
||||
/// True if this function has an inferred error set.
|
||||
inferred_error_set: bool,
|
||||
disable_instrumentation: bool,
|
||||
|
||||
_: u17 = 0,
|
||||
_: u23 = 0,
|
||||
|
||||
pub const State = enum(u2) {
|
||||
/// The runtime function has never been referenced.
|
||||
@ -8696,7 +8695,6 @@ pub fn getFuncDecl(
|
||||
.branch_hint = .none,
|
||||
.is_noinline = key.is_noinline,
|
||||
.calls_or_awaits_errorable_fn = false,
|
||||
.stack_alignment = .none,
|
||||
.inferred_error_set = false,
|
||||
.disable_instrumentation = false,
|
||||
},
|
||||
@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes(
|
||||
.branch_hint = .none,
|
||||
.is_noinline = key.is_noinline,
|
||||
.calls_or_awaits_errorable_fn = false,
|
||||
.stack_alignment = .none,
|
||||
.inferred_error_set = true,
|
||||
.disable_instrumentation = false,
|
||||
},
|
||||
@ -8992,7 +8989,6 @@ pub fn getFuncInstance(
|
||||
.branch_hint = .none,
|
||||
.is_noinline = arg.is_noinline,
|
||||
.calls_or_awaits_errorable_fn = false,
|
||||
.stack_alignment = .none,
|
||||
.inferred_error_set = false,
|
||||
.disable_instrumentation = false,
|
||||
},
|
||||
@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes(
|
||||
.branch_hint = .none,
|
||||
.is_noinline = arg.is_noinline,
|
||||
.calls_or_awaits_errorable_fn = false,
|
||||
.stack_alignment = .none,
|
||||
.inferred_error_set = true,
|
||||
.disable_instrumentation = false,
|
||||
},
|
||||
@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
|
||||
return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
|
||||
}
|
||||
|
||||
pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
|
||||
const unwrapped_func = func.unwrap(ip);
|
||||
const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
|
||||
extra_mutex.lock();
|
||||
defer extra_mutex.unlock();
|
||||
|
||||
const analysis_ptr = ip.funcAnalysisPtr(func);
|
||||
var analysis = analysis_ptr.*;
|
||||
analysis.stack_alignment = switch (analysis.stack_alignment) {
|
||||
.none => new_stack_alignment,
|
||||
else => |old_stack_alignment| old_stack_alignment.maxStrict(new_stack_alignment),
|
||||
};
|
||||
@atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
|
||||
}
|
||||
|
||||
pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void {
|
||||
const unwrapped_func = func.unwrap(ip);
|
||||
const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
|
||||
|
34
src/Sema.zig
34
src/Sema.zig
@ -1326,11 +1326,6 @@ fn analyzeBodyInner(
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.set_align_stack => {
|
||||
try sema.zirSetAlignStack(block, extended);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.breakpoint => {
|
||||
if (!block.is_comptime) {
|
||||
_ = try block.addNoOp(.breakpoint);
|
||||
@ -6510,35 +6505,6 @@ pub fn analyzeExport(
|
||||
});
|
||||
}
|
||||
|
||||
fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
|
||||
const operand_src = block.builtinCallArgSrc(extra.node, 0);
|
||||
const src = block.nodeOffset(extra.node);
|
||||
const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
|
||||
|
||||
const func = switch (sema.owner.unwrap()) {
|
||||
.func => |func| func,
|
||||
.cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}),
|
||||
};
|
||||
|
||||
if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
|
||||
return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
|
||||
alignment.toByteUnits().?,
|
||||
});
|
||||
}
|
||||
|
||||
switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) {
|
||||
.naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
|
||||
.@"inline" => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
|
||||
else => {},
|
||||
}
|
||||
|
||||
zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
|
||||
sema.allow_memoize = false;
|
||||
}
|
||||
|
||||
fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
|
@ -3592,7 +3592,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
|
||||
else => false,
|
||||
},
|
||||
.stage2_x86_64 => switch (cc) {
|
||||
.x86_64_sysv, .x86_64_win, .naked => true,
|
||||
.x86_64_sysv, .x86_64_win, .naked => true, // stack alignment supported
|
||||
else => false,
|
||||
},
|
||||
.stage2_aarch64 => switch (cc) {
|
||||
|
@ -710,7 +710,7 @@ stack_size: u32 = 0,
|
||||
/// The stack alignment, which is 16 bytes by default. This is specified by the
|
||||
/// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md
|
||||
/// and also what the llvm backend will emit.
|
||||
/// However, local variables or the usage of `@setAlignStack` can overwrite this default.
|
||||
/// However, local variables or the usage of `incoming_stack_alignment` in a `CallingConvention` can overwrite this default.
|
||||
stack_alignment: Alignment = .@"16",
|
||||
|
||||
// For each individual Wasm valtype we store a seperate free list which
|
||||
|
@ -11,6 +11,7 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking);
|
||||
const wip_mir_log = std.log.scoped(.wip_mir);
|
||||
const math = std.math;
|
||||
const mem = std.mem;
|
||||
const target_util = @import("../../target.zig");
|
||||
const trace = @import("../../tracy.zig").trace;
|
||||
|
||||
const Air = @import("../../Air.zig");
|
||||
@ -872,7 +873,7 @@ pub fn generate(
|
||||
@intFromEnum(FrameIndex.stack_frame),
|
||||
FrameAlloc.init(.{
|
||||
.size = 0,
|
||||
.alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"),
|
||||
.alignment = target_util.stackAlignment(function.target.*, fn_type.fnCallingConvention(zcu)),
|
||||
}),
|
||||
);
|
||||
function.frame_allocs.set(
|
||||
|
@ -567,7 +567,6 @@ const Writer = struct {
|
||||
.c_undef,
|
||||
.c_include,
|
||||
.set_float_mode,
|
||||
.set_align_stack,
|
||||
.wasm_memory_size,
|
||||
.int_from_error,
|
||||
.error_from_int,
|
||||
|
@ -607,3 +607,19 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stackAlignment(target: std.Target, cc: std.builtin.CallingConvention) u64 {
|
||||
switch (cc) {
|
||||
inline else => |payload| switch (@TypeOf(payload)) {
|
||||
std.builtin.CallingConvention.CommonOptions,
|
||||
std.builtin.CallingConvention.X86RegparmOptions,
|
||||
std.builtin.CallingConvention.ArmInterruptOptions,
|
||||
std.builtin.CallingConvention.MipsInterruptOptions,
|
||||
std.builtin.CallingConvention.RiscvInterruptOptions,
|
||||
=> if (payload.incoming_stack_alignment) |a| return a,
|
||||
void => {},
|
||||
else => comptime unreachable,
|
||||
},
|
||||
}
|
||||
return target.stackAlignment();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user