diff options
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMBaseRegisterInfo.cpp | 22 | ||||
-rw-r--r-- | lib/Target/ARM/ARMFrameLowering.cpp | 11 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1RegisterInfo.cpp | 16 |
3 files changed, 44 insertions, 5 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 2608685e04..8512049e8c 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -484,11 +484,16 @@ ARMBaseRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const { bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); if (!EnableBasePointer) return false; - if (needsStackRealignment(MF) && MFI->hasVarSizedObjects()) + // When outgoing call frames are so large that we adjust the stack pointer + // around the call, we can no longer use the stack pointer to reach the + // emergency spill slot. + if (needsStackRealignment(MF) && (MFI->hasVarSizedObjects() || + !TFI->hasReservedCallFrame(MF))) return true; // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited @@ -1056,6 +1061,21 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); + // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the + // call frame setup/destroy instructions have already been eliminated. That + // means the stack pointer cannot be used to access the emergency spill slot + // when !hasReservedCallFrame(). +#ifndef NDEBUG + if (RS && FrameReg == ARM::SP && FrameIndex == RS->getScavengingFrameIndex()){ + assert(TFI->hasReservedCallFrame(MF) && + "Cannot use SP to access the emergency spill slot in " + "functions without a reserved call frame"); + assert(!MF.getFrameInfo()->hasVarSizedObjects() && + "Cannot use SP to access the emergency spill slot in " + "functions with variable sized frame objects"); + } +#endif // NDEBUG + // Special handling of dbg_value instructions. if (MI.isDebugValue()) { MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/); diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index f3a2197c23..463e4abc76 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -499,6 +499,10 @@ ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF, else if (AFI->isDPRCalleeSavedAreaFrame(FI)) return Offset - AFI->getDPRCalleeSavedAreaOffset(); + // SP can move around if there are allocas. We may also lose track of SP + // when emergency spilling inside a non-reserved call frame setup. + bool hasMovingSP = MFI->hasVarSizedObjects() || !hasReservedCallFrame(MF); + // When dynamically realigning the stack, use the frame pointer for // parameters, and the stack/base pointer for locals. if (RegInfo->needsStackRealignment(MF)) { @@ -506,7 +510,7 @@ ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF, if (isFixed) { FrameReg = RegInfo->getFrameRegister(MF); Offset = FPOffset; - } else if (MFI->hasVarSizedObjects()) { + } else if (hasMovingSP) { assert(RegInfo->hasBasePointer(MF) && "VLAs and dynamic stack alignment, but missing base pointer!"); FrameReg = RegInfo->getBaseRegister(); @@ -518,11 +522,10 @@ ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF, if (hasFP(MF) && AFI->hasStackFrame()) { // Use frame pointer to reference fixed objects. Use it for locals if // there are VLAs (and thus the SP isn't reliable as a base). - if (isFixed || (MFI->hasVarSizedObjects() && - !RegInfo->hasBasePointer(MF))) { + if (isFixed || (hasMovingSP && !RegInfo->hasBasePointer(MF))) { FrameReg = RegInfo->getFrameRegister(MF); return FPOffset; - } else if (MFI->hasVarSizedObjects()) { + } else if (hasMovingSP) { assert(RegInfo->hasBasePointer(MF) && "missing base pointer!"); if (AFI->isThumb2Function()) { // Try to use the frame pointer if we can, else use the base pointer diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp index 87e27bd0a1..1613acd7a6 100644 --- a/lib/Target/ARM/Thumb1RegisterInfo.cpp +++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp @@ -28,6 +28,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" @@ -624,6 +625,21 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, FrameReg = BasePtr; } + // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the + // call frame setup/destroy instructions have already been eliminated. That + // means the stack pointer cannot be used to access the emergency spill slot + // when !hasReservedCallFrame(). +#ifndef NDEBUG + if (RS && FrameReg == ARM::SP && FrameIndex == RS->getScavengingFrameIndex()){ + assert(MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF) && + "Cannot use SP to access the emergency spill slot in " + "functions without a reserved call frame"); + assert(!MF.getFrameInfo()->hasVarSizedObjects() && + "Cannot use SP to access the emergency spill slot in " + "functions with variable sized frame objects"); + } +#endif // NDEBUG + // Special handling of dbg_value instructions. if (MI.isDebugValue()) { MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/); |