diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index 445dbaa1cef..e0beab078f1 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -2472,6 +2472,34 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const { return (ImmValue < MinValue || ImmValue > MaxValue); } +// Returns the opcode to use when converting MI, which is a conditional jump, +// into a conditional instruction which uses the .new value of the predicate. +// We also use branch probabilities to add a hint to the jump. +int +HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI, + const + MachineBranchProbabilityInfo *MBPI) const { + + // We assume that block can have at most two successors. + bool taken = false; + MachineBasicBlock *Src = MI->getParent(); + MachineOperand *BrTarget = &MI->getOperand(1); + MachineBasicBlock *Dst = BrTarget->getMBB(); + + const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst); + if (Prediction >= BranchProbability(1,2)) + taken = true; + + switch (MI->getOpcode()) { + case Hexagon::JMP_t: + return taken ? Hexagon::JMP_tnew_t : Hexagon::JMP_tnew_nt; + case Hexagon::JMP_f: + return taken ? Hexagon::JMP_fnew_t : Hexagon::JMP_fnew_nt; + + default: + llvm_unreachable("Unexpected jump instruction."); + } +} // Returns true if a particular operand is extendable for an instruction. bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI, unsigned short OperandNum) const { diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h index 03a8a77a33a..e0bec04e64f 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/lib/Target/Hexagon/HexagonInstrInfo.h @@ -18,8 +18,7 @@ #include "MCTargetDesc/HexagonBaseInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetInstrInfo.h" - +#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #define GET_INSTRINFO_HEADER #include "HexagonGenInstrInfo.inc" @@ -192,6 +191,8 @@ public: void immediateExtend(MachineInstr *MI) const; bool isConstExtended(MachineInstr *MI) const; + int getDotNewPredJumpOp(MachineInstr *MI, + const MachineBranchProbabilityInfo *MBPI) const; unsigned getAddrMode(const MachineInstr* MI) const; bool isOperandExtended(const MachineInstr *MI, unsigned short OperandNum) const; diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp index 723edbc1dd5..72af87659e1 100644 --- a/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp @@ -68,6 +68,7 @@ namespace { HexagonNewValueJump() : MachineFunctionPass(ID) { } virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -78,6 +79,8 @@ namespace { virtual bool runOnMachineFunction(MachineFunction &Fn); private: + /// \brief A handle to the branch probability pass. + const MachineBranchProbabilityInfo *MBPI; }; @@ -267,42 +270,58 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, // Given a compare operator, return a matching New Value Jump // compare operator. Make sure that MI here is included in // HexagonInstrInfo.cpp::isNewValueJumpCandidate -static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg, - bool secondRegNewified) { +static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, + bool secondRegNewified, + MachineBasicBlock *jmpTarget, + const MachineBranchProbabilityInfo + *MBPI) { + bool taken = false; + MachineBasicBlock *Src = MI->getParent(); + const BranchProbability Prediction = + MBPI->getEdgeProbability(Src, jmpTarget); + + if (Prediction >= BranchProbability(1,2)) + taken = true; + switch (MI->getOpcode()) { case Hexagon::CMPEQrr: - return Hexagon::JMP_EQrrPt_nv_V4; + return taken ? Hexagon::JMP_EQrrPt_nv_V4 : Hexagon::JMP_EQrrPnt_nv_V4; case Hexagon::CMPEQri: { if (reg >= 0) - return Hexagon::JMP_EQriPt_nv_V4; + return taken ? Hexagon::JMP_EQriPt_nv_V4 : Hexagon::JMP_EQriPnt_nv_V4; else - return Hexagon::JMP_EQriPtneg_nv_V4; + return taken ? Hexagon::JMP_EQriPtneg_nv_V4 + : Hexagon::JMP_EQriPntneg_nv_V4; } case Hexagon::CMPGTrr: { if (secondRegNewified) - return Hexagon::JMP_GTrrdnPt_nv_V4; + return taken ? Hexagon::JMP_GTrrdnPt_nv_V4 + : Hexagon::JMP_GTrrdnPnt_nv_V4; else - return Hexagon::JMP_GTrrPt_nv_V4; + return taken ? Hexagon::JMP_GTrrPt_nv_V4 + : Hexagon::JMP_GTrrPnt_nv_V4; } case Hexagon::CMPGTri: { if (reg >= 0) - return Hexagon::JMP_GTriPt_nv_V4; + return taken ? Hexagon::JMP_GTriPt_nv_V4 : Hexagon::JMP_GTriPnt_nv_V4; else - return Hexagon::JMP_GTriPtneg_nv_V4; + return taken ? Hexagon::JMP_GTriPtneg_nv_V4 + : Hexagon::JMP_GTriPntneg_nv_V4; } case Hexagon::CMPGTUrr: { if (secondRegNewified) - return Hexagon::JMP_GTUrrdnPt_nv_V4; + return taken ? Hexagon::JMP_GTUrrdnPt_nv_V4 + : Hexagon::JMP_GTUrrdnPnt_nv_V4; else - return Hexagon::JMP_GTUrrPt_nv_V4; + return taken ? Hexagon::JMP_GTUrrPt_nv_V4 : Hexagon::JMP_GTUrrPnt_nv_V4; } case Hexagon::CMPGTUri: - return Hexagon::JMP_GTUriPt_nv_V4; + return taken ? Hexagon::JMP_GTUriPt_nv_V4 : Hexagon::JMP_GTUriPnt_nv_V4; default: llvm_unreachable("Could not find matching New Value Jump instruction."); @@ -326,6 +345,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { QII = static_cast(MF.getTarget().getInstrInfo()); QRI = static_cast(MF.getTarget().getRegisterInfo()); + MBPI = &getAnalysis(); if (!QRI->Subtarget.hasV4TOps() || DisableNewValueJumps) { @@ -560,7 +580,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { assert((QII->isNewValueJumpCandidate(cmpInstr)) && "This compare is not a New Value Jump candidate."); unsigned opc = getNewValueJumpOpcode(cmpInstr, cmpOp2, - isSecondOpNewified); + isSecondOpNewified, + jmpTarget, MBPI); if (invertPredicate) opc = QII->getInvertedPredicatedOpcode(opc); diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index 805a79deaa9..e592df9bdc0 100644 --- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -48,19 +48,35 @@ #include "HexagonMachineFunctionInfo.h" #include +#include using namespace llvm; +static cl::opt PacketizeVolatiles("hexagon-packetize-volatiles", + cl::ZeroOrMore, cl::Hidden, cl::init(true), + cl::desc("Allow non-solo packetization of volatile memory references")); + +extern cl::opt ScheduleInlineAsm; +extern cl::opt CountDeadOutput; + +namespace llvm { + void initializeHexagonPacketizerPass(PassRegistry&); +} + + namespace { class HexagonPacketizer : public MachineFunctionPass { public: static char ID; - HexagonPacketizer() : MachineFunctionPass(ID) {} + HexagonPacketizer() : MachineFunctionPass(ID) { + initializeHexagonPacketizerPass(*PassRegistry::getPassRegistry()); + } void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); + AU.addRequired(); AU.addPreserved(); AU.addRequired(); AU.addPreserved(); @@ -96,10 +112,17 @@ namespace { // schedule this instruction. bool FoundSequentialDependence; + /// \brief A handle to the branch probability pass. + const MachineBranchProbabilityInfo *MBPI; + + // Track MIs with ignored dependece. + std::vector IgnoreDepMIs; + public: // Ctor. HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, - MachineDominatorTree &MDT); + MachineDominatorTree &MDT, + const MachineBranchProbabilityInfo *MBPI); // initPacketizerState - initialize some internal flags. void initPacketizerState(); @@ -123,20 +146,20 @@ namespace { private: bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg); bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType, - MachineBasicBlock::iterator &MII, - const TargetRegisterClass* RC); + MachineBasicBlock::iterator &MII, + const TargetRegisterClass* RC); bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU, - unsigned DepReg, - std::map MIToSUnit, - MachineBasicBlock::iterator &MII, - const TargetRegisterClass* RC); + unsigned DepReg, + std::map MIToSUnit, + MachineBasicBlock::iterator &MII, + const TargetRegisterClass* RC); bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU, - unsigned DepReg, - std::map MIToSUnit, - MachineBasicBlock::iterator &MII); + unsigned DepReg, + std::map MIToSUnit, + MachineBasicBlock::iterator &MII); bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI, - unsigned DepReg, - std::map MIToSUnit); + unsigned DepReg, + std::map MIToSUnit); bool DemoteToDotOld(MachineInstr* MI); bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2, std::map MIToSUnit); @@ -152,19 +175,31 @@ namespace { }; } +INITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer", + false, false) +INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) +INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer", + false, false) + + // HexagonPacketizerList Ctor. HexagonPacketizerList::HexagonPacketizerList( - MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT) + MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT, + const MachineBranchProbabilityInfo *MBPI) : VLIWPacketizerList(MF, MLI, MDT, true){ + this->MBPI = MBPI; } bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) { const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); MachineLoopInfo &MLI = getAnalysis(); MachineDominatorTree &MDT = getAnalysis(); - + const MachineBranchProbabilityInfo *MBPI = + &getAnalysis(); // Instantiate the packetizer. - HexagonPacketizerList Packetizer(Fn, MLI, MDT); + HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI); // DFA state table should not be empty. assert(Packetizer.getResourceTracker() && "Empty DFA table!"); @@ -710,8 +745,10 @@ static int GetDotNewOp(const int opc) { } // Return .new predicate version for an instruction -static int GetDotNewPredOp(const int opc) { - switch (opc) { +static int GetDotNewPredOp(MachineInstr *MI, + const MachineBranchProbabilityInfo *MBPI, + const HexagonInstrInfo *QII) { + switch (MI->getOpcode()) { default: llvm_unreachable("Unknown .new type"); // Conditional stores // Store byte conditionally @@ -858,10 +895,8 @@ static int GetDotNewPredOp(const int opc) { // Condtional Jumps case Hexagon::JMP_t: - return Hexagon::JMP_f; - case Hexagon::JMP_f: - return Hexagon::JMP_fnew_t; + return QII->getDotNewPredJumpOp(MI, MBPI); case Hexagon::JMPR_t: return Hexagon::JMPR_tnew_tV3; @@ -1261,7 +1296,7 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI, int NewOpcode; if (RC == &Hexagon::PredRegsRegClass) - NewOpcode = GetDotNewPredOp(MI->getOpcode()); + NewOpcode = GetDotNewPredOp(MI, MBPI, QII); else NewOpcode = GetDotNewOp(MI->getOpcode()); MI->setDesc(QII->get(NewOpcode));