From 52490411259ccc34b8c59f3532e78442a46fffd7 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Sat, 1 Oct 2011 02:03:18 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 7 ++----- lib/Target/ARM/ARMFrameLowering.cpp | 6 ++++-- lib/Target/ARM/Thumb1FrameLowering.cpp | 21 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 7c42342229a..48e3c524606 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(); // 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 2d1de6fe8e9..4bac6c5fa95 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 d4d59ea59da..9ff3ffcfa2b 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