HexagonNewValueJump() : MachineFunctionPass(ID) { }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineBranchProbabilityInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
virtual bool runOnMachineFunction(MachineFunction &Fn);
private:
+ /// \brief A handle to the branch probability pass.
+ const MachineBranchProbabilityInfo *MBPI;
};
// 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.");
QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
QRI =
static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
+ MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
if (!QRI->Subtarget.hasV4TOps() ||
DisableNewValueJumps) {
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);
#include "HexagonMachineFunctionInfo.h"
#include <map>
+#include <vector>
using namespace llvm;
+static cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles",
+ cl::ZeroOrMore, cl::Hidden, cl::init(true),
+ cl::desc("Allow non-solo packetization of volatile memory references"));
+
+extern cl::opt<bool> ScheduleInlineAsm;
+extern cl::opt<bool> 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<MachineDominatorTree>();
+ AU.addRequired<MachineBranchProbabilityInfo>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
// schedule this instruction.
bool FoundSequentialDependence;
+ /// \brief A handle to the branch probability pass.
+ const MachineBranchProbabilityInfo *MBPI;
+
+ // Track MIs with ignored dependece.
+ std::vector<MachineInstr*> IgnoreDepMIs;
+
public:
// Ctor.
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
- MachineDominatorTree &MDT);
+ MachineDominatorTree &MDT,
+ const MachineBranchProbabilityInfo *MBPI);
// initPacketizerState - initialize some internal flags.
void initPacketizerState();
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 <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit,
+ MachineBasicBlock::iterator &MII,
+ const TargetRegisterClass* RC);
bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit,
+ MachineBasicBlock::iterator &MII);
bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit);
bool DemoteToDotOld(MachineInstr* MI);
bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2,
std::map <MachineInstr*, SUnit*> MIToSUnit);
};
}
+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<MachineLoopInfo>();
MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
-
+ const MachineBranchProbabilityInfo *MBPI =
+ &getAnalysis<MachineBranchProbabilityInfo>();
// 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!");
}
// 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
// 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;
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));