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