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