117a519f9SDimitry Andric //===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===//
217a519f9SDimitry Andric //
317a519f9SDimitry Andric //                     The LLVM Compiler Infrastructure
417a519f9SDimitry Andric //
517a519f9SDimitry Andric // This file is distributed under the University of Illinois Open Source
617a519f9SDimitry Andric // License. See LICENSE.TXT for details.
717a519f9SDimitry Andric //
817a519f9SDimitry Andric //===----------------------------------------------------------------------===//
917a519f9SDimitry Andric //
1017a519f9SDimitry Andric // This analysis uses probability info stored in Machine Basic Blocks.
1117a519f9SDimitry Andric //
1217a519f9SDimitry Andric //===----------------------------------------------------------------------===//
1317a519f9SDimitry Andric 
1417a519f9SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
1517a519f9SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
16139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h"
1717a519f9SDimitry Andric #include "llvm/Support/Debug.h"
1817a519f9SDimitry Andric #include "llvm/Support/raw_ostream.h"
1917a519f9SDimitry Andric 
2017a519f9SDimitry Andric using namespace llvm;
2117a519f9SDimitry Andric 
2217a519f9SDimitry Andric INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfo, "machine-branch-prob",
2317a519f9SDimitry Andric                       "Machine Branch Probability Analysis", false, true)
2417a519f9SDimitry Andric INITIALIZE_PASS_END(MachineBranchProbabilityInfo, "machine-branch-prob",
2517a519f9SDimitry Andric                     "Machine Branch Probability Analysis", false, true)
2617a519f9SDimitry Andric 
273ca95b02SDimitry Andric cl::opt<unsigned>
283ca95b02SDimitry Andric     StaticLikelyProb("static-likely-prob",
293ca95b02SDimitry Andric                      cl::desc("branch probability threshold in percentage"
303ca95b02SDimitry Andric                               "to be considered very likely"),
313ca95b02SDimitry Andric                      cl::init(80), cl::Hidden);
323ca95b02SDimitry Andric 
333ca95b02SDimitry Andric cl::opt<unsigned> ProfileLikelyProb(
343ca95b02SDimitry Andric     "profile-likely-prob",
353ca95b02SDimitry Andric     cl::desc("branch probability threshold in percentage to be considered"
363ca95b02SDimitry Andric              " very likely when profile is available"),
373ca95b02SDimitry Andric     cl::init(51), cl::Hidden);
383ca95b02SDimitry Andric 
3917a519f9SDimitry Andric char MachineBranchProbabilityInfo::ID = 0;
4017a519f9SDimitry Andric 
anchor()41dff0c46cSDimitry Andric void MachineBranchProbabilityInfo::anchor() {}
4217a519f9SDimitry Andric 
getEdgeProbability(const MachineBasicBlock * Src,MachineBasicBlock::const_succ_iterator Dst) const437d523365SDimitry Andric BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
447d523365SDimitry Andric     const MachineBasicBlock *Src,
453861d79fSDimitry Andric     MachineBasicBlock::const_succ_iterator Dst) const {
467d523365SDimitry Andric   return Src->getSuccProbability(Dst);
4717a519f9SDimitry Andric }
4817a519f9SDimitry Andric 
getEdgeProbability(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const497d523365SDimitry Andric BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
507d523365SDimitry Andric     const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
513861d79fSDimitry Andric   // This is a linear search. Try to use the const_succ_iterator version when
523861d79fSDimitry Andric   // possible.
53d88c1a5aSDimitry Andric   return getEdgeProbability(Src, find(Src->successors(), Dst));
543861d79fSDimitry Andric }
553861d79fSDimitry Andric 
isEdgeHot(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const563ca95b02SDimitry Andric bool MachineBranchProbabilityInfo::isEdgeHot(
573ca95b02SDimitry Andric     const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
583ca95b02SDimitry Andric   BranchProbability HotProb(StaticLikelyProb, 100);
597d523365SDimitry Andric   return getEdgeProbability(Src, Dst) > HotProb;
6017a519f9SDimitry Andric }
6117a519f9SDimitry Andric 
6217a519f9SDimitry Andric MachineBasicBlock *
getHotSucc(MachineBasicBlock * MBB) const6317a519f9SDimitry Andric MachineBranchProbabilityInfo::getHotSucc(MachineBasicBlock *MBB) const {
647d523365SDimitry Andric   auto MaxProb = BranchProbability::getZero();
6591bc56edSDimitry Andric   MachineBasicBlock *MaxSucc = nullptr;
6617a519f9SDimitry Andric   for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
6717a519f9SDimitry Andric        E = MBB->succ_end(); I != E; ++I) {
687d523365SDimitry Andric     auto Prob = getEdgeProbability(MBB, I);
697d523365SDimitry Andric     if (Prob > MaxProb) {
707d523365SDimitry Andric       MaxProb = Prob;
71dff0c46cSDimitry Andric       MaxSucc = *I;
7217a519f9SDimitry Andric     }
7317a519f9SDimitry Andric   }
7417a519f9SDimitry Andric 
753ca95b02SDimitry Andric   BranchProbability HotProb(StaticLikelyProb, 100);
767d523365SDimitry Andric   if (getEdgeProbability(MBB, MaxSucc) >= HotProb)
7717a519f9SDimitry Andric     return MaxSucc;
7817a519f9SDimitry Andric 
7991bc56edSDimitry Andric   return nullptr;
8017a519f9SDimitry Andric }
8117a519f9SDimitry Andric 
printEdgeProbability(raw_ostream & OS,const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const8291bc56edSDimitry Andric raw_ostream &MachineBranchProbabilityInfo::printEdgeProbability(
8391bc56edSDimitry Andric     raw_ostream &OS, const MachineBasicBlock *Src,
8491bc56edSDimitry Andric     const MachineBasicBlock *Dst) const {
8517a519f9SDimitry Andric 
8617a519f9SDimitry Andric   const BranchProbability Prob = getEdgeProbability(Src, Dst);
87*2cab237bSDimitry Andric   OS << "edge " << printMBBReference(*Src) << " -> " << printMBBReference(*Dst)
8817a519f9SDimitry Andric      << " probability is " << Prob
8917a519f9SDimitry Andric      << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
9017a519f9SDimitry Andric 
9117a519f9SDimitry Andric   return OS;
9217a519f9SDimitry Andric }
93