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