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 43*0fca6ea1SDimitry Andric MachineBranchProbabilityAnalysis::run(MachineFunction &, 44*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &) { 45*0fca6ea1SDimitry Andric return MachineBranchProbabilityInfo(); 46480093f4SDimitry Andric } 47480093f4SDimitry Andric 48*0fca6ea1SDimitry Andric PreservedAnalyses 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:: 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 71*0fca6ea1SDimitry Andric void MachineBranchProbabilityInfoWrapperPass::anchor() {} 72*0fca6ea1SDimitry Andric 73*0fca6ea1SDimitry Andric AnalysisKey MachineBranchProbabilityAnalysis::Key; 74*0fca6ea1SDimitry Andric 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 820b57cec5SDimitry 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 880b57cec5SDimitry 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 950b57cec5SDimitry 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 1010b57cec5SDimitry 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