1 //===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- 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 BlockFrequencyInfoWrapperPass. The 11 // difference is that with this pass the block frequencies are not computed when 12 // the analysis pass is executed but rather when the BFI results is explicitly 13 // requested by the analysis client. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H 18 #define LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H 19 20 #include "llvm/Analysis/BlockFrequencyInfo.h" 21 #include "llvm/Pass.h" 22 23 namespace llvm { 24 class AnalysisUsage; 25 class BranchProbabilityInfo; 26 class Function; 27 class LoopInfo; 28 29 /// \brief This is an alternative analysis pass to 30 /// BlockFrequencyInfoWrapperPass. The difference is that with this pass the 31 /// block frequencies are not computed when the analysis pass is executed but 32 /// rather when the BFI 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(LazyBFIPass) 40 /// 41 /// 2. Similarly, getAnalysisUsage should call: 42 /// 43 /// LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU) 44 /// 45 /// 3. The computed BFI should be requested with 46 /// getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() before either LoopInfo 47 /// or BPI 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 LazyBlockFrequencyInfoPass : public FunctionPass { 52 53 /// Wraps a BFI to allow lazy computation of the block frequencies. 54 /// 55 /// A pass that only conditionally uses BFI can uncondtionally require the 56 /// analysis without paying for the overhead if BFI doesn't end up being used. 57 class LazyBlockFrequencyInfo { 58 public: LazyBlockFrequencyInfo()59 LazyBlockFrequencyInfo() 60 : Calculated(false), F(nullptr), BPI(nullptr), LI(nullptr) {} 61 62 /// Set up the per-function input. setAnalysis(const Function * F,const BranchProbabilityInfo * BPI,const LoopInfo * LI)63 void setAnalysis(const Function *F, const BranchProbabilityInfo *BPI, 64 const LoopInfo *LI) { 65 this->F = F; 66 this->BPI = BPI; 67 this->LI = LI; 68 } 69 70 /// Retrieve the BFI with the block frequencies computed. getCalculated()71 BlockFrequencyInfo &getCalculated() { 72 if (!Calculated) { 73 assert(F && BPI && LI && "call setAnalysis"); 74 BFI.calculate(*F, *BPI, *LI); 75 Calculated = true; 76 } 77 return BFI; 78 } 79 getCalculated()80 const BlockFrequencyInfo &getCalculated() const { 81 return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated(); 82 } 83 releaseMemory()84 void releaseMemory() { 85 BFI.releaseMemory(); 86 Calculated = false; 87 setAnalysis(nullptr, nullptr, nullptr); 88 } 89 90 private: 91 BlockFrequencyInfo BFI; 92 bool Calculated; 93 const Function *F; 94 const BranchProbabilityInfo *BPI; 95 const LoopInfo *LI; 96 }; 97 98 LazyBlockFrequencyInfo LBFI; 99 100 public: 101 static char ID; 102 103 LazyBlockFrequencyInfoPass(); 104 105 /// \brief Compute and return the block frequencies. getBFI()106 BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); } 107 108 /// \brief Compute and return the block frequencies. getBFI()109 const BlockFrequencyInfo &getBFI() const { return LBFI.getCalculated(); } 110 111 void getAnalysisUsage(AnalysisUsage &AU) const override; 112 113 /// Helper for client passes to set up the analysis usage on behalf of this 114 /// pass. 115 static void getLazyBFIAnalysisUsage(AnalysisUsage &AU); 116 117 bool runOnFunction(Function &F) override; 118 void releaseMemory() override; 119 void print(raw_ostream &OS, const Module *M) const override; 120 }; 121 122 /// \brief Helper for client passes to initialize dependent passes for LBFI. 123 void initializeLazyBFIPassPass(PassRegistry &Registry); 124 } 125 #endif 126