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 23namespace llvm { 24class AnalysisUsage; 25class Function; 26class LoopInfo; 27class TargetLibraryInfo; 28 29/// \brief 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. 51class 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: 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. 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 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 87public: 88 static char ID; 89 90 LazyBranchProbabilityInfoPass(); 91 92 /// \brief Compute and return the branch probabilities. 93 BranchProbabilityInfo &getBPI() { return LBPI->getCalculated(); } 94 95 /// \brief Compute and return the branch probabilities. 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/// \brief Helper for client passes to initialize dependent passes for LBPI. 110void initializeLazyBPIPassPass(PassRegistry &Registry); 111 112/// \brief Simple trait class that provides a mapping between BPI passes and the 113/// corresponding BPInfo. 114template <typename PassT> struct BPIPassTrait { 115 static PassT &getBPI(PassT *P) { return *P; } 116}; 117 118template <> struct BPIPassTrait<LazyBranchProbabilityInfoPass> { 119 static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) { 120 return P->getBPI(); 121 } 122}; 123} 124#endif 125