Line data Source code
1 : //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
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 : #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
15 : #include "llvm/ADT/DenseMap.h"
16 : #include "llvm/ADT/None.h"
17 : #include "llvm/ADT/iterator.h"
18 : #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
19 : #include "llvm/CodeGen/MachineBasicBlock.h"
20 : #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
21 : #include "llvm/CodeGen/MachineFunction.h"
22 : #include "llvm/CodeGen/MachineLoopInfo.h"
23 : #include "llvm/Pass.h"
24 : #include "llvm/Support/CommandLine.h"
25 : #include "llvm/Support/GraphWriter.h"
26 : #include <string>
27 :
28 : using namespace llvm;
29 :
30 : #define DEBUG_TYPE "machine-block-freq"
31 :
32 : static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
33 : "view-machine-block-freq-propagation-dags", cl::Hidden,
34 : cl::desc("Pop up a window to show a dag displaying how machine block "
35 : "frequencies propagate through the CFG."),
36 : cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
37 : clEnumValN(GVDT_Fraction, "fraction",
38 : "display a graph using the "
39 : "fractional block frequency representation."),
40 : clEnumValN(GVDT_Integer, "integer",
41 : "display a graph using the raw "
42 : "integer fractional block frequency representation."),
43 : clEnumValN(GVDT_Count, "count", "display a graph using the real "
44 : "profile count if available.")));
45 :
46 : // Similar option above, but used to control BFI display only after MBP pass
47 : cl::opt<GVDAGType> ViewBlockLayoutWithBFI(
48 : "view-block-layout-with-bfi", cl::Hidden,
49 : cl::desc(
50 : "Pop up a window to show a dag displaying MBP layout and associated "
51 : "block frequencies of the CFG."),
52 : cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
53 : clEnumValN(GVDT_Fraction, "fraction",
54 : "display a graph using the "
55 : "fractional block frequency representation."),
56 : clEnumValN(GVDT_Integer, "integer",
57 : "display a graph using the raw "
58 : "integer fractional block frequency representation."),
59 : clEnumValN(GVDT_Count, "count",
60 : "display a graph using the real "
61 : "profile count if available.")));
62 :
63 : // Command line option to specify the name of the function for CFG dump
64 : // Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name=
65 : extern cl::opt<std::string> ViewBlockFreqFuncName;
66 :
67 : // Command line option to specify hot frequency threshold.
68 : // Defined in Analysis/BlockFrequencyInfo.cpp: -view-hot-freq-perc=
69 : extern cl::opt<unsigned> ViewHotFreqPercent;
70 :
71 : static cl::opt<bool> PrintMachineBlockFreq(
72 : "print-machine-bfi", cl::init(false), cl::Hidden,
73 : cl::desc("Print the machine block frequency info."));
74 :
75 : // Command line option to specify the name of the function for block frequency
76 : // dump. Defined in Analysis/BlockFrequencyInfo.cpp.
77 : extern cl::opt<std::string> PrintBlockFreqFuncName;
78 :
79 : static GVDAGType getGVDT() {
80 0 : if (ViewBlockLayoutWithBFI != GVDT_None)
81 : return ViewBlockLayoutWithBFI;
82 :
83 : return ViewMachineBlockFreqPropagationDAG;
84 : }
85 :
86 : namespace llvm {
87 :
88 : template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
89 : using NodeRef = const MachineBasicBlock *;
90 : using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
91 : using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
92 :
93 : static NodeRef getEntryNode(const MachineBlockFrequencyInfo *G) {
94 : return &G->getFunction()->front();
95 : }
96 :
97 : static ChildIteratorType child_begin(const NodeRef N) {
98 : return N->succ_begin();
99 : }
100 :
101 : static ChildIteratorType child_end(const NodeRef N) { return N->succ_end(); }
102 :
103 : static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
104 0 : return nodes_iterator(G->getFunction()->begin());
105 : }
106 :
107 : static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
108 0 : return nodes_iterator(G->getFunction()->end());
109 : }
110 : };
111 :
112 : using MBFIDOTGraphTraitsBase =
113 : BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
114 : MachineBranchProbabilityInfo>;
115 :
116 : template <>
117 0 : struct DOTGraphTraits<MachineBlockFrequencyInfo *>
118 : : public MBFIDOTGraphTraitsBase {
119 : const MachineFunction *CurFunc = nullptr;
120 : DenseMap<const MachineBasicBlock *, int> LayoutOrderMap;
121 :
122 : explicit DOTGraphTraits(bool isSimple = false)
123 0 : : MBFIDOTGraphTraitsBase(isSimple) {}
124 :
125 0 : std::string getNodeLabel(const MachineBasicBlock *Node,
126 : const MachineBlockFrequencyInfo *Graph) {
127 : int layout_order = -1;
128 : // Attach additional ordering information if 'isSimple' is false.
129 0 : if (!isSimple()) {
130 0 : const MachineFunction *F = Node->getParent();
131 0 : if (!CurFunc || F != CurFunc) {
132 0 : if (CurFunc)
133 0 : LayoutOrderMap.clear();
134 :
135 0 : CurFunc = F;
136 : int O = 0;
137 0 : for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) {
138 0 : LayoutOrderMap[&*MBI] = O;
139 : }
140 : }
141 0 : layout_order = LayoutOrderMap[Node];
142 : }
143 : return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(),
144 0 : layout_order);
145 : }
146 :
147 : std::string getNodeAttributes(const MachineBasicBlock *Node,
148 : const MachineBlockFrequencyInfo *Graph) {
149 : return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph,
150 0 : ViewHotFreqPercent);
151 : }
152 :
153 0 : std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
154 : const MachineBlockFrequencyInfo *MBFI) {
155 : return MBFIDOTGraphTraitsBase::getEdgeAttributes(
156 0 : Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent);
157 : }
158 : };
159 :
160 : } // end namespace llvm
161 :
162 85394 : INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, DEBUG_TYPE,
163 : "Machine Block Frequency Analysis", true, true)
164 85394 : INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
165 85394 : INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
166 405743 : INITIALIZE_PASS_END(MachineBlockFrequencyInfo, DEBUG_TYPE,
167 : "Machine Block Frequency Analysis", true, true)
168 :
169 : char MachineBlockFrequencyInfo::ID = 0;
170 :
171 86248 : MachineBlockFrequencyInfo::MachineBlockFrequencyInfo()
172 86248 : : MachineFunctionPass(ID) {
173 86248 : initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
174 86248 : }
175 :
176 : MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default;
177 :
178 86226 : void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
179 : AU.addRequired<MachineBranchProbabilityInfo>();
180 : AU.addRequired<MachineLoopInfo>();
181 : AU.setPreservesAll();
182 86226 : MachineFunctionPass::getAnalysisUsage(AU);
183 86226 : }
184 :
185 826498 : void MachineBlockFrequencyInfo::calculate(
186 : const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI,
187 : const MachineLoopInfo &MLI) {
188 826498 : if (!MBFI)
189 826498 : MBFI.reset(new ImplType);
190 826498 : MBFI->calculate(F, MBPI, MLI);
191 826498 : if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
192 : (ViewBlockFreqFuncName.empty() ||
193 826498 : F.getName().equals(ViewBlockFreqFuncName))) {
194 0 : view("MachineBlockFrequencyDAGS." + F.getName());
195 : }
196 826498 : if (PrintMachineBlockFreq &&
197 : (PrintBlockFreqFuncName.empty() ||
198 826498 : F.getName().equals(PrintBlockFreqFuncName))) {
199 0 : MBFI->print(dbgs());
200 : }
201 826498 : }
202 :
203 826476 : bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
204 : MachineBranchProbabilityInfo &MBPI =
205 826476 : getAnalysis<MachineBranchProbabilityInfo>();
206 826476 : MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
207 826476 : calculate(F, MBPI, MLI);
208 826476 : return false;
209 : }
210 :
211 826538 : void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
212 :
213 : /// Pop up a ghostview window with the current block frequency propagation
214 : /// rendered using dot.
215 0 : void MachineBlockFrequencyInfo::view(const Twine &Name, bool isSimple) const {
216 : // This code is only for debugging.
217 0 : ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this), Name, isSimple);
218 0 : }
219 :
220 : BlockFrequency
221 8739255 : MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const {
222 8739255 : return MBFI ? MBFI->getBlockFreq(MBB) : 0;
223 : }
224 :
225 62 : Optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount(
226 : const MachineBasicBlock *MBB) const {
227 62 : const Function &F = MBFI->getFunction()->getFunction();
228 62 : return MBFI ? MBFI->getBlockProfileCount(F, MBB) : None;
229 : }
230 :
231 : Optional<uint64_t>
232 0 : MachineBlockFrequencyInfo::getProfileCountFromFreq(uint64_t Freq) const {
233 0 : const Function &F = MBFI->getFunction()->getFunction();
234 0 : return MBFI ? MBFI->getProfileCountFromFreq(F, Freq) : None;
235 : }
236 :
237 : bool
238 0 : MachineBlockFrequencyInfo::isIrrLoopHeader(const MachineBasicBlock *MBB) {
239 : assert(MBFI && "Expected analysis to be available");
240 0 : return MBFI->isIrrLoopHeader(MBB);
241 : }
242 :
243 0 : const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
244 0 : return MBFI ? MBFI->getFunction() : nullptr;
245 : }
246 :
247 0 : const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const {
248 0 : return MBFI ? &MBFI->getBPI() : nullptr;
249 : }
250 :
251 : raw_ostream &
252 0 : MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
253 : const BlockFrequency Freq) const {
254 0 : return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
255 : }
256 :
257 : raw_ostream &
258 0 : MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
259 : const MachineBasicBlock *MBB) const {
260 0 : return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
261 : }
262 :
263 4991736 : uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
264 4991736 : return MBFI ? MBFI->getEntryFreq() : 0;
265 : }
|