1//===- BlockFrequencyInfo.h - 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// Loops should be simplified before this analysis.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
15#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
16
17#include "llvm/ADT/Optional.h"
18#include "llvm/IR/PassManager.h"
19#include "llvm/Pass.h"
20#include "llvm/Support/BlockFrequency.h"
21#include <cstdint>
22#include <memory>
23
24namespace llvm {
25
26class BasicBlock;
27class BranchProbabilityInfo;
28class Function;
29class LoopInfo;
30class Module;
31class raw_ostream;
32template <class BlockT> class BlockFrequencyInfoImpl;
33
34enum PGOViewCountsType { PGOVCT_None, PGOVCT_Graph, PGOVCT_Text };
35
36/// BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to
37/// estimate IR basic block frequencies.
38class BlockFrequencyInfo {
39  using ImplType = BlockFrequencyInfoImpl<BasicBlock>;
40
41  std::unique_ptr<ImplType> BFI;
42
43public:
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() 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  /// \brief 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  Optional<uint64_t> getBlockProfileCount(const BasicBlock *BB) const;
72
73  /// \brief Returns the estimated profile count of \p Freq.
74  /// This uses the frequency \p Freq and multiplies it by
75  /// the enclosing function's count (if available) and returns the value.
76  Optional<uint64_t> getProfileCountFromFreq(uint64_t Freq) const;
77
78  // Set the frequency of the given basic block.
79  void setBlockFreq(const BasicBlock *BB, uint64_t Freq);
80
81  /// Set the frequency of \p ReferenceBB to \p Freq and scale the frequencies
82  /// of the blocks in \p BlocksToScale such that their frequencies relative
83  /// to \p ReferenceBB remain unchanged.
84  void setBlockFreqAndScale(const BasicBlock *ReferenceBB, uint64_t Freq,
85                            SmallPtrSetImpl<BasicBlock *> &BlocksToScale);
86
87  /// calculate - compute block frequency info for the given function.
88  void calculate(const Function &F, const BranchProbabilityInfo &BPI,
89                 const LoopInfo &LI);
90
91  // Print the block frequency Freq to OS using the current functions entry
92  // frequency to convert freq into a relative decimal form.
93  raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const;
94
95  // Convenience method that attempts to look up the frequency associated with
96  // BB and print it to OS.
97  raw_ostream &printBlockFreq(raw_ostream &OS, const BasicBlock *BB) const;
98
99  uint64_t getEntryFreq() const;
100  void releaseMemory();
101  void print(raw_ostream &OS) const;
102};
103
104/// \brief Analysis pass which computes \c BlockFrequencyInfo.
105class BlockFrequencyAnalysis
106    : public AnalysisInfoMixin<BlockFrequencyAnalysis> {
107  friend AnalysisInfoMixin<BlockFrequencyAnalysis>;
108
109  static AnalysisKey Key;
110
111public:
112  /// \brief Provide the result type for this analysis pass.
113  using Result = BlockFrequencyInfo;
114
115  /// \brief Run the analysis pass over a function and produce BFI.
116  Result run(Function &F, FunctionAnalysisManager &AM);
117};
118
119/// \brief Printer pass for the \c BlockFrequencyInfo results.
120class BlockFrequencyPrinterPass
121    : public PassInfoMixin<BlockFrequencyPrinterPass> {
122  raw_ostream &OS;
123
124public:
125  explicit BlockFrequencyPrinterPass(raw_ostream &OS) : OS(OS) {}
126
127  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
128};
129
130/// \brief Legacy analysis pass which computes \c BlockFrequencyInfo.
131class BlockFrequencyInfoWrapperPass : public FunctionPass {
132  BlockFrequencyInfo BFI;
133
134public:
135  static char ID;
136
137  BlockFrequencyInfoWrapperPass();
138  ~BlockFrequencyInfoWrapperPass() override;
139
140  BlockFrequencyInfo &getBFI() { return BFI; }
141  const BlockFrequencyInfo &getBFI() const { return BFI; }
142
143  void getAnalysisUsage(AnalysisUsage &AU) const override;
144
145  bool runOnFunction(Function &F) override;
146  void releaseMemory() override;
147  void print(raw_ostream &OS, const Module *M) const override;
148};
149
150} // end namespace llvm
151
152#endif // LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
153