//===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This is an alternative analysis pass to BlockFrequencyInfoWrapperPass. The // difference is that with this pass the block frequencies are not computed when // the analysis pass is executed but rather when the BFI result is explicitly // requested by the analysis client. // //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H #define LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H #include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/LazyBranchProbabilityInfo.h" #include "llvm/Pass.h" namespace llvm { class AnalysisUsage; class Function; class LoopInfo; /// Wraps a BFI to allow lazy computation of the block frequencies. /// /// A pass that only conditionally uses BFI can uncondtionally require the /// analysis without paying for the overhead if BFI doesn't end up being used. template class LazyBlockFrequencyInfo { public: LazyBlockFrequencyInfo() = default; /// Set up the per-function input. void setAnalysis(const FunctionT *F, BranchProbabilityInfoPassT *BPIPass, const LoopInfoT *LI) { this->F = F; this->BPIPass = BPIPass; this->LI = LI; } /// Retrieve the BFI with the block frequencies computed. BlockFrequencyInfoT &getCalculated() { if (!Calculated) { assert(F && BPIPass && LI && "call setAnalysis"); BFI.calculate( *F, BPIPassTrait::getBPI(BPIPass), *LI); Calculated = true; } return BFI; } const BlockFrequencyInfoT &getCalculated() const { return const_cast(this)->getCalculated(); } void releaseMemory() { BFI.releaseMemory(); Calculated = false; setAnalysis(nullptr, nullptr, nullptr); } private: BlockFrequencyInfoT BFI; bool Calculated = false; const FunctionT *F = nullptr; BranchProbabilityInfoPassT *BPIPass = nullptr; const LoopInfoT *LI = nullptr; }; /// This is an alternative analysis pass to /// BlockFrequencyInfoWrapperPass. The difference is that with this pass the /// block frequencies are not computed when the analysis pass is executed but /// rather when the BFI result is explicitly requested by the analysis client. /// /// There are some additional requirements for any client pass that wants to use /// the analysis: /// /// 1. The pass needs to initialize dependent passes with: /// /// INITIALIZE_PASS_DEPENDENCY(LazyBFIPass) /// /// 2. Similarly, getAnalysisUsage should call: /// /// LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU) /// /// 3. The computed BFI should be requested with /// getAnalysis().getBFI() before either LoopInfo /// or BPI could be invalidated for example by changing the CFG. /// /// Note that it is expected that we wouldn't need this functionality for the /// new PM since with the new PM, analyses are executed on demand. class LazyBlockFrequencyInfoPass : public FunctionPass { private: LazyBlockFrequencyInfo LBFI; public: static char ID; LazyBlockFrequencyInfoPass(); /// Compute and return the block frequencies. BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); } /// Compute and return the block frequencies. const BlockFrequencyInfo &getBFI() const { return LBFI.getCalculated(); } void getAnalysisUsage(AnalysisUsage &AU) const override; /// Helper for client passes to set up the analysis usage on behalf of this /// pass. static void getLazyBFIAnalysisUsage(AnalysisUsage &AU); bool runOnFunction(Function &F) override; void releaseMemory() override; void print(raw_ostream &OS, const Module *M) const override; }; /// Helper for client passes to initialize dependent passes for LBFI. void initializeLazyBFIPassPass(PassRegistry &Registry); } #endif