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