10b57cec5SDimitry Andric //===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This analysis uses probability info stored in Machine Basic Blocks.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
15480093f4SDimitry Andric #include "llvm/InitializePasses.h"
16480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
170b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric
21*0fca6ea1SDimitry Andric INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfoWrapperPass,
22*0fca6ea1SDimitry Andric "machine-branch-prob",
230b57cec5SDimitry Andric "Machine Branch Probability Analysis", false, true)
24*0fca6ea1SDimitry Andric INITIALIZE_PASS_END(MachineBranchProbabilityInfoWrapperPass,
25*0fca6ea1SDimitry Andric "machine-branch-prob",
260b57cec5SDimitry Andric "Machine Branch Probability Analysis", false, true)
270b57cec5SDimitry Andric
28fe6060f1SDimitry Andric namespace llvm {
290b57cec5SDimitry Andric cl::opt<unsigned>
300b57cec5SDimitry Andric StaticLikelyProb("static-likely-prob",
310b57cec5SDimitry Andric cl::desc("branch probability threshold in percentage"
320b57cec5SDimitry Andric "to be considered very likely"),
330b57cec5SDimitry Andric cl::init(80), cl::Hidden);
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric cl::opt<unsigned> ProfileLikelyProb(
360b57cec5SDimitry Andric "profile-likely-prob",
370b57cec5SDimitry Andric cl::desc("branch probability threshold in percentage to be considered"
380b57cec5SDimitry Andric " very likely when profile is available"),
390b57cec5SDimitry Andric cl::init(51), cl::Hidden);
40fe6060f1SDimitry Andric } // namespace llvm
410b57cec5SDimitry Andric
42*0fca6ea1SDimitry Andric MachineBranchProbabilityAnalysis::Result
run(MachineFunction &,MachineFunctionAnalysisManager &)43*0fca6ea1SDimitry Andric MachineBranchProbabilityAnalysis::run(MachineFunction &,
44*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &) {
45*0fca6ea1SDimitry Andric return MachineBranchProbabilityInfo();
46480093f4SDimitry Andric }
47480093f4SDimitry Andric
48*0fca6ea1SDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)49*0fca6ea1SDimitry Andric MachineBranchProbabilityPrinterPass::run(MachineFunction &MF,
50*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM) {
51*0fca6ea1SDimitry Andric OS << "Printing analysis 'Machine Branch Probability Analysis' for machine "
52*0fca6ea1SDimitry Andric "function '"
53*0fca6ea1SDimitry Andric << MF.getName() << "':\n";
54*0fca6ea1SDimitry Andric auto &MBPI = MFAM.getResult<MachineBranchProbabilityAnalysis>(MF);
55*0fca6ea1SDimitry Andric for (const MachineBasicBlock &MBB : MF) {
56*0fca6ea1SDimitry Andric for (const MachineBasicBlock *Succ : MBB.successors())
57*0fca6ea1SDimitry Andric MBPI.printEdgeProbability(OS << " ", &MBB, Succ);
58*0fca6ea1SDimitry Andric }
59*0fca6ea1SDimitry Andric return PreservedAnalyses::all();
60*0fca6ea1SDimitry Andric }
61*0fca6ea1SDimitry Andric
62*0fca6ea1SDimitry Andric char MachineBranchProbabilityInfoWrapperPass::ID = 0;
63*0fca6ea1SDimitry Andric
64*0fca6ea1SDimitry Andric MachineBranchProbabilityInfoWrapperPass::
MachineBranchProbabilityInfoWrapperPass()65*0fca6ea1SDimitry Andric MachineBranchProbabilityInfoWrapperPass()
66*0fca6ea1SDimitry Andric : ImmutablePass(ID) {
67*0fca6ea1SDimitry Andric PassRegistry &Registry = *PassRegistry::getPassRegistry();
68*0fca6ea1SDimitry Andric initializeMachineBranchProbabilityInfoWrapperPassPass(Registry);
69*0fca6ea1SDimitry Andric }
70*0fca6ea1SDimitry Andric
anchor()71*0fca6ea1SDimitry Andric void MachineBranchProbabilityInfoWrapperPass::anchor() {}
72*0fca6ea1SDimitry Andric
73*0fca6ea1SDimitry Andric AnalysisKey MachineBranchProbabilityAnalysis::Key;
74*0fca6ea1SDimitry Andric
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)75*0fca6ea1SDimitry Andric bool MachineBranchProbabilityInfo::invalidate(
76*0fca6ea1SDimitry Andric MachineFunction &, const PreservedAnalyses &PA,
77*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
78*0fca6ea1SDimitry Andric auto PAC = PA.getChecker<MachineBranchProbabilityAnalysis>();
79*0fca6ea1SDimitry Andric return !PAC.preservedWhenStateless();
80*0fca6ea1SDimitry Andric }
810b57cec5SDimitry Andric
getEdgeProbability(const MachineBasicBlock * Src,MachineBasicBlock::const_succ_iterator Dst) const820b57cec5SDimitry Andric BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
830b57cec5SDimitry Andric const MachineBasicBlock *Src,
840b57cec5SDimitry Andric MachineBasicBlock::const_succ_iterator Dst) const {
850b57cec5SDimitry Andric return Src->getSuccProbability(Dst);
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric
getEdgeProbability(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const880b57cec5SDimitry Andric BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
890b57cec5SDimitry Andric const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
900b57cec5SDimitry Andric // This is a linear search. Try to use the const_succ_iterator version when
910b57cec5SDimitry Andric // possible.
920b57cec5SDimitry Andric return getEdgeProbability(Src, find(Src->successors(), Dst));
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric
isEdgeHot(const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const950b57cec5SDimitry Andric bool MachineBranchProbabilityInfo::isEdgeHot(
960b57cec5SDimitry Andric const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
970b57cec5SDimitry Andric BranchProbability HotProb(StaticLikelyProb, 100);
980b57cec5SDimitry Andric return getEdgeProbability(Src, Dst) > HotProb;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric
printEdgeProbability(raw_ostream & OS,const MachineBasicBlock * Src,const MachineBasicBlock * Dst) const1010b57cec5SDimitry Andric raw_ostream &MachineBranchProbabilityInfo::printEdgeProbability(
1020b57cec5SDimitry Andric raw_ostream &OS, const MachineBasicBlock *Src,
1030b57cec5SDimitry Andric const MachineBasicBlock *Dst) const {
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andric const BranchProbability Prob = getEdgeProbability(Src, Dst);
1060b57cec5SDimitry Andric OS << "edge " << printMBBReference(*Src) << " -> " << printMBBReference(*Dst)
1070b57cec5SDimitry Andric << " probability is " << Prob
1080b57cec5SDimitry Andric << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric return OS;
1110b57cec5SDimitry Andric }
112