From: Jim Grosbach Date: Tue, 27 Oct 2009 22:45:39 +0000 (+0000) Subject: Infrastructure for dynamic stack realignment on ARM. For now, this is off by X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=3dab2778571b5bb00b35a0adcb7011dc85158beb;p=oota-llvm.git 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 --- diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 17fc296991a..11cd1ef0f2c 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -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 ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(false), cl::desc("Reuse repeated frame index values")); +static cl::opt +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(); + 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 UnspilledCS2GPRs; ARMFunctionInfo *AFI = MF.getInfo(); + 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) { diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index 750d29f8d6a..029e468d425 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -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,