[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:
David Majnemer 2016-01-04 04:49:41 +00:00
parent 82e76d50b1
commit f124911f7a
6 changed files with 33 additions and 25 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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) ||