aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMFrameInfo.cpp
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2010-11-18 21:19:35 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2010-11-18 21:19:35 +0000
commitd0c38176690e9602a93a20a43f1bd084564a8116 (patch)
treed4c7a39ff5665d4adb34f193c2256f1c6d033181 /lib/Target/ARM/ARMFrameInfo.cpp
parentb9064bb96458ab48a878e1a7e678cada2e22ab7a (diff)
downloadexternal_llvm-d0c38176690e9602a93a20a43f1bd084564a8116.tar.gz
external_llvm-d0c38176690e9602a93a20a43f1bd084564a8116.tar.bz2
external_llvm-d0c38176690e9602a93a20a43f1bd084564a8116.zip
Move hasFP() and few related hooks to TargetFrameInfo.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119740 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMFrameInfo.cpp')
-rw-r--r--lib/Target/ARM/ARMFrameInfo.cpp50
1 files changed, 48 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMFrameInfo.cpp b/lib/Target/ARM/ARMFrameInfo.cpp
index 3417ae2659..fa110963af 100644
--- a/lib/Target/ARM/ARMFrameInfo.cpp
+++ b/lib/Target/ARM/ARMFrameInfo.cpp
@@ -17,9 +17,55 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/Target/TargetOptions.h"
using namespace llvm;
+/// hasFP - Return true if the specified function should have a dedicated frame
+/// pointer register. This is true if the function has variable sized allocas
+/// or if frame pointer elimination is disabled.
+///
+bool ARMFrameInfo::hasFP(const MachineFunction &MF) const {
+ const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
+
+ // Mac OS X requires FP not to be clobbered for backtracing purpose.
+ if (STI.isTargetDarwin())
+ return true;
+
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ // Always eliminate non-leaf frame pointers.
+ return ((DisableFramePointerElim(MF) && MFI->hasCalls()) ||
+ RegInfo->needsStackRealignment(MF) ||
+ MFI->hasVarSizedObjects() ||
+ MFI->isFrameAddressTaken());
+}
+
+// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+// not required, we reserve argument space for call sites in the function
+// immediately on entry to the current function. This eliminates the need for
+// add/sub sp brackets around call sites. Returns true if the call frame is
+// included as part of the stack frame.
+bool ARMFrameInfo::hasReservedCallFrame(const MachineFunction &MF) const {
+ const MachineFrameInfo *FFI = MF.getFrameInfo();
+ unsigned CFSize = FFI->getMaxCallFrameSize();
+ // It's not always a good idea to include the call frame as part of the
+ // stack frame. ARM (especially Thumb) has small immediate offset to
+ // address the stack frame. So a large call frame can cause poor codegen
+ // and may even makes it impossible to scavenge a register.
+ if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
+ return false;
+
+ return !MF.getFrameInfo()->hasVarSizedObjects();
+}
+
+// canSimplifyCallFramePseudos - If there is a reserved call frame, the
+// call frame pseudos can be simplified. Unlike most targets, having a FP
+// is not sufficient here since we still may reference some objects via SP
+// even when FP is available in Thumb2 mode.
+bool ARMFrameInfo::canSimplifyCallFramePseudos(const MachineFunction &MF)const {
+ return hasReservedCallFrame(MF) || MF.getFrameInfo()->hasVarSizedObjects();
+}
+
static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
for (unsigned i = 0; CSRegs[i]; ++i)
if (Reg == CSRegs[i])
@@ -136,7 +182,7 @@ void ARMFrameInfo::emitPrologue(MachineFunction &MF) const {
// Otherwise, if this is not Darwin, all the callee-saved registers go
// into spill area 1, including the FP in R11. In either case, it is
// now safe to emit this assignment.
- bool HasFP = RegInfo->hasFP(MF);
+ bool HasFP = hasFP(MF);
if (HasFP) {
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
MachineInstrBuilder MIB =
@@ -170,7 +216,7 @@ void ARMFrameInfo::emitPrologue(MachineFunction &MF) const {
AFI->setShouldRestoreSPFromFP(true);
}
- if (STI.isTargetELF() && RegInfo->hasFP(MF)) {
+ if (STI.isTargetELF() && hasFP(MF)) {
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
AFI->getFramePtrSpillOffset());
AFI->setShouldRestoreSPFromFP(true);