diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-01-30 01:18:38 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-01-30 01:18:38 +0000 |
commit | d1b2c1e88fe4a7728ca9739b0f1c6fd90a19c5fd (patch) | |
tree | a06f37be3684c1db7e3e3182bf132703a45bc1b2 /lib/Target/ARM/ARMRegisterInfo.cpp | |
parent | 225dfe973bd85e36ff16fe7a08e458f285703cc9 (diff) |
- In thumb mode, if size of MachineFunction is >= 2048, force LR to be
spilled (if it is not already).
- If LR is spilled, use BL to implement far jumps. LR is not used as a GPR
in thumb mode so it can be clobbered if it is properly spilled / restored
in prologue / epilogue.
- If LR is force spilled but no far jump has been emitted, try undo'ing the
spill by:
push lr -> delete
pop pc -> bx lr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33650 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMRegisterInfo.cpp')
-rw-r--r-- | lib/Target/ARM/ARMRegisterInfo.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index 2accaf890e..07869e4cf8 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -770,17 +770,29 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const { } ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); + bool ForceLRSpill = false; + if (!LRSpilled && AFI->isThumbFunction()) { + unsigned FnSize = ARM::GetFunctionSize(MF); + // Force LR spill if the Thumb function size is > 2048. This enables the + // use of BL to implement far jump. If it turns out that it's not needed + // the branch fix up path will undo it. + if (FnSize >= (1 << 11)) { + CanEliminateFrame = false; + ForceLRSpill = true; + } + } + if (!CanEliminateFrame) { AFI->setHasStackFrame(true); // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled. // Spill LR as well so we can fold BX_RET to the registers restore (LDM). if (!LRSpilled && CS1Spilled) { - LRSpilled = true; MF.changePhyRegUsed(ARM::LR, true); NumGPRSpills++; UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), UnspilledCS1GPRs.end(), (unsigned)ARM::LR)); + ForceLRSpill = false; } if (STI.isTargetDarwin()) { @@ -800,8 +812,10 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const { } } - // Remembe if LR has been spilled. - AFI->setLRIsSpilled(LRSpilled); + if (ForceLRSpill) { + MF.changePhyRegUsed(ARM::LR, true); + AFI->setLRIsForceSpilled(true); + } } /// Move iterator pass the next bunch of callee save load / store ops for |