1411bd29eSDimitry Andric //===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===//
2411bd29eSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6411bd29eSDimitry Andric //
7411bd29eSDimitry Andric //===----------------------------------------------------------------------===//
8411bd29eSDimitry Andric //
9411bd29eSDimitry Andric // This analysis uses probability info stored in Machine Basic Blocks.
10411bd29eSDimitry Andric //
11411bd29eSDimitry Andric //===----------------------------------------------------------------------===//
12411bd29eSDimitry Andric
13411bd29eSDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
14411bd29eSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
15706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
16706b4fc4SDimitry Andric #include "llvm/Support/CommandLine.h"
17411bd29eSDimitry Andric #include "llvm/Support/raw_ostream.h"
18411bd29eSDimitry Andric
19411bd29eSDimitry Andric using namespace llvm;
20411bd29eSDimitry Andric
21ac9a064cSDimitry Andric INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfoWrapperPass,
22ac9a064cSDimitry Andric "machine-branch-prob",
23411bd29eSDimitry Andric "Machine Branch Probability Analysis", false, true)
24ac9a064cSDimitry Andric INITIALIZE_PASS_END(MachineBranchProbabilityInfoWrapperPass,
25ac9a064cSDimitry Andric "machine-branch-prob",
26411bd29eSDimitry Andric "Machine Branch Probability Analysis", false, true)
27411bd29eSDimitry Andric
28344a3780SDimitry Andric namespace llvm {
2901095a5dSDimitry Andric cl::opt<unsigned>
3001095a5dSDimitry Andric StaticLikelyProb("static-likely-prob",
3101095a5dSDimitry Andric cl::desc("branch probability threshold in percentage"
3201095a5dSDimitry Andric "to be considered very likely"),
3301095a5dSDimitry Andric cl::init(80), cl::Hidden);
3401095a5dSDimitry Andric
3501095a5dSDimitry Andric cl::opt<unsigned> ProfileLikelyProb(
3601095a5dSDimitry Andric "profile-likely-prob",
3701095a5dSDimitry Andric cl::desc("branch probability threshold in percentage to be considered"
3801095a5dSDimitry Andric " very likely when profile is available"),
3901095a5dSDimitry Andric cl::init(51), cl::Hidden);
40344a3780SDimitry Andric } // namespace llvm
4101095a5dSDimitry Andric
42ac9a064cSDimitry Andric MachineBranchProbabilityAnalysis::Result
run(MachineFunction &,MachineFunctionAnalysisManager &)43ac9a064cSDimitry Andric MachineBranchProbabilityAnalysis::run(MachineFunction &,
44ac9a064cSDimitry Andric MachineFunctionAnalysisManager &) {
45ac9a064cSDimitry Andric return MachineBranchProbabilityInfo();
46706b4fc4SDimitry Andric }
47706b4fc4SDimitry Andric
48ac9a064cSDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)49ac9a064cSDimitry Andric MachineBranchProbabilityPrinterPass::run(MachineFunction &MF,
50ac9a064cSDimitry Andric MachineFunctionAnalysisManager &MFAM) {
51ac9a064cSDimitry Andric OS << "Printing analysis 'Machine Branch Probability Analysis' for machine "
52ac9a064cSDimitry Andric "function '"
53ac9a064cSDimitry Andric << MF.getName() << "':\n";
54ac9a064cSDimitry Andric auto &MBPI = MFAM.getResult<MachineBranchProbabilityAnalysis>(MF);
55ac9a064cSDimitry Andric for (const MachineBasicBlock &MBB : MF) {
56ac9a064cSDimitry Andric for (const MachineBasicBlock *Succ : MBB.successors())
57ac9a064cSDimitry Andric MBPI.printEdgeProbability(OS << " ", &MBB, Succ);
58ac9a064cSDimitry Andric }
59ac9a064cSDimitry Andric return PreservedAnalyses::all();
60ac9a064cSDimitry Andric }
61ac9a064cSDimitry Andric
62ac9a064cSDimitry Andric char MachineBranchProbabilityInfoWrapperPass::ID = 0;
63ac9a064cSDimitry Andric
64ac9a064cSDimitry Andric MachineBranchProbabilityInfoWrapperPass::
MachineBranchProbabilityInfoWrapperPass()65ac9a064cSDimitry Andric MachineBranchProbabilityInfoWrapperPass()
66ac9a064cSDimitry Andric : ImmutablePass(ID) {
67ac9a064cSDimitry Andric PassRegistry &Registry = *PassRegistry::getPassRegistry();
68ac9a064cSDimitry Andric initializeMachineBranchProbabilityInfoWrapperPassPass(Registry);
69ac9a064cSDimitry Andric }
70ac9a064cSDimitry Andric
anchor()71ac9a064cSDimitry Andric void MachineBranchProbabilityInfoWrapperPass::anchor() {}
72ac9a064cSDimitry Andric
73ac9a064cSDimitry Andric AnalysisKey MachineBranchProbabilityAnalysis::Key;
74ac9a064cSDimitry Andric
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)75ac9a064cSDimitry Andric bool MachineBranchProbabilityInfo::invalidate(
76ac9a064cSDimitry Andric MachineFunction &, const PreservedAnalyses &PA,
77ac9a064cSDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
78ac9a064cSDimitry Andric auto PAC = PA.getChecker<MachineBranchProbabilityAnalysis>();
79ac9a064cSDimitry Andric return !PAC.preservedWhenStateless();
80ac9a064cSDimitry Andric }
81411bd29eSDimitry Andric
getEdgeProbability(const MachineBasicBlock * Src,MachineBasicBlock::const_succ_iterator Dst) const82dd58ef01SDimitry Andric BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
83dd58ef01SDimitry Andric const MachineBasicBlock *Src,
84522600a2SDimitry Andric MachineBasicBlock::const_succ_iterator Dst) const {
85dd58ef01SDimitry Andric return Src->getSuccProbability(Dst);
86411bd29eSDimitry Andric }
87411bd29eSDimitry Andric
getEdgeProbability(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const88dd58ef01SDimitry Andric BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
89dd58ef01SDimitry Andric const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
90522600a2SDimitry Andric // This is a linear search. Try to use the const_succ_iterator version when
91522600a2SDimitry Andric // possible.
92b915e9e0SDimitry Andric return getEdgeProbability(Src, find(Src->successors(), Dst));
93522600a2SDimitry Andric }
94522600a2SDimitry Andric
isEdgeHot(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const9501095a5dSDimitry Andric bool MachineBranchProbabilityInfo::isEdgeHot(
9601095a5dSDimitry Andric const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
9701095a5dSDimitry Andric BranchProbability HotProb(StaticLikelyProb, 100);
98dd58ef01SDimitry Andric return getEdgeProbability(Src, Dst) > HotProb;
99411bd29eSDimitry Andric }
100411bd29eSDimitry Andric
printEdgeProbability(raw_ostream & OS,const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const1015ca98fd9SDimitry Andric raw_ostream &MachineBranchProbabilityInfo::printEdgeProbability(
1025ca98fd9SDimitry Andric raw_ostream &OS, const MachineBasicBlock *Src,
1035ca98fd9SDimitry Andric const MachineBasicBlock *Dst) const {
104411bd29eSDimitry Andric
105411bd29eSDimitry Andric const BranchProbability Prob = getEdgeProbability(Src, Dst);
106044eb2f6SDimitry Andric OS << "edge " << printMBBReference(*Src) << " -> " << printMBBReference(*Dst)
107411bd29eSDimitry Andric << " probability is " << Prob
108411bd29eSDimitry Andric << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
109411bd29eSDimitry Andric
110411bd29eSDimitry Andric return OS;
111411bd29eSDimitry Andric }
112