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