mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 08:29:43 +00:00
[X86] Make hasFP constant time
We need a frame pointer if there is a push/pop sequence after the prologue in order to unwind the stack. Scanning the instructions to figure out if this happened made hasFP not constant-time which is a violation of expectations. Let's compute this up-front and reuse that computation when we need it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256730 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
82e76d50b1
commit
f124911f7a
@ -2269,6 +2269,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return true if the MachineFunction contains a COPY which would imply
|
||||
/// HasOpaqueSPAdjustment.
|
||||
virtual bool hasCopyImplyingStackAdjustment(MachineFunction *MF) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Perform necessary initialization to handle a subset of CSRs explicitly
|
||||
/// via copies. This function is called at the beginning of instruction
|
||||
/// selection.
|
||||
|
@ -633,6 +633,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
||||
MRI.replaceRegWith(From, To);
|
||||
}
|
||||
|
||||
if (TLI->hasCopyImplyingStackAdjustment(MF))
|
||||
MFI->setHasOpaqueSPAdjustment(true);
|
||||
|
||||
// Freeze the set of reserved registers now that MachineFrameInfo has been
|
||||
// set up. All the information required by getReservedRegs() should be
|
||||
// available now.
|
||||
|
@ -78,23 +78,6 @@ X86FrameLowering::needsFrameIndexResolution(const MachineFunction &MF) const {
|
||||
MF.getInfo<X86MachineFunctionInfo>()->getHasPushSequences();
|
||||
}
|
||||
|
||||
/// usesTheStack - This function checks if any of the users of EFLAGS
|
||||
/// copies the EFLAGS. We know that the code that lowers COPY of EFLAGS has
|
||||
/// to use the stack, and if we don't adjust the stack we clobber the first
|
||||
/// frame index.
|
||||
/// See X86InstrInfo::copyPhysReg.
|
||||
static bool usesTheStack(const MachineFunction &MF) {
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
return any_of(MRI.reg_instructions(X86::EFLAGS),
|
||||
[](const MachineInstr &RI) { return RI.isCopy(); });
|
||||
}
|
||||
|
||||
static bool doesStackUseImplyFP(const MachineFunction &MF) {
|
||||
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
|
||||
return IsWin64Prologue && usesTheStack(MF);
|
||||
}
|
||||
|
||||
/// hasFP - Return true if the specified function should have a dedicated frame
|
||||
/// pointer register. This is true if the function has variable sized allocas
|
||||
/// or if frame pointer elimination is disabled.
|
||||
@ -108,8 +91,7 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
|
||||
MFI->isFrameAddressTaken() || MFI->hasOpaqueSPAdjustment() ||
|
||||
MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
|
||||
MMI.callsUnwindInit() || MMI.hasEHFunclets() || MMI.callsEHReturn() ||
|
||||
MFI->hasStackMap() || MFI->hasPatchPoint() ||
|
||||
doesStackUseImplyFP(MF));
|
||||
MFI->hasStackMap() || MFI->hasPatchPoint());
|
||||
}
|
||||
|
||||
static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) {
|
||||
@ -961,11 +943,11 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
// push and pop from the stack.
|
||||
if (Is64Bit && !Fn->hasFnAttribute(Attribute::NoRedZone) &&
|
||||
!TRI->needsStackRealignment(MF) &&
|
||||
!MFI->hasVarSizedObjects() && // No dynamic alloca.
|
||||
!MFI->adjustsStack() && // No calls.
|
||||
!IsWin64CC && // Win64 has no Red Zone
|
||||
!usesTheStack(MF) && // Don't push and pop.
|
||||
!MF.shouldSplitStack()) { // Regular stack
|
||||
!MFI->hasVarSizedObjects() && // No dynamic alloca.
|
||||
!MFI->adjustsStack() && // No calls.
|
||||
!IsWin64CC && // Win64 has no Red Zone
|
||||
!MFI->hasOpaqueSPAdjustment() && // Don't push and pop.
|
||||
!MF.shouldSplitStack()) { // Regular stack
|
||||
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
||||
if (HasFP) MinSize += SlotSize;
|
||||
StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
|
||||
|
@ -27982,6 +27982,18 @@ bool X86TargetLowering::isTypeDesirableForOp(unsigned Opc, EVT VT) const {
|
||||
}
|
||||
}
|
||||
|
||||
/// This function checks if any of the users of EFLAGS copies the EFLAGS. We
|
||||
/// know that the code that lowers COPY of EFLAGS has to use the stack, and if
|
||||
/// we don't adjust the stack we clobber the first frame index.
|
||||
/// See X86InstrInfo::copyPhysReg.
|
||||
bool X86TargetLowering::hasCopyImplyingStackAdjustment(
|
||||
MachineFunction *MF) const {
|
||||
const MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||
|
||||
return any_of(MRI.reg_instructions(X86::EFLAGS),
|
||||
[](const MachineInstr &RI) { return RI.isCopy(); });
|
||||
}
|
||||
|
||||
/// IsDesirableToPromoteOp - This method query the target whether it is
|
||||
/// beneficial for dag combiner to promote the specified node. If true, it
|
||||
/// should return the desired promotion type by reference.
|
||||
|
@ -697,6 +697,10 @@ namespace llvm {
|
||||
/// and some i16 instructions are slow.
|
||||
bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const override;
|
||||
|
||||
/// Return true if the MachineFunction contains a COPY which would imply
|
||||
/// HasOpaqueSPAdjustment.
|
||||
bool hasCopyImplyingStackAdjustment(MachineFunction *MF) const override;
|
||||
|
||||
MachineBasicBlock *
|
||||
EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB) const override;
|
||||
|
@ -4453,7 +4453,8 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
// such as TF/IF/DF, which LLVM doesn't model.
|
||||
//
|
||||
// Notice that we have to adjust the stack if we don't want to clobber the
|
||||
// first frame index. See X86FrameLowering.cpp - usesTheStack.
|
||||
// first frame index.
|
||||
// See X86ISelLowering.cpp - X86::hasCopyImplyingStackAdjustment.
|
||||
|
||||
|
||||
bool AXDead = (Reg == AX) ||
|
||||
|
Loading…
Reference in New Issue
Block a user