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