diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-07-25 14:42:11 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-07-25 14:42:11 +0000 |
commit | 080bebd212869135dbae80bb721f38f4eefeee12 (patch) | |
tree | 9e88abc432d7db3a9fdf80ad82129ea80b55161b /llvm/lib/Target/Hexagon | |
parent | 8031238017a5aa0294168ecec4ef90fc1b3b76b4 (diff) | |
download | bcm5719-llvm-080bebd212869135dbae80bb721f38f4eefeee12.tar.gz bcm5719-llvm-080bebd212869135dbae80bb721f38f4eefeee12.zip |
[Hexagon] Add target feature to generate long calls
llvm-svn: 276638
Diffstat (limited to 'llvm/lib/Target/Hexagon')
-rw-r--r-- | llvm/lib/Target/Hexagon/Hexagon.td | 17 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 62 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSubtarget.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSubtarget.h | 2 |
6 files changed, 73 insertions, 29 deletions
diff --git a/llvm/lib/Target/Hexagon/Hexagon.td b/llvm/lib/Target/Hexagon/Hexagon.td index aaa0f3e9b3d..f6a2e4f1f82 100644 --- a/llvm/lib/Target/Hexagon/Hexagon.td +++ b/llvm/lib/Target/Hexagon/Hexagon.td @@ -27,11 +27,12 @@ def ArchV5: SubtargetFeature<"v5", "HexagonArchVersion", "V5", "Hexagon V5">; def ArchV55: SubtargetFeature<"v55", "HexagonArchVersion", "V55", "Hexagon V55">; def ArchV60: SubtargetFeature<"v60", "HexagonArchVersion", "V60", "Hexagon V60">; -// Hexagon ISA Extensions -def ExtensionHVX: SubtargetFeature<"hvx", "UseHVXOps", - "true", "Hexagon HVX instructions">; -def ExtensionHVXDbl: SubtargetFeature<"hvx-double", "UseHVXDblOps", - "true", "Hexagon HVX Double instructions">; +def FeatureHVX: SubtargetFeature<"hvx", "UseHVXOps", "true", + "Hexagon HVX instructions">; +def FeatureHVXDbl: SubtargetFeature<"hvx-double", "UseHVXDblOps", "true", + "Hexagon HVX Double instructions">; +def FeatureLongCalls: SubtargetFeature<"long-calls", "UseLongCalls", "true", + "Use constant-extended calls">; //===----------------------------------------------------------------------===// // Hexagon Instruction Predicate Definitions. @@ -45,10 +46,10 @@ def HasV60T : Predicate<"HST->hasV60TOps()">, def UseMEMOP : Predicate<"HST->useMemOps()">; def IEEERndNearV5T : Predicate<"HST->modeIEEERndNear()">; def UseHVXDbl : Predicate<"HST->useHVXDblOps()">, - AssemblerPredicate<"ExtensionHVXDbl">; + AssemblerPredicate<"FeatureHVXDbl">; def UseHVXSgl : Predicate<"HST->useHVXSglOps()">; def UseHVX : Predicate<"HST->useHVXSglOps() ||HST->useHVXDblOps()">, - AssemblerPredicate<"ExtensionHVX">; + AssemblerPredicate<"FeatureHVX">; //===----------------------------------------------------------------------===// // Classes used for relation maps. @@ -269,7 +270,7 @@ def : Proc<"hexagonv5", HexagonModelV4, def : Proc<"hexagonv55", HexagonModelV55, [ArchV4, ArchV5, ArchV55]>; def : Proc<"hexagonv60", HexagonModelV60, - [ArchV4, ArchV5, ArchV55, ArchV60, ExtensionHVX]>; + [ArchV4, ArchV5, ArchV55, ArchV60, FeatureHVX]>; //===----------------------------------------------------------------------===// // Declare the target which we are implementing 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); diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index cdd4c2f8617..2362ef8048f 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -842,14 +842,17 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, InFlag = SDValue(); } + bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls(); + unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0; + // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, PtrVT); + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, PtrVT, 0, Flags); } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { - Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT); + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, Flags); } // Returns a chain & a flag for retval copy to use. diff --git a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp index 00dfed75499..10730536080 100644 --- a/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp @@ -44,14 +44,17 @@ SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy( const char *SpecialMemcpyName = "__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes"; + const MachineFunction &MF = DAG.getMachineFunction(); + bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls(); + unsigned Flags = LongCalls ? HexagonII::HMOTF_ConstExtended : 0; TargetLowering::CallLoweringInfo CLI(DAG); CLI.setDebugLoc(dl) .setChain(Chain) .setCallee(TLI.getLibcallCallingConv(RTLIB::MEMCPY), Type::getVoidTy(*DAG.getContext()), - DAG.getTargetExternalSymbol( - SpecialMemcpyName, TLI.getPointerTy(DAG.getDataLayout())), + DAG.getTargetExternalSymbol(SpecialMemcpyName, + TLI.getPointerTy(DAG.getDataLayout()), Flags), std::move(Args)) .setDiscardResult(); diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index 73d3bd13d9f..2771142bac6 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -69,6 +69,10 @@ static cl::opt<bool> EnableSubregLiveness("hexagon-subreg-liveness", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Enable subregister liveness tracking for Hexagon")); +static cl::opt<bool> OverrideLongCalls("hexagon-long-calls", + cl::Hidden, cl::ZeroOrMore, cl::init(false), + cl::desc("If present, forces/disables the use of long calls")); + void HexagonSubtarget::initializeEnvironment() { UseMemOps = false; ModeIEEERndNear = false; @@ -94,12 +98,15 @@ HexagonSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) { UseHVXOps = false; UseHVXDblOps = false; + UseLongCalls = false; ParseSubtargetFeatures(CPUString, FS); if (EnableHexagonHVX.getPosition()) UseHVXOps = EnableHexagonHVX; if (EnableHexagonHVXDouble.getPosition()) UseHVXDblOps = EnableHexagonHVXDouble; + if (OverrideLongCalls.getPosition()) + UseLongCalls = OverrideLongCalls; return *this; } diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/llvm/lib/Target/Hexagon/HexagonSubtarget.h index 77d096608d4..56939cf2ddd 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -34,6 +34,7 @@ class HexagonSubtarget : public HexagonGenSubtargetInfo { virtual void anchor(); bool UseMemOps, UseHVXOps, UseHVXDblOps; + bool UseLongCalls; bool ModeIEEERndNear; public: @@ -101,6 +102,7 @@ public: bool useHVXOps() const { return UseHVXOps; } bool useHVXDblOps() const { return UseHVXOps && UseHVXDblOps; } bool useHVXSglOps() const { return UseHVXOps && !UseHVXDblOps; } + bool useLongCalls() const { return UseLongCalls; } bool useBSBScheduling() const { return UseBSBScheduling; } bool enableMachineScheduler() const override; |