1//===- MachineBlockFrequencyInfo.h - MBB 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_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
14#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
15
16#include "llvm/CodeGen/MachineFunctionPass.h"
17#include "llvm/CodeGen/MachinePassManager.h"
18#include "llvm/Support/BlockFrequency.h"
19#include <cstdint>
20#include <memory>
21#include <optional>
22
23namespace llvm {
24
25template <class BlockT> class BlockFrequencyInfoImpl;
26class MachineBasicBlock;
27class MachineBranchProbabilityInfo;
28class MachineFunction;
29class MachineLoopInfo;
30class raw_ostream;
31
32/// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation
33/// to estimate machine basic block frequencies.
34class MachineBlockFrequencyInfo {
35 using ImplType = BlockFrequencyInfoImpl<MachineBasicBlock>;
36 std::unique_ptr<ImplType> MBFI;
37
38public:
39 MachineBlockFrequencyInfo(); // Legacy pass manager only.
40 explicit MachineBlockFrequencyInfo(MachineFunction &F,
41 MachineBranchProbabilityInfo &MBPI,
42 MachineLoopInfo &MLI);
43 MachineBlockFrequencyInfo(MachineBlockFrequencyInfo &&);
44 ~MachineBlockFrequencyInfo();
45
46 /// Handle invalidation explicitly.
47 bool invalidate(MachineFunction &F, const PreservedAnalyses &PA,
48 MachineFunctionAnalysisManager::Invalidator &);
49
50 /// calculate - compute block frequency info for the given function.
51 void calculate(const MachineFunction &F,
52 const MachineBranchProbabilityInfo &MBPI,
53 const MachineLoopInfo &MLI);
54
55 void print(raw_ostream &OS);
56
57 void releaseMemory();
58
59 /// getblockFreq - Return block frequency. Return 0 if we don't have the
60 /// information. Please note that initial frequency is equal to 1024. It means
61 /// that we should not rely on the value itself, but only on the comparison to
62 /// the other block frequencies. We do this to avoid using of floating points.
63 /// For example, to get the frequency of a block relative to the entry block,
64 /// divide the integral value returned by this function (the
65 /// BlockFrequency::getFrequency() value) by getEntryFreq().
66 BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
67
68 /// Compute the frequency of the block, relative to the entry block.
69 /// This API assumes getEntryFreq() is non-zero.
70 double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const {
71 assert(getEntryFreq() != BlockFrequency(0) &&
72 "getEntryFreq() should not return 0 here!");
73 return static_cast<double>(getBlockFreq(MBB).getFrequency()) /
74 static_cast<double>(getEntryFreq().getFrequency());
75 }
76
77 std::optional<uint64_t>
78 getBlockProfileCount(const MachineBasicBlock *MBB) const;
79 std::optional<uint64_t> getProfileCountFromFreq(BlockFrequency Freq) const;
80
81 bool isIrrLoopHeader(const MachineBasicBlock *MBB) const;
82
83 /// incrementally calculate block frequencies when we split edges, to avoid
84 /// full CFG traversal.
85 void onEdgeSplit(const MachineBasicBlock &NewPredecessor,
86 const MachineBasicBlock &NewSuccessor,
87 const MachineBranchProbabilityInfo &MBPI);
88
89 const MachineFunction *getFunction() const;
90 const MachineBranchProbabilityInfo *getMBPI() const;
91
92 /// Pop up a ghostview window with the current block frequency propagation
93 /// rendered using dot.
94 void view(const Twine &Name, bool isSimple = true) const;
95
96 /// Divide a block's BlockFrequency::getFrequency() value by this value to
97 /// obtain the entry block - relative frequency of said block.
98 BlockFrequency getEntryFreq() const;
99};
100
101/// Print the block frequency @p Freq relative to the current functions entry
102/// frequency. Returns a Printable object that can be piped via `<<` to a
103/// `raw_ostream`.
104Printable printBlockFreq(const MachineBlockFrequencyInfo &MBFI,
105 BlockFrequency Freq);
106
107/// Convenience function equivalent to calling
108/// `printBlockFreq(MBFI, MBFI.getBlockFreq(&MBB))`.
109Printable printBlockFreq(const MachineBlockFrequencyInfo &MBFI,
110 const MachineBasicBlock &MBB);
111
112class MachineBlockFrequencyAnalysis
113 : public AnalysisInfoMixin<MachineBlockFrequencyAnalysis> {
114 friend AnalysisInfoMixin<MachineBlockFrequencyAnalysis>;
115 static AnalysisKey Key;
116
117public:
118 using Result = MachineBlockFrequencyInfo;
119
120 Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
121};
122
123/// Printer pass for the \c MachineBlockFrequencyInfo results.
124class MachineBlockFrequencyPrinterPass
125 : public PassInfoMixin<MachineBlockFrequencyPrinterPass> {
126 raw_ostream &OS;
127
128public:
129 explicit MachineBlockFrequencyPrinterPass(raw_ostream &OS) : OS(OS) {}
130
131 PreservedAnalyses run(MachineFunction &MF,
132 MachineFunctionAnalysisManager &MFAM);
133
134 static bool isRequired() { return true; }
135};
136
137class MachineBlockFrequencyInfoWrapperPass : public MachineFunctionPass {
138 MachineBlockFrequencyInfo MBFI;
139
140public:
141 static char ID;
142
143 MachineBlockFrequencyInfoWrapperPass();
144
145 void getAnalysisUsage(AnalysisUsage &AU) const override;
146
147 bool runOnMachineFunction(MachineFunction &F) override;
148
149 void releaseMemory() override { MBFI.releaseMemory(); }
150
151 MachineBlockFrequencyInfo &getMBFI() { return MBFI; }
152
153 const MachineBlockFrequencyInfo &getMBFI() const { return MBFI; }
154};
155} // end namespace llvm
156
157#endif // LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
158