1 //===- LazyBranchProbabilityInfo.h - Lazy Branch Probability ----*- C++ -*-===// 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 is an alternative analysis pass to BranchProbabilityInfoWrapperPass. 10 // The difference is that with this pass the branch probabilities are not 11 // computed when the analysis pass is executed but rather when the BPI results 12 // is explicitly requested by the analysis client. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_ANALYSIS_LAZYBRANCHPROBABILITYINFO_H 17 #define LLVM_ANALYSIS_LAZYBRANCHPROBABILITYINFO_H 18 19 #include "llvm/Analysis/BranchProbabilityInfo.h" 20 #include "llvm/Pass.h" 21 22 namespace llvm { 23 class AnalysisUsage; 24 class Function; 25 class LoopInfo; 26 class TargetLibraryInfo; 27 28 /// This is an alternative analysis pass to 29 /// BranchProbabilityInfoWrapperPass. The difference is that with this pass the 30 /// branch probabilities are not computed when the analysis pass is executed but 31 /// rather when the BPI results is explicitly requested by the analysis client. 32 /// 33 /// There are some additional requirements for any client pass that wants to use 34 /// the analysis: 35 /// 36 /// 1. The pass needs to initialize dependent passes with: 37 /// 38 /// INITIALIZE_PASS_DEPENDENCY(LazyBPIPass) 39 /// 40 /// 2. Similarly, getAnalysisUsage should call: 41 /// 42 /// LazyBranchProbabilityInfoPass::getLazyBPIAnalysisUsage(AU) 43 /// 44 /// 3. The computed BPI should be requested with 45 /// getAnalysis<LazyBranchProbabilityInfoPass>().getBPI() before LoopInfo 46 /// could be invalidated for example by changing the CFG. 47 /// 48 /// Note that it is expected that we wouldn't need this functionality for the 49 /// new PM since with the new PM, analyses are executed on demand. 50 class LazyBranchProbabilityInfoPass : public FunctionPass { 51 52 /// Wraps a BPI to allow lazy computation of the branch probabilities. 53 /// 54 /// A pass that only conditionally uses BPI can uncondtionally require the 55 /// analysis without paying for the overhead if BPI doesn't end up being used. 56 class LazyBranchProbabilityInfo { 57 public: LazyBranchProbabilityInfo(const Function * F,const LoopInfo * LI,const TargetLibraryInfo * TLI)58 LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI, 59 const TargetLibraryInfo *TLI) 60 : F(F), LI(LI), TLI(TLI) {} 61 62 /// Retrieve the BPI with the branch probabilities computed. getCalculated()63 BranchProbabilityInfo &getCalculated() { 64 if (!Calculated) { 65 assert(F && LI && "call setAnalysis"); 66 BPI.calculate(*F, *LI, TLI, nullptr, nullptr); 67 Calculated = true; 68 } 69 return BPI; 70 } 71 getCalculated()72 const BranchProbabilityInfo &getCalculated() const { 73 return const_cast<LazyBranchProbabilityInfo *>(this)->getCalculated(); 74 } 75 76 private: 77 BranchProbabilityInfo BPI; 78 bool Calculated = false; 79 const Function *F; 80 const LoopInfo *LI; 81 const TargetLibraryInfo *TLI; 82 }; 83 84 std::unique_ptr<LazyBranchProbabilityInfo> LBPI; 85 86 public: 87 static char ID; 88 89 LazyBranchProbabilityInfoPass(); 90 91 /// Compute and return the branch probabilities. getBPI()92 BranchProbabilityInfo &getBPI() { return LBPI->getCalculated(); } 93 94 /// Compute and return the branch probabilities. getBPI()95 const BranchProbabilityInfo &getBPI() const { return LBPI->getCalculated(); } 96 97 void getAnalysisUsage(AnalysisUsage &AU) const override; 98 99 /// Helper for client passes to set up the analysis usage on behalf of this 100 /// pass. 101 static void getLazyBPIAnalysisUsage(AnalysisUsage &AU); 102 103 bool runOnFunction(Function &F) override; 104 void releaseMemory() override; 105 void print(raw_ostream &OS, const Module *M) const override; 106 }; 107 108 /// Helper for client passes to initialize dependent passes for LBPI. 109 void initializeLazyBPIPassPass(PassRegistry &Registry); 110 111 /// Simple trait class that provides a mapping between BPI passes and the 112 /// corresponding BPInfo. 113 template <typename PassT> struct BPIPassTrait { getBPIBPIPassTrait114 static PassT &getBPI(PassT *P) { return *P; } 115 }; 116 117 template <> struct BPIPassTrait<LazyBranchProbabilityInfoPass> { 118 static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) { 119 return P->getBPI(); 120 } 121 }; 122 } 123 #endif 124