summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp62
1 files changed, 45 insertions, 17 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 25402147bf5..43ff10b98cb 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -149,6 +149,10 @@ static cl::opt<unsigned> ShrinkLimit("shrink-frame-limit", cl::init(UINT_MAX),
cl::Hidden, cl::ZeroOrMore, cl::desc("Max count of stack frame "
"shrink-wraps"));
+static cl::opt<bool> EnableSaveRestoreLong("enable-save-restore-long",
+ cl::Hidden, cl::desc("Enable long calls for save-restore stubs."),
+ cl::init(false), cl::ZeroOrMore);
+
static cl::opt<bool> UseAllocframe("use-allocframe", cl::init(true),
cl::Hidden, cl::desc("Use allocframe more conservatively"));
@@ -342,7 +346,7 @@ void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
ShrinkCounter++;
}
- auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget());
+ auto &HST = MF.getSubtarget<HexagonSubtarget>();
auto &HRI = *HST.getRegisterInfo();
MachineDominatorTree MDT;
@@ -440,7 +444,7 @@ void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
/// in one place allows shrink-wrapping of the stack frame.
void HexagonFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
- auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget());
+ auto &HST = MF.getSubtarget<HexagonSubtarget>();
auto &HRI = *HST.getRegisterInfo();
MachineFrameInfo *MFI = MF.getFrameInfo();
@@ -581,7 +585,7 @@ void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
if (!hasFP(MF))
return;
- auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget());
+ auto &HST = MF.getSubtarget<HexagonSubtarget>();
auto &HII = *HST.getInstrInfo();
auto &HRI = *HST.getRegisterInfo();
unsigned SP = HRI.getStackRegister();
@@ -1049,7 +1053,8 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI = MBB.begin();
PrologueStubs = false;
MachineFunction &MF = *MBB.getParent();
- auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
+ auto &HST = MF.getSubtarget<HexagonSubtarget>();
+ auto &HII = *HST.getInstrInfo();
if (useSpillFunction(MF, CSI)) {
PrologueStubs = true;
@@ -1059,20 +1064,31 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
StkOvrFlowEnabled);
auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
bool IsPIC = HTM.isPositionIndependent();
+ bool LongCalls = HST.useLongCalls() || EnableSaveRestoreLong;
// Call spill function.
DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc();
unsigned SpillOpc;
- if (StkOvrFlowEnabled)
- SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
- : Hexagon::SAVE_REGISTERS_CALL_V4STK;
- else
- SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
- : Hexagon::SAVE_REGISTERS_CALL_V4;
+ if (StkOvrFlowEnabled) {
+ if (LongCalls)
+ SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
+ else
+ SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4STK;
+ } else {
+ if (LongCalls)
+ SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
+ else
+ SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4;
+ }
MachineInstr *SaveRegsCall =
BuildMI(MBB, MI, DL, HII.get(SpillOpc))
.addExternalSymbol(SpillFun);
+
// Add callee-saved registers as use.
addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI, false, true);
// Add live in registers.
@@ -1104,7 +1120,8 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI = MBB.getFirstTerminator();
MachineFunction &MF = *MBB.getParent();
- auto &HII = *MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
+ auto &HST = MF.getSubtarget<HexagonSubtarget>();
+ auto &HII = *HST.getInstrInfo();
if (useRestoreFunction(MF, CSI)) {
bool HasTC = hasTailCall(MBB) || !hasReturn(MBB);
@@ -1113,6 +1130,7 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
const char *RestoreFn = getSpillFunctionFor(MaxR, Kind);
auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
bool IsPIC = HTM.isPositionIndependent();
+ bool LongCalls = HST.useLongCalls() || EnableSaveRestoreLong;
// Call spill function.
DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc()
@@ -1120,17 +1138,27 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
MachineInstr *DeallocCall = nullptr;
if (HasTC) {
- unsigned ROpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
- : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
- DeallocCall = BuildMI(MBB, MI, DL, HII.get(ROpc))
+ unsigned RetOpc;
+ if (LongCalls)
+ RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
+ : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
+ else
+ RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
+ : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
+ DeallocCall = BuildMI(MBB, MI, DL, HII.get(RetOpc))
.addExternalSymbol(RestoreFn);
} else {
// The block has a return.
MachineBasicBlock::iterator It = MBB.getFirstTerminator();
assert(It->isReturn() && std::next(It) == MBB.end());
- unsigned ROpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
- : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
- DeallocCall = BuildMI(MBB, It, DL, HII.get(ROpc))
+ unsigned RetOpc;
+ if (LongCalls)
+ RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
+ : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
+ else
+ RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
+ : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
+ DeallocCall = BuildMI(MBB, It, DL, HII.get(RetOpc))
.addExternalSymbol(RestoreFn);
// Transfer the function live-out registers.
DeallocCall->copyImplicitOps(MF, *It);
OpenPOWER on IntegriCloud