| //===- 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 BranchProbabilityInfo; |
| 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 <typename FunctionT, typename BranchProbabilityInfoPassT, |
| typename LoopInfoT, typename BlockFrequencyInfoT> |
| class LazyBlockFrequencyInfo { |
| public: |
| LazyBlockFrequencyInfo() |
| : Calculated(false), F(nullptr), BPIPass(nullptr), LI(nullptr) {} |
| |
| /// 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<BranchProbabilityInfoPassT>::getBPI(BPIPass), *LI); |
| Calculated = true; |
| } |
| return BFI; |
| } |
| |
| const BlockFrequencyInfoT &getCalculated() const { |
| return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated(); |
| } |
| |
| void releaseMemory() { |
| BFI.releaseMemory(); |
| Calculated = false; |
| setAnalysis(nullptr, nullptr, nullptr); |
| } |
| |
| private: |
| BlockFrequencyInfoT BFI; |
| bool Calculated; |
| const FunctionT *F; |
| BranchProbabilityInfoPassT *BPIPass; |
| const LoopInfoT *LI; |
| }; |
| |
| /// 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<LazyBlockFrequencyInfoPass>().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<Function, LazyBranchProbabilityInfoPass, LoopInfo, |
| BlockFrequencyInfo> |
| 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 |