1//===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This analysis uses probability info stored in Machine Basic Blocks.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
14#include "llvm/CodeGen/MachineBasicBlock.h"
15#include "llvm/InitializePasses.h"
16#include "llvm/Support/CommandLine.h"
17#include "llvm/Support/raw_ostream.h"
18
19using namespace llvm;
20
21INITIALIZE_PASS(MachineBranchProbabilityInfoWrapperPass, "machine-branch-prob",
22 "Machine Branch Probability Analysis", false, true)
23namespace llvm {
24cl::opt<unsigned>
25 StaticLikelyProb("static-likely-prob",
26 cl::desc("branch probability threshold in percentage"
27 " to be considered very likely"),
28 cl::init(Val: 80), cl::Hidden);
29
30cl::opt<unsigned> ProfileLikelyProb(
31 "profile-likely-prob",
32 cl::desc("branch probability threshold in percentage to be considered"
33 " very likely when profile is available"),
34 cl::init(Val: 51), cl::Hidden);
35} // namespace llvm
36
37MachineBranchProbabilityAnalysis::Result
38MachineBranchProbabilityAnalysis::run(MachineFunction &,
39 MachineFunctionAnalysisManager &) {
40 return MachineBranchProbabilityInfo();
41}
42
43PreservedAnalyses
44MachineBranchProbabilityPrinterPass::run(MachineFunction &MF,
45 MachineFunctionAnalysisManager &MFAM) {
46 OS << "Printing analysis 'Machine Branch Probability Analysis' for machine "
47 "function '"
48 << MF.getName() << "':\n";
49 auto &MBPI = MFAM.getResult<MachineBranchProbabilityAnalysis>(IR&: MF);
50 for (const MachineBasicBlock &MBB : MF) {
51 for (const MachineBasicBlock *Succ : MBB.successors())
52 MBPI.printEdgeProbability(OS&: OS << " ", Src: &MBB, Dst: Succ);
53 }
54 return PreservedAnalyses::all();
55}
56
57char MachineBranchProbabilityInfoWrapperPass::ID = 0;
58
59MachineBranchProbabilityInfoWrapperPass::
60 MachineBranchProbabilityInfoWrapperPass()
61 : ImmutablePass(ID) {}
62
63void MachineBranchProbabilityInfoWrapperPass::anchor() {}
64
65AnalysisKey MachineBranchProbabilityAnalysis::Key;
66
67bool MachineBranchProbabilityInfo::invalidate(
68 MachineFunction &, const PreservedAnalyses &PA,
69 MachineFunctionAnalysisManager::Invalidator &) {
70 auto PAC = PA.getChecker<MachineBranchProbabilityAnalysis>();
71 return !PAC.preservedWhenStateless();
72}
73
74BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
75 const MachineBasicBlock *Src,
76 MachineBasicBlock::const_succ_iterator Dst) const {
77 return Src->getSuccProbability(Succ: Dst);
78}
79
80BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
81 const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
82 // This is a linear search. Try to use the const_succ_iterator version when
83 // possible.
84 return getEdgeProbability(Src, Dst: find(Range: Src->successors(), Val: Dst));
85}
86
87bool MachineBranchProbabilityInfo::isEdgeHot(
88 const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
89 BranchProbability HotProb(StaticLikelyProb, 100);
90 return getEdgeProbability(Src, Dst) > HotProb;
91}
92
93raw_ostream &MachineBranchProbabilityInfo::printEdgeProbability(
94 raw_ostream &OS, const MachineBasicBlock *Src,
95 const MachineBasicBlock *Dst) const {
96
97 const BranchProbability Prob = getEdgeProbability(Src, Dst);
98 OS << "edge " << printMBBReference(MBB: *Src) << " -> " << printMBBReference(MBB: *Dst)
99 << " probability is " << Prob
100 << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
101
102 return OS;
103}
104