aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@apple.com>2011-10-01 02:03:18 +0000
committerChad Rosier <mcrosier@apple.com>2011-10-01 02:03:18 +0000
commit52490411259ccc34b8c59f3532e78442a46fffd7 (patch)
tree5f5869382a763dcf72f2d4e10a5d21d14f2159b5
parentb2ab2fa524f3f90376639037bd81924483cca0af (diff)
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
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp7
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp6
-rw-r--r--lib/Target/ARM/Thumb1FrameLowering.cpp21
3 files changed, 27 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 7c42342229..48e3c52460 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -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::
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 2d1de6fe8e..4bac6c5fa9 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -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);
}
diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp
index d4d59ea59d..9ff3ffcfa2 100644
--- a/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -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