blob: 1370ace759b0fdf17dc8832593bffc32cd1315b9 [file] [log] [blame]
Duncan P. N. Exon Smith689a5072014-04-11 23:20:58 +00001//===- BlockFrequencyInfo.cpp - Block Frequency Analysis ------------------===//
Jakub Staszak668c6fa2011-06-23 21:56:59 +00002//
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
Jakub Staszak875ebd52011-07-25 19:25:40 +000014#include "llvm/Analysis/BlockFrequencyInfo.h"
Duncan P. N. Exon Smith689a5072014-04-11 23:20:58 +000015#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "llvm/Analysis/BranchProbabilityInfo.h"
Jakub Staszak668c6fa2011-06-23 21:56:59 +000017#include "llvm/Analysis/LoopInfo.h"
18#include "llvm/Analysis/Passes.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000019#include "llvm/IR/CFG.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/InitializePasses.h"
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000021#include "llvm/Support/CommandLine.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/GraphWriter.h"
Jakub Staszak668c6fa2011-06-23 21:56:59 +000024
25using namespace llvm;
26
Chandler Carruthf1221bd2014-04-22 02:48:03 +000027#define DEBUG_TYPE "block-freq"
28
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000029#ifndef NDEBUG
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000030static cl::opt<GVDAGType>
31ViewBlockFreqPropagationDAG("view-block-freq-propagation-dags", cl::Hidden,
32 cl::desc("Pop up a window to show a dag displaying how block "
33 "frequencies propagation through the CFG."),
34 cl::values(
35 clEnumValN(GVDT_None, "none",
36 "do not display graphs."),
37 clEnumValN(GVDT_Fraction, "fraction", "display a graph using the "
38 "fractional block frequency representation."),
39 clEnumValN(GVDT_Integer, "integer", "display a graph using the raw "
40 "integer fractional block frequency representation."),
41 clEnumValEnd));
42
43namespace llvm {
44
45template <>
46struct GraphTraits<BlockFrequencyInfo *> {
47 typedef const BasicBlock NodeType;
48 typedef succ_const_iterator ChildIteratorType;
49 typedef Function::const_iterator nodes_iterator;
50
51 static inline const NodeType *getEntryNode(const BlockFrequencyInfo *G) {
Duncan P. N. Exon Smith5a82c912015-10-10 00:53:03 +000052 return &G->getFunction()->front();
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000053 }
54 static ChildIteratorType child_begin(const NodeType *N) {
55 return succ_begin(N);
56 }
57 static ChildIteratorType child_end(const NodeType *N) {
58 return succ_end(N);
59 }
60 static nodes_iterator nodes_begin(const BlockFrequencyInfo *G) {
61 return G->getFunction()->begin();
62 }
63 static nodes_iterator nodes_end(const BlockFrequencyInfo *G) {
64 return G->getFunction()->end();
65 }
66};
67
Xinliang David Li55415f22016-06-28 03:41:29 +000068typedef BFIDOTGraphTraitsBase<BlockFrequencyInfo, BranchProbabilityInfo>
69 BFIDOTGTraitsBase;
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000070
Xinliang David Li55415f22016-06-28 03:41:29 +000071template <>
72struct DOTGraphTraits<BlockFrequencyInfo *> : public BFIDOTGTraitsBase {
73 explicit DOTGraphTraits(bool isSimple = false)
74 : BFIDOTGTraitsBase(isSimple) {}
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000075
76 std::string getNodeLabel(const BasicBlock *Node,
77 const BlockFrequencyInfo *Graph) {
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000078
Xinliang David Li55415f22016-06-28 03:41:29 +000079 return BFIDOTGTraitsBase::getNodeLabel(Node, Graph,
80 ViewBlockFreqPropagationDAG);
81 }
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000082
Xinliang David Li55415f22016-06-28 03:41:29 +000083 std::string getEdgeAttributes(const BasicBlock *Node, EdgeIter EI,
84 const BlockFrequencyInfo *BFI) {
85 return BFIDOTGTraitsBase::getEdgeAttributes(Node, EI, BFI->getBPI());
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000086 }
87};
88
89} // end namespace llvm
90#endif
91
Cong Hou9b4f6b22015-07-16 23:23:35 +000092BlockFrequencyInfo::BlockFrequencyInfo() {}
93
94BlockFrequencyInfo::BlockFrequencyInfo(const Function &F,
95 const BranchProbabilityInfo &BPI,
96 const LoopInfo &LI) {
97 calculate(F, BPI, LI);
98}
99
Xinliang David Li28a93272016-05-05 21:13:27 +0000100BlockFrequencyInfo::BlockFrequencyInfo(BlockFrequencyInfo &&Arg)
101 : BFI(std::move(Arg.BFI)) {}
102
103BlockFrequencyInfo &BlockFrequencyInfo::operator=(BlockFrequencyInfo &&RHS) {
104 releaseMemory();
105 BFI = std::move(RHS.BFI);
106 return *this;
107}
108
Wei Mideee61e2015-07-14 23:40:50 +0000109void BlockFrequencyInfo::calculate(const Function &F,
110 const BranchProbabilityInfo &BPI,
111 const LoopInfo &LI) {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000112 if (!BFI)
113 BFI.reset(new ImplType);
Cong Hou5e67b662015-07-15 19:58:26 +0000114 BFI->calculate(F, BPI, LI);
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000115#ifndef NDEBUG
116 if (ViewBlockFreqPropagationDAG != GVDT_None)
117 view();
118#endif
Chandler Carruth343fad42011-10-19 10:12:41 +0000119}
120
Jakub Staszak96f8c552011-12-20 20:03:10 +0000121BlockFrequency BlockFrequencyInfo::getBlockFreq(const BasicBlock *BB) const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000122 return BFI ? BFI->getBlockFreq(BB) : 0;
Jakub Staszak668c6fa2011-06-23 21:56:59 +0000123}
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000124
Easwaran Raman12b79aa2016-03-23 18:18:26 +0000125Optional<uint64_t>
126BlockFrequencyInfo::getBlockProfileCount(const BasicBlock *BB) const {
Xinliang David Lib12b3532016-06-22 17:12:12 +0000127 if (!BFI)
Easwaran Raman12b79aa2016-03-23 18:18:26 +0000128 return None;
Xinliang David Lib12b3532016-06-22 17:12:12 +0000129
130 return BFI->getBlockProfileCount(*getFunction(), BB);
Easwaran Raman12b79aa2016-03-23 18:18:26 +0000131}
132
Xinliang David Lib12b3532016-06-22 17:12:12 +0000133void BlockFrequencyInfo::setBlockFreq(const BasicBlock *BB, uint64_t Freq) {
Manman Ren72d44b12015-10-15 14:59:40 +0000134 assert(BFI && "Expected analysis to be available");
135 BFI->setBlockFreq(BB, Freq);
136}
137
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000138/// Pop up a ghostview window with the current block frequency propagation
139/// rendered using dot.
140void BlockFrequencyInfo::view() const {
141// This code is only for debugging.
142#ifndef NDEBUG
143 ViewGraph(const_cast<BlockFrequencyInfo *>(this), "BlockFrequencyDAGs");
144#else
145 errs() << "BlockFrequencyInfo::view is only available in debug builds on "
146 "systems with Graphviz or gv!\n";
147#endif // NDEBUG
148}
149
150const Function *BlockFrequencyInfo::getFunction() const {
Duncan P. N. Exon Smith10be9a82014-04-21 17:57:07 +0000151 return BFI ? BFI->getFunction() : nullptr;
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000152}
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000153
Xinliang David Li55415f22016-06-28 03:41:29 +0000154const BranchProbabilityInfo *BlockFrequencyInfo::getBPI() const {
155 return BFI ? &BFI->getBPI() : nullptr;
156}
157
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000158raw_ostream &BlockFrequencyInfo::
159printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000160 return BFI ? BFI->printBlockFreq(OS, Freq) : OS;
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000161}
162
163raw_ostream &
164BlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
165 const BasicBlock *BB) const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000166 return BFI ? BFI->printBlockFreq(OS, BB) : OS;
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000167}
Yuchen Wu5947c8f2013-12-20 22:11:11 +0000168
169uint64_t BlockFrequencyInfo::getEntryFreq() const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000170 return BFI ? BFI->getEntryFreq() : 0;
Yuchen Wu5947c8f2013-12-20 22:11:11 +0000171}
Wei Mideee61e2015-07-14 23:40:50 +0000172
173void BlockFrequencyInfo::releaseMemory() { BFI.reset(); }
174
175void BlockFrequencyInfo::print(raw_ostream &OS) const {
176 if (BFI)
177 BFI->print(OS);
178}
179
180
181INITIALIZE_PASS_BEGIN(BlockFrequencyInfoWrapperPass, "block-freq",
182 "Block Frequency Analysis", true, true)
Cong Houab23bfb2015-07-15 22:48:29 +0000183INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
Wei Mideee61e2015-07-14 23:40:50 +0000184INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
185INITIALIZE_PASS_END(BlockFrequencyInfoWrapperPass, "block-freq",
186 "Block Frequency Analysis", true, true)
187
188char BlockFrequencyInfoWrapperPass::ID = 0;
189
190
191BlockFrequencyInfoWrapperPass::BlockFrequencyInfoWrapperPass()
192 : FunctionPass(ID) {
193 initializeBlockFrequencyInfoWrapperPassPass(*PassRegistry::getPassRegistry());
194}
195
196BlockFrequencyInfoWrapperPass::~BlockFrequencyInfoWrapperPass() {}
197
198void BlockFrequencyInfoWrapperPass::print(raw_ostream &OS,
199 const Module *) const {
200 BFI.print(OS);
201}
202
203void BlockFrequencyInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
Cong Houab23bfb2015-07-15 22:48:29 +0000204 AU.addRequired<BranchProbabilityInfoWrapperPass>();
Wei Mideee61e2015-07-14 23:40:50 +0000205 AU.addRequired<LoopInfoWrapperPass>();
206 AU.setPreservesAll();
207}
208
209void BlockFrequencyInfoWrapperPass::releaseMemory() { BFI.releaseMemory(); }
210
211bool BlockFrequencyInfoWrapperPass::runOnFunction(Function &F) {
Cong Houab23bfb2015-07-15 22:48:29 +0000212 BranchProbabilityInfo &BPI =
213 getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
Wei Mideee61e2015-07-14 23:40:50 +0000214 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
215 BFI.calculate(F, BPI, LI);
216 return false;
217}
Xinliang David Li28a93272016-05-05 21:13:27 +0000218
219char BlockFrequencyAnalysis::PassID;
220BlockFrequencyInfo BlockFrequencyAnalysis::run(Function &F,
221 AnalysisManager<Function> &AM) {
222 BlockFrequencyInfo BFI;
223 BFI.calculate(F, AM.getResult<BranchProbabilityAnalysis>(F),
224 AM.getResult<LoopAnalysis>(F));
225 return BFI;
226}
227
228PreservedAnalyses
229BlockFrequencyPrinterPass::run(Function &F, AnalysisManager<Function> &AM) {
230 OS << "Printing analysis results of BFI for function "
231 << "'" << F.getName() << "':"
232 << "\n";
233 AM.getResult<BlockFrequencyAnalysis>(F).print(OS);
234 return PreservedAnalyses::all();
235}