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 23namespace llvm { 24class AnalysisUsage; 25class BranchProbabilityInfo; 26class Function; 27class 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. 51class 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: 59 LazyBlockFrequencyInfo() 60 : Calculated(false), F(nullptr), BPI(nullptr), LI(nullptr) {} 61 62 /// Set up the per-function input. 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. 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 80 const BlockFrequencyInfo &getCalculated() const { 81 return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated(); 82 } 83 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 100public: 101 static char ID; 102 103 LazyBlockFrequencyInfoPass(); 104 105 /// \brief Compute and return the block frequencies. 106 BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); } 107 108 /// \brief Compute and return the block frequencies. 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. 123void initializeLazyBFIPassPass(PassRegistry &Registry); 124} 125#endif 126