aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMRegisterInfo.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-05-01 00:52:08 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-05-01 00:52:08 +0000
commit5c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5 (patch)
tree3d6f77d6123b4da9f1796dc57be8fcd9c9c89f20 /lib/Target/ARM/ARMRegisterInfo.cpp
parent14f1dd120fc13200697560680999c0efe7ecd714 (diff)
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. However, this is not always a good idea. If the "call frame" is large and the target load / store instructions have small immediate field to encode sp offset, this can cause poor codegen. In the worst case, this can make it impossible to scavenge a register if the reserved spill slot is pushed too far apart from sp / fp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36607 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMRegisterInfo.cpp')
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.cpp30
1 files changed, 27 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp
index 2fdbe68149..bfb8266458 100644
--- a/lib/Target/ARM/ARMRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMRegisterInfo.cpp
@@ -386,6 +386,29 @@ bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const {
return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
}
+// 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 ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
+ const MachineFrameInfo *FFI = MF.getFrameInfo();
+ unsigned CFSize = FFI->getMaxCallFrameSize();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ // 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 (AFI->isThumbFunction()) {
+ if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
+ return false;
+ } else {
+ if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
+ return false;
+ }
+ return !hasFP(MF);
+}
+
/// emitARMRegPlusImmediate - Emits a series of instructions to materialize
/// a destreg = basereg + immediate in ARM code.
static
@@ -605,7 +628,7 @@ void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
void ARMRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
- if (hasFP(MF)) {
+ if (!hasReservedCallFrame(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
@@ -1146,8 +1169,9 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
Limit = (1 << 8) - 1;
goto DoneEstimating;
} else if (AddrMode == ARMII::AddrMode5) {
- Limit = ((1 << 8) - 1) * 4;
- goto DoneEstimating;
+ unsigned ThisLimit = ((1 << 8) - 1) * 4;
+ if (ThisLimit < Limit)
+ Limit = ThisLimit;
}
}
}