summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2017-10-22 11:56:35 +0000
committerMomchil Velikov <momchil.velikov@arm.com>2017-10-22 11:56:35 +0000
commitd6a4ab3d4917c4e8efc7bae806db5599c7f42f7e (patch)
treee0c8fbc0fa3459271b330861215aad7ffd7bc90b /llvm/lib/Target
parent92d5ce3bd43ff480e5baea99a1dd8b0b8150f675 (diff)
downloadbcm5719-llvm-d6a4ab3d4917c4e8efc7bae806db5599c7f42f7e.tar.gz
bcm5719-llvm-d6a4ab3d4917c4e8efc7bae806db5599c7f42f7e.zip
[ARM] Dynamic stack alignment for 16-bit Thumb
This patch implements dynamic stack (re-)alignment for 16-bit Thumb. When targeting processors, which support only the 16-bit Thumb instruction set the compiler ignores the alignment attributes of automatic variables and may silently generate incorrect code. Differential revision: https://reviews.llvm.org/D38143 llvm-svn: 316289
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp6
-rw-r--r--llvm/lib/Target/ARM/ARMFrameLowering.cpp14
-rw-r--r--llvm/lib/Target/ARM/Thumb1FrameLowering.cpp34
3 files changed, 38 insertions, 16 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index bf39aebaf44..63b14ee98d7 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -391,16 +391,12 @@ bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
const MachineRegisterInfo *MRI = &MF.getRegInfo();
- const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
const ARMFrameLowering *TFI = getFrameLowering(MF);
// 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.
+ // 2. There are VLAs in the function and the base pointer is disabled.
if (!TargetRegisterInfo::canRealignStack(MF))
return false;
- if (AFI->isThumb1OnlyFunction())
- return false;
// Stack realignment requires a frame pointer. If we already started
// register allocation with frame pointer elimination, it is too late now.
if (!MRI->canReserveReg(getFramePointerReg(MF.getSubtarget<ARMSubtarget>())))
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 4af744f5ec3..ce4add974d6 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1610,14 +1610,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
if (AFI->getArgRegsSaveSize() > 0)
SavedRegs.set(ARM::LR);
- // Spill R4 if Thumb1 epilogue has to restore SP from FP. We don't know
- // 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.
+ // Spill R4 if Thumb1 epilogue has to restore SP from FP or the function
+ // requires stack alignment. We don't know 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.
// FIXME: It will be better just to find spare register here.
- unsigned StackSize = MFI.estimateStackSize(MF);
- if (MFI.hasVarSizedObjects() || StackSize > 508)
+ if (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) ||
+ MFI.estimateStackSize(MF) > 508)
SavedRegs.set(ARM::R4);
}
diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
index 13068992e8f..4f330e3a884 100644
--- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -352,10 +352,36 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF,
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
- // Thumb1 does not currently support dynamic stack realignment. Report a
- // fatal error rather then silently generate bad code.
- if (RegInfo->needsStackRealignment(MF))
- report_fatal_error("Dynamic stack realignment not supported for thumb1.");
+ if (RegInfo->needsStackRealignment(MF)) {
+ const unsigned NrBitsToZero = countTrailingZeros(MFI.getMaxAlignment());
+ // Emit the following sequence, using R4 as a temporary, since we cannot use
+ // SP as a source or destination register for the shifts:
+ // mov r4, sp
+ // lsrs r4, r4, #NrBitsToZero
+ // lsls r4, r4, #NrBitsToZero
+ // mov sp, r4
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4)
+ .addReg(ARM::SP, RegState::Kill)
+ .add(predOps(ARMCC::AL));
+
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSRri), ARM::R4)
+ .addDef(ARM::CPSR)
+ .addReg(ARM::R4, RegState::Kill)
+ .addImm(NrBitsToZero)
+ .add(predOps(ARMCC::AL));
+
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSLri), ARM::R4)
+ .addDef(ARM::CPSR)
+ .addReg(ARM::R4, RegState::Kill)
+ .addImm(NrBitsToZero)
+ .add(predOps(ARMCC::AL));
+
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
+ .addReg(ARM::R4, RegState::Kill)
+ .add(predOps(ARMCC::AL));
+
+ AFI->setShouldRestoreSPFromFP(true);
+ }
// 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
OpenPOWER on IntegriCloud