1 | //===- BlockFrequencyInfo.h - 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 | // Loops should be simplified before this analysis. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H |
14 | #define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H |
15 | |
16 | #include "llvm/IR/PassManager.h" |
17 | #include "llvm/Pass.h" |
18 | #include "llvm/Support/BlockFrequency.h" |
19 | #include "llvm/Support/Printable.h" |
20 | #include <cstdint> |
21 | #include <memory> |
22 | #include <optional> |
23 | |
24 | namespace llvm { |
25 | |
26 | class BasicBlock; |
27 | class BranchProbabilityInfo; |
28 | class Function; |
29 | class LoopInfo; |
30 | class Module; |
31 | class raw_ostream; |
32 | template <class BlockT> class BlockFrequencyInfoImpl; |
33 | |
34 | enum PGOViewCountsType { PGOVCT_None, PGOVCT_Graph, PGOVCT_Text }; |
35 | |
36 | /// BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to |
37 | /// estimate IR basic block frequencies. |
38 | class BlockFrequencyInfo { |
39 | using ImplType = BlockFrequencyInfoImpl<BasicBlock>; |
40 | |
41 | std::unique_ptr<ImplType> BFI; |
42 | |
43 | public: |
44 | BlockFrequencyInfo(); |
45 | BlockFrequencyInfo(const Function &F, const BranchProbabilityInfo &BPI, |
46 | const LoopInfo &LI); |
47 | BlockFrequencyInfo(const BlockFrequencyInfo &) = delete; |
48 | BlockFrequencyInfo &operator=(const BlockFrequencyInfo &) = delete; |
49 | BlockFrequencyInfo(BlockFrequencyInfo &&Arg); |
50 | BlockFrequencyInfo &operator=(BlockFrequencyInfo &&RHS); |
51 | ~BlockFrequencyInfo(); |
52 | |
53 | /// Handle invalidation explicitly. |
54 | bool invalidate(Function &F, const PreservedAnalyses &PA, |
55 | FunctionAnalysisManager::Invalidator &); |
56 | |
57 | const Function *getFunction() const; |
58 | const BranchProbabilityInfo *getBPI() const; |
59 | void view(StringRef = "BlockFrequencyDAGs" ) const; |
60 | |
61 | /// getblockFreq - Return block frequency. Return 0 if we don't have the |
62 | /// information. Please note that initial frequency is equal to ENTRY_FREQ. It |
63 | /// means that we should not rely on the value itself, but only on the |
64 | /// comparison to the other block frequencies. We do this to avoid using of |
65 | /// floating points. |
66 | BlockFrequency getBlockFreq(const BasicBlock *BB) const; |
67 | |
68 | /// Returns the estimated profile count of \p BB. |
69 | /// This computes the relative block frequency of \p BB and multiplies it by |
70 | /// the enclosing function's count (if available) and returns the value. |
71 | std::optional<uint64_t> |
72 | getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic = false) const; |
73 | |
74 | /// Returns the estimated profile count of \p Freq. |
75 | /// This uses the frequency \p Freq and multiplies it by |
76 | /// the enclosing function's count (if available) and returns the value. |
77 | std::optional<uint64_t> getProfileCountFromFreq(BlockFrequency Freq) const; |
78 | |
79 | /// Returns true if \p BB is an irreducible loop header |
80 | /// block. Otherwise false. |
81 | bool (const BasicBlock *BB); |
82 | |
83 | // Set the frequency of the given basic block. |
84 | void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq); |
85 | |
86 | /// Set the frequency of \p ReferenceBB to \p Freq and scale the frequencies |
87 | /// of the blocks in \p BlocksToScale such that their frequencies relative |
88 | /// to \p ReferenceBB remain unchanged. |
89 | void setBlockFreqAndScale(const BasicBlock *ReferenceBB, BlockFrequency Freq, |
90 | SmallPtrSetImpl<BasicBlock *> &BlocksToScale); |
91 | |
92 | /// calculate - compute block frequency info for the given function. |
93 | void calculate(const Function &F, const BranchProbabilityInfo &BPI, |
94 | const LoopInfo &LI); |
95 | |
96 | BlockFrequency getEntryFreq() const; |
97 | void releaseMemory(); |
98 | void print(raw_ostream &OS) const; |
99 | |
100 | // Compare to the other BFI and verify they match. |
101 | void verifyMatch(BlockFrequencyInfo &Other) const; |
102 | }; |
103 | |
104 | /// Print the block frequency @p Freq relative to the current functions entry |
105 | /// frequency. Returns a Printable object that can be piped via `<<` to a |
106 | /// `raw_ostream`. |
107 | Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq); |
108 | |
109 | /// Convenience function equivalent to calling |
110 | /// `printBlockFreq(BFI, BFI.getBlocakFreq(&BB))`. |
111 | Printable printBlockFreq(const BlockFrequencyInfo &BFI, const BasicBlock &BB); |
112 | |
113 | /// Analysis pass which computes \c BlockFrequencyInfo. |
114 | class BlockFrequencyAnalysis |
115 | : public AnalysisInfoMixin<BlockFrequencyAnalysis> { |
116 | friend AnalysisInfoMixin<BlockFrequencyAnalysis>; |
117 | |
118 | static AnalysisKey Key; |
119 | |
120 | public: |
121 | /// Provide the result type for this analysis pass. |
122 | using Result = BlockFrequencyInfo; |
123 | |
124 | /// Run the analysis pass over a function and produce BFI. |
125 | Result run(Function &F, FunctionAnalysisManager &AM); |
126 | }; |
127 | |
128 | /// Printer pass for the \c BlockFrequencyInfo results. |
129 | class BlockFrequencyPrinterPass |
130 | : public PassInfoMixin<BlockFrequencyPrinterPass> { |
131 | raw_ostream &OS; |
132 | |
133 | public: |
134 | explicit BlockFrequencyPrinterPass(raw_ostream &OS) : OS(OS) {} |
135 | |
136 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); |
137 | |
138 | static bool isRequired() { return true; } |
139 | }; |
140 | |
141 | /// Legacy analysis pass which computes \c BlockFrequencyInfo. |
142 | class BlockFrequencyInfoWrapperPass : public FunctionPass { |
143 | BlockFrequencyInfo BFI; |
144 | |
145 | public: |
146 | static char ID; |
147 | |
148 | BlockFrequencyInfoWrapperPass(); |
149 | ~BlockFrequencyInfoWrapperPass() override; |
150 | |
151 | BlockFrequencyInfo &getBFI() { return BFI; } |
152 | const BlockFrequencyInfo &getBFI() const { return BFI; } |
153 | |
154 | void getAnalysisUsage(AnalysisUsage &AU) const override; |
155 | |
156 | bool runOnFunction(Function &F) override; |
157 | void releaseMemory() override; |
158 | void print(raw_ostream &OS, const Module *M) const override; |
159 | }; |
160 | |
161 | } // end namespace llvm |
162 | |
163 | #endif // LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H |
164 | |