diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-05-01 00:52:08 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-05-01 00:52:08 +0000 |
commit | 5c3885ce8e6a3dc69913b50fe6bdc0c89c5432d5 (patch) | |
tree | 3d6f77d6123b4da9f1796dc57be8fcd9c9c89f20 /lib/Target/ARM/ARMRegisterInfo.cpp | |
parent | 14f1dd120fc13200697560680999c0efe7ecd714 (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.cpp | 30 |
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; } } } |