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