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