aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Analysis/BlockFrequencyInfo.h
blob: 89370cbeeea1ca1f1bac6db02c0fe1d440b1aa72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//===- BlockFrequencyInfo.h - Block Frequency Analysis ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Loops should be simplified before this analysis.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H

#include "llvm/ADT/Optional.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/BlockFrequency.h"
#include <cstdint>
#include <memory>

namespace llvm {

class BasicBlock;
class BranchProbabilityInfo;
class Function;
class LoopInfo;
class Module;
class raw_ostream;
template <class BlockT> class BlockFrequencyInfoImpl;

enum PGOViewCountsType { PGOVCT_None, PGOVCT_Graph, PGOVCT_Text };

/// BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to
/// estimate IR basic block frequencies.
class BlockFrequencyInfo {
  using ImplType = BlockFrequencyInfoImpl<BasicBlock>;

  std::unique_ptr<ImplType> BFI;

public:
  BlockFrequencyInfo();
  BlockFrequencyInfo(const Function &F, const BranchProbabilityInfo &BPI,
                     const LoopInfo &LI);
  BlockFrequencyInfo(const BlockFrequencyInfo &) = delete;
  BlockFrequencyInfo &operator=(const BlockFrequencyInfo &) = delete;
  BlockFrequencyInfo(BlockFrequencyInfo &&Arg);
  BlockFrequencyInfo &operator=(BlockFrequencyInfo &&RHS);
  ~BlockFrequencyInfo();

  /// Handle invalidation explicitly.
  bool invalidate(Function &F, const PreservedAnalyses &PA,
                  FunctionAnalysisManager::Invalidator &);

  const Function *getFunction() const;
  const BranchProbabilityInfo *getBPI() const;
  void view() const;

  /// getblockFreq - Return block frequency. Return 0 if we don't have the
  /// information. Please note that initial frequency is equal to ENTRY_FREQ. It
  /// means that we should not rely on the value itself, but only on the
  /// comparison to the other block frequencies. We do this to avoid using of
  /// floating points.
  BlockFrequency getBlockFreq(const BasicBlock *BB) const;

  /// \brief Returns the estimated profile count of \p BB.
  /// This computes the relative block frequency of \p BB and multiplies it by
  /// the enclosing function's count (if available) and returns the value.
  Optional<uint64_t> getBlockProfileCount(const BasicBlock *BB) const;

  /// \brief Returns the estimated profile count of \p Freq.
  /// This uses the frequency \p Freq and multiplies it by
  /// the enclosing function's count (if available) and returns the value.
  Optional<uint64_t> getProfileCountFromFreq(uint64_t Freq) const;

  /// \brief Returns true if \p BB is an irreducible loop header
  /// block. Otherwise false.
  bool isIrrLoopHeader(const BasicBlock *BB);

  // Set the frequency of the given basic block.
  void setBlockFreq(const BasicBlock *BB, uint64_t Freq);

  /// Set the frequency of \p ReferenceBB to \p Freq and scale the frequencies
  /// of the blocks in \p BlocksToScale such that their frequencies relative
  /// to \p ReferenceBB remain unchanged.
  void setBlockFreqAndScale(const BasicBlock *ReferenceBB, uint64_t Freq,
                            SmallPtrSetImpl<BasicBlock *> &BlocksToScale);

  /// calculate - compute block frequency info for the given function.
  void calculate(const Function &F, const BranchProbabilityInfo &BPI,
                 const LoopInfo &LI);

  // Print the block frequency Freq to OS using the current functions entry
  // frequency to convert freq into a relative decimal form.
  raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const;

  // Convenience method that attempts to look up the frequency associated with
  // BB and print it to OS.
  raw_ostream &printBlockFreq(raw_ostream &OS, const BasicBlock *BB) const;

  uint64_t getEntryFreq() const;
  void releaseMemory();
  void print(raw_ostream &OS) const;
};

/// \brief Analysis pass which computes \c BlockFrequencyInfo.
class BlockFrequencyAnalysis
    : public AnalysisInfoMixin<BlockFrequencyAnalysis> {
  friend AnalysisInfoMixin<BlockFrequencyAnalysis>;

  static AnalysisKey Key;

public:
  /// \brief Provide the result type for this analysis pass.
  using Result = BlockFrequencyInfo;

  /// \brief Run the analysis pass over a function and produce BFI.
  Result run(Function &F, FunctionAnalysisManager &AM);
};

/// \brief Printer pass for the \c BlockFrequencyInfo results.
class BlockFrequencyPrinterPass
    : public PassInfoMixin<BlockFrequencyPrinterPass> {
  raw_ostream &OS;

public:
  explicit BlockFrequencyPrinterPass(raw_ostream &OS) : OS(OS) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};

/// \brief Legacy analysis pass which computes \c BlockFrequencyInfo.
class BlockFrequencyInfoWrapperPass : public FunctionPass {
  BlockFrequencyInfo BFI;

public:
  static char ID;

  BlockFrequencyInfoWrapperPass();
  ~BlockFrequencyInfoWrapperPass() override;

  BlockFrequencyInfo &getBFI() { return BFI; }
  const BlockFrequencyInfo &getBFI() const { return BFI; }

  void getAnalysisUsage(AnalysisUsage &AU) const override;

  bool runOnFunction(Function &F) override;
  void releaseMemory() override;
  void print(raw_ostream &OS, const Module *M) const override;
};

} // end namespace llvm

#endif // LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H