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