Attempt to fix dynamic stack realignment for thumb1 functions. It is in fact

useful if an optimization assumes the stack has been realigned.  Credit to
Eli for his assistance.
rdar://10043857

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140924 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chad Rosier 2011-10-01 02:03:18 +00:00
parent b2ab2fa524
commit 5249041125
3 changed files with 27 additions and 7 deletions

View File

@ -626,13 +626,10 @@ bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
// We can't realign the stack if:
// 1. Dynamic stack realignment is explicitly disabled,
// 2. This is a Thumb1 function (it's not useful, so we don't bother), or
// 3. There are VLAs in the function and the base pointer is disabled.
return (RealignStack && !AFI->isThumb1OnlyFunction() &&
(!MFI->hasVarSizedObjects() || EnableBasePointer));
// 2. There are VLAs in the function and the base pointer is disabled.
return (RealignStack && (!MFI->hasVarSizedObjects() || EnableBasePointer));
}
bool ARMBaseRegisterInfo::

View File

@ -881,10 +881,12 @@ ARMFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// for sure what the stack size will be, but for this, an estimate is good
// enough. If there anything changes it, it'll be a spill, which implies
// we've used all the registers and so R4 is already used, so not marking
// it here will be OK.
// it here will be OK. Also spill R4 if Thumb1 function requires stack
// realignment.
// FIXME: It will be better just to find spare register here.
unsigned StackSize = estimateStackSize(MF);
if (MFI->hasVarSizedObjects() || StackSize > 508)
if (MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) ||
StackSize > 508)
MF.getRegInfo().setPhysRegUsed(ARM::R4);
}

View File

@ -155,6 +155,27 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
if (RegInfo->needsStackRealignment(MF)) {
// We cannot use sp as source/dest register here, thus we're emitting the
// following sequence:
// mov r4, sp
// lsrs r4, r4, Log2MaxAlign
// lsls r4, r4, Log2MaxAlign
// mov sp, r4
unsigned MaxAlign = MFI->getMaxAlignment();
unsigned Log2MaxAlign = Log2_32(MaxAlign);
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4)
.addReg(ARM::SP, RegState::Kill));
AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSRri), ARM::R4))
.addReg(ARM::R4, RegState::Kill)
.addImm(Log2MaxAlign));
AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSLri), ARM::R4))
.addReg(ARM::R4, RegState::Kill)
.addImm(Log2MaxAlign));
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
.addReg(ARM::R4, RegState::Kill));
}
// If we need a base pointer, set it up here. It's whatever the value
// of the stack pointer is at this point. Any variable size objects
// will be allocated after this, so we can still use the base pointer