mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-29 07:53:33 +00:00
Infrastructure for dynamic stack realignment on ARM. For now, this is off by
default behind a command line option. This will enable better performance for vectors on NEON enabled processors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85333 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de020736c0
commit
3dab277857
@ -29,6 +29,7 @@
|
||||
#include "llvm/CodeGen/MachineLocation.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetFrameInfo.h"
|
||||
@ -48,6 +49,10 @@ static cl::opt<bool>
|
||||
ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(false),
|
||||
cl::desc("Reuse repeated frame index values"));
|
||||
|
||||
static cl::opt<bool>
|
||||
ARMDynamicStackAlign("arm-dynamic-stack-alignment", cl::Hidden, cl::init(false),
|
||||
cl::desc("Dynamically re-align the stack as needed"));
|
||||
|
||||
unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
|
||||
bool *isSPVFP) {
|
||||
if (isSPVFP)
|
||||
@ -466,6 +471,21 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) {
|
||||
unsigned MaxAlign = 0;
|
||||
|
||||
for (int i = FFI->getObjectIndexBegin(),
|
||||
e = FFI->getObjectIndexEnd(); i != e; ++i) {
|
||||
if (FFI->isDeadObjectIndex(i))
|
||||
continue;
|
||||
|
||||
unsigned Align = FFI->getObjectAlignment(i);
|
||||
MaxAlign = std::max(MaxAlign, Align);
|
||||
}
|
||||
|
||||
return MaxAlign;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
@ -473,10 +493,28 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
|
||||
bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
return (NoFramePointerElim ||
|
||||
needsStackRealignment(MF) ||
|
||||
MFI->hasVarSizedObjects() ||
|
||||
MFI->isFrameAddressTaken());
|
||||
}
|
||||
|
||||
bool ARMBaseRegisterInfo::
|
||||
needsStackRealignment(const MachineFunction &MF) const {
|
||||
// Only do this for ARM if explicitly enabled
|
||||
// FIXME: Once it's passing all the tests, enable by default
|
||||
if (!ARMDynamicStackAlign)
|
||||
return false;
|
||||
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
|
||||
return (RealignStack &&
|
||||
!AFI->isThumb1OnlyFunction() &&
|
||||
(MFI->getMaxAlignment() > StackAlign) &&
|
||||
!MFI->hasVarSizedObjects());
|
||||
|
||||
}
|
||||
|
||||
bool ARMBaseRegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
if (NoFramePointerElim && MFI->hasCalls())
|
||||
@ -552,6 +590,16 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
SmallVector<unsigned, 4> UnspilledCS2GPRs;
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
|
||||
// Calculate and set max stack object alignment early, so we can decide
|
||||
// whether we will need stack realignment (and thus FP).
|
||||
if (ARMDynamicStackAlign) {
|
||||
unsigned MaxAlign = std::max(MFI->getMaxAlignment(),
|
||||
calculateMaxStackAlignment(MFI));
|
||||
MFI->setMaxAlignment(MaxAlign);
|
||||
}
|
||||
|
||||
// Don't spill FP if the frame can be eliminated. This is determined
|
||||
// by scanning the callee-save registers to see if any is used.
|
||||
const unsigned *CSRegs = getCalleeSavedRegs();
|
||||
@ -1085,16 +1133,28 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int FrameIndex = MI.getOperand(i).getIndex();
|
||||
int Offset = MFI->getObjectOffset(FrameIndex) + MFI->getStackSize() + SPAdj;
|
||||
|
||||
// When doing dynamic stack realignment, all of these need to change(?)
|
||||
if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
|
||||
Offset -= AFI->getGPRCalleeSavedArea1Offset();
|
||||
else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
|
||||
Offset -= AFI->getGPRCalleeSavedArea2Offset();
|
||||
else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
|
||||
Offset -= AFI->getDPRCalleeSavedAreaOffset();
|
||||
else if (hasFP(MF) && AFI->hasStackFrame()) {
|
||||
else if (needsStackRealignment(MF)) {
|
||||
// When dynamically realigning the stack, use the frame pointer for
|
||||
// parameters, and the stack pointer for locals.
|
||||
assert (hasFP(MF) && "dynamic stack realignment without a FP!");
|
||||
if (FrameIndex < 0) {
|
||||
FrameReg = getFrameRegister(MF);
|
||||
Offset -= AFI->getFramePtrSpillOffset();
|
||||
// When referencing from the frame pointer, stack pointer adjustments
|
||||
// don't matter.
|
||||
SPAdj = 0;
|
||||
}
|
||||
} else if (hasFP(MF) && AFI->hasStackFrame()) {
|
||||
assert(SPAdj == 0 && "Unexpected stack offset!");
|
||||
// Use frame pointer to reference fixed objects unless this is a
|
||||
// frameless function,
|
||||
// frameless function.
|
||||
FrameReg = getFrameRegister(MF);
|
||||
Offset -= AFI->getFramePtrSpillOffset();
|
||||
}
|
||||
@ -1303,6 +1363,18 @@ emitPrologue(MachineFunction &MF) const {
|
||||
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
||||
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
||||
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
||||
|
||||
// If we need dynamic stack realignment, do it here.
|
||||
if (needsStackRealignment(MF)) {
|
||||
unsigned Opc;
|
||||
unsigned MaxAlign = MFI->getMaxAlignment();
|
||||
assert (!AFI->isThumb1OnlyFunction());
|
||||
Opc = AFI->isThumbFunction() ? ARM::t2BICri : ARM::BICri;
|
||||
|
||||
AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), ARM::SP)
|
||||
.addReg(ARM::SP, RegState::Kill)
|
||||
.addImm(MaxAlign-1)));
|
||||
}
|
||||
}
|
||||
|
||||
static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
|
||||
|
@ -96,6 +96,8 @@ public:
|
||||
|
||||
bool hasFP(const MachineFunction &MF) const;
|
||||
|
||||
bool needsStackRealignment(const MachineFunction &MF) const;
|
||||
|
||||
bool cannotEliminateFrame(const MachineFunction &MF) const;
|
||||
|
||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
|
Loading…
Reference in New Issue
Block a user