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