mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 09:32:20 +00:00
Factor out redzone ABI checks [NFCI]
As requested in D58632, cleanup our red zone detection logic in the X86 backend. The existing X86MachineFunctionInfo flag is used to track whether we *use* the redzone (via a particularly optimization?), but there's no common way to check whether the function *has* a red zone. I'd appreciate careful review of the uses being updated. I think they are NFC, but a careful eye from someone else would be appreciated. Differential Revision: https://reviews.llvm.org/D61799 llvm-svn: 360479
This commit is contained in:
parent
b3d6073b3c
commit
849ef823df
@ -872,6 +872,17 @@ void X86FrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB,
|
||||
MI->getOperand(3).setIsDead();
|
||||
}
|
||||
|
||||
bool X86FrameLowering::has128ByteRedZone(const MachineFunction& MF) const {
|
||||
// x86-64 (non Win64) has a 128 byte red zone which is guaranteed not to be
|
||||
// clobbered by any interrupt handler.
|
||||
assert(&STI == &MF.getSubtarget<X86Subtarget>() &&
|
||||
"MF used frame lowering for wrong subtarget");
|
||||
const Function &Fn = MF.getFunction();
|
||||
const bool IsWin64CC = STI.isCallingConvWin64(Fn.getCallingConv());
|
||||
return Is64Bit && !IsWin64CC && !Fn.hasFnAttribute(Attribute::NoRedZone);
|
||||
}
|
||||
|
||||
|
||||
/// emitPrologue - Push callee-saved registers onto the stack, which
|
||||
/// automatically adjust the stack pointer. Adjust the stack pointer to allocate
|
||||
/// space for local variables. Also emit labels used by the exception handler to
|
||||
@ -976,7 +987,6 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
MF.hasEHFunclets() && Personality == EHPersonality::CoreCLR;
|
||||
bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
|
||||
bool HasFP = hasFP(MF);
|
||||
bool IsWin64CC = STI.isCallingConvWin64(Fn.getCallingConv());
|
||||
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||
bool NeedsWin64CFI = IsWin64Prologue && Fn.needsUnwindTableEntry();
|
||||
// FIXME: Emit FPO data for EH funclets.
|
||||
@ -1030,12 +1040,11 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
// pointer, calls, or dynamic alloca then we do not need to adjust the
|
||||
// stack pointer (we fit in the Red Zone). We also check that we don't
|
||||
// push and pop from the stack.
|
||||
if (Is64Bit && !Fn.hasFnAttribute(Attribute::NoRedZone) &&
|
||||
if (has128ByteRedZone(MF) &&
|
||||
!TRI->needsStackRealignment(MF) &&
|
||||
!MFI.hasVarSizedObjects() && // No dynamic alloca.
|
||||
!MFI.adjustsStack() && // No calls.
|
||||
!UseStackProbe && // No stack probes.
|
||||
!IsWin64CC && // Win64 has no Red Zone
|
||||
!MFI.hasCopyImplyingStackAdjustment() && // Don't push and pop.
|
||||
!MF.shouldSplitStack()) { // Regular stack
|
||||
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
||||
|
@ -171,6 +171,10 @@ public:
|
||||
|
||||
unsigned getInitialCFARegister(const MachineFunction &MF) const override;
|
||||
|
||||
/// Return true if the function has a redzone (accessible bytes past the
|
||||
/// frame of the top of stack function) as part of it's ABI.
|
||||
bool has128ByteRedZone(const MachineFunction& MF) const;
|
||||
|
||||
private:
|
||||
uint64_t calculateMaxStackAlign(const MachineFunction &MF) const;
|
||||
|
||||
|
@ -7464,7 +7464,7 @@ bool X86InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF,
|
||||
|
||||
// Does the function use a red zone? If it does, then we can't risk messing
|
||||
// with the stack.
|
||||
if (!F.hasFnAttribute(Attribute::NoRedZone)) {
|
||||
if (Subtarget.getFrameLowering()->has128ByteRedZone(MF)) {
|
||||
// It could have a red zone. If it does, then we don't want to touch it.
|
||||
const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
||||
if (!X86FI || X86FI->getUsesRedZone())
|
||||
|
@ -2473,7 +2473,7 @@ void X86SpeculativeLoadHardeningPass::tracePredStateThroughCall(
|
||||
// If we have no red zones or if the function returns twice (possibly without
|
||||
// using the `ret` instruction) like setjmp, we need to save the expected
|
||||
// return address prior to the call.
|
||||
if (MF.getFunction().hasFnAttribute(Attribute::NoRedZone) ||
|
||||
if (!Subtarget->getFrameLowering()->has128ByteRedZone(MF) ||
|
||||
MF.exposesReturnsTwice()) {
|
||||
// If we don't have red zones, we need to compute the expected return
|
||||
// address prior to the call and store it in a register that lives across
|
||||
|
Loading…
Reference in New Issue
Block a user