diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMMachineFunctionInfo.h | 7 |
3 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index 429c2a582bb..382dc44ad03 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1647,6 +1647,9 @@ ARMConstantIslands::fixupUnconditionalBr(ImmBranch &Br) { if (!isThumb1) llvm_unreachable("fixupUnconditionalBr is Thumb1 only!"); + if (!AFI->isLRSpilled()) + report_fatal_error("underestimated function size"); + // Use BL to implement far jump. Br.MaxDisp = (1 << 21) * 2; MI->setDesc(TII->get(ARM::tBfar)); diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index cee6f867526..0e5740f55ea 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -29,6 +29,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -1475,13 +1476,17 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, } // FIXME: Make generic? -static unsigned GetFunctionSizeInBytes(const MachineFunction &MF, - const ARMBaseInstrInfo &TII) { +static unsigned EstimateFunctionSizeInBytes(const MachineFunction &MF, + const ARMBaseInstrInfo &TII) { unsigned FnSize = 0; for (auto &MBB : MF) { for (auto &MI : MBB) FnSize += TII.getInstSizeInBytes(MI); } + if (MF.getJumpTableInfo()) + for (auto &Table: MF.getJumpTableInfo()->getJumpTables()) + FnSize += Table.MBBs.size() * 4; + FnSize += MF.getConstantPool()->getConstants().size() * 4; return FnSize; } @@ -1725,7 +1730,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, bool ForceLRSpill = false; if (!LRSpilled && AFI->isThumb1OnlyFunction()) { - unsigned FnSize = GetFunctionSizeInBytes(MF, TII); + unsigned FnSize = EstimateFunctionSizeInBytes(MF, TII); // Force LR to be spilled if the Thumb function size is > 2048. This enables // use of BL to implement far jump. If it turns out that it's not needed // then the branch fix up path will undo it. @@ -2027,6 +2032,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, SavedRegs.set(ARM::LR); AFI->setLRIsSpilledForFarJump(true); } + AFI->setLRIsSpilled(SavedRegs.test(ARM::LR)); } MachineBasicBlock::iterator ARMFrameLowering::eliminateCallFramePseudoInstr( diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h index cad6e8e3825..f96124e10f3 100644 --- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h +++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -61,6 +61,10 @@ class ARMFunctionInfo : public MachineFunctionInfo { /// enable far jump. bool LRSpilledForFarJump = false; + /// LRSpilled - True if the LR register has been for spilled for + /// any reason, so it's legal to emit an ARM::tBfar (i.e. "bl"). + bool LRSpilled = false; + /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer /// spill stack offset. unsigned FramePtrSpillOffset = 0; @@ -150,6 +154,9 @@ public: bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; } void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; } + bool isLRSpilled() const { return LRSpilled; } + void setLRIsSpilled(bool s) { LRSpilled = s; } + bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; } void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; } |