blob: f470d3c6a8b5f970e7b3b0dac15e78859ff74895 [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
Xinliang David Li8dd5ce92016-06-28 04:07:03 +000030static cl::opt<GVDAGType> ViewBlockFreqPropagationDAG(
31 "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(clEnumValN(GVDT_None, "none", "do not display graphs."),
35 clEnumValN(GVDT_Fraction, "fraction",
36 "display a graph using the "
37 "fractional block frequency representation."),
38 clEnumValN(GVDT_Integer, "integer",
39 "display a graph using the raw "
40 "integer fractional block frequency representation."),
41 clEnumValN(GVDT_Count, "count", "display a graph using the real "
42 "profile count if available."),
43 clEnumValEnd));
44
45cl::opt<std::string> ViewBlockFreqFuncName("view-bfi-func-name", cl::Hidden);
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000046
47namespace llvm {
48
49template <>
50struct GraphTraits<BlockFrequencyInfo *> {
51 typedef const BasicBlock NodeType;
52 typedef succ_const_iterator ChildIteratorType;
53 typedef Function::const_iterator nodes_iterator;
54
55 static inline const NodeType *getEntryNode(const BlockFrequencyInfo *G) {
Duncan P. N. Exon Smith5a82c912015-10-10 00:53:03 +000056 return &G->getFunction()->front();
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000057 }
58 static ChildIteratorType child_begin(const NodeType *N) {
59 return succ_begin(N);
60 }
61 static ChildIteratorType child_end(const NodeType *N) {
62 return succ_end(N);
63 }
64 static nodes_iterator nodes_begin(const BlockFrequencyInfo *G) {
65 return G->getFunction()->begin();
66 }
67 static nodes_iterator nodes_end(const BlockFrequencyInfo *G) {
68 return G->getFunction()->end();
69 }
70};
71
Xinliang David Li55415f22016-06-28 03:41:29 +000072typedef BFIDOTGraphTraitsBase<BlockFrequencyInfo, BranchProbabilityInfo>
73 BFIDOTGTraitsBase;
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000074
Xinliang David Li55415f22016-06-28 03:41:29 +000075template <>
76struct DOTGraphTraits<BlockFrequencyInfo *> : public BFIDOTGTraitsBase {
77 explicit DOTGraphTraits(bool isSimple = false)
78 : BFIDOTGTraitsBase(isSimple) {}
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000079
80 std::string getNodeLabel(const BasicBlock *Node,
81 const BlockFrequencyInfo *Graph) {
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000082
Xinliang David Li55415f22016-06-28 03:41:29 +000083 return BFIDOTGTraitsBase::getNodeLabel(Node, Graph,
84 ViewBlockFreqPropagationDAG);
85 }
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000086
Xinliang David Li55415f22016-06-28 03:41:29 +000087 std::string getEdgeAttributes(const BasicBlock *Node, EdgeIter EI,
88 const BlockFrequencyInfo *BFI) {
89 return BFIDOTGTraitsBase::getEdgeAttributes(Node, EI, BFI->getBPI());
Michael Gottesmanfd8aee72013-11-14 02:27:46 +000090 }
91};
92
93} // end namespace llvm
94#endif
95
Cong Hou9b4f6b22015-07-16 23:23:35 +000096BlockFrequencyInfo::BlockFrequencyInfo() {}
97
98BlockFrequencyInfo::BlockFrequencyInfo(const Function &F,
99 const BranchProbabilityInfo &BPI,
100 const LoopInfo &LI) {
101 calculate(F, BPI, LI);
102}
103
Xinliang David Li28a93272016-05-05 21:13:27 +0000104BlockFrequencyInfo::BlockFrequencyInfo(BlockFrequencyInfo &&Arg)
105 : BFI(std::move(Arg.BFI)) {}
106
107BlockFrequencyInfo &BlockFrequencyInfo::operator=(BlockFrequencyInfo &&RHS) {
108 releaseMemory();
109 BFI = std::move(RHS.BFI);
110 return *this;
111}
112
Wei Mideee61e2015-07-14 23:40:50 +0000113void BlockFrequencyInfo::calculate(const Function &F,
114 const BranchProbabilityInfo &BPI,
115 const LoopInfo &LI) {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000116 if (!BFI)
117 BFI.reset(new ImplType);
Cong Hou5e67b662015-07-15 19:58:26 +0000118 BFI->calculate(F, BPI, LI);
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000119#ifndef NDEBUG
Xinliang David Li8dd5ce92016-06-28 04:07:03 +0000120 if (ViewBlockFreqPropagationDAG != GVDT_None &&
121 (ViewBlockFreqFuncName.empty() ||
122 F.getName().equals(ViewBlockFreqFuncName))) {
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000123 view();
Xinliang David Li8dd5ce92016-06-28 04:07:03 +0000124 }
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000125#endif
Chandler Carruth343fad42011-10-19 10:12:41 +0000126}
127
Jakub Staszak96f8c552011-12-20 20:03:10 +0000128BlockFrequency BlockFrequencyInfo::getBlockFreq(const BasicBlock *BB) const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000129 return BFI ? BFI->getBlockFreq(BB) : 0;
Jakub Staszak668c6fa2011-06-23 21:56:59 +0000130}
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000131
Easwaran Raman12b79aa2016-03-23 18:18:26 +0000132Optional<uint64_t>
133BlockFrequencyInfo::getBlockProfileCount(const BasicBlock *BB) const {
Xinliang David Lib12b3532016-06-22 17:12:12 +0000134 if (!BFI)
Easwaran Raman12b79aa2016-03-23 18:18:26 +0000135 return None;
Xinliang David Lib12b3532016-06-22 17:12:12 +0000136
137 return BFI->getBlockProfileCount(*getFunction(), BB);
Easwaran Raman12b79aa2016-03-23 18:18:26 +0000138}
139
Xinliang David Lib12b3532016-06-22 17:12:12 +0000140void BlockFrequencyInfo::setBlockFreq(const BasicBlock *BB, uint64_t Freq) {
Manman Ren72d44b12015-10-15 14:59:40 +0000141 assert(BFI && "Expected analysis to be available");
142 BFI->setBlockFreq(BB, Freq);
143}
144
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000145/// Pop up a ghostview window with the current block frequency propagation
146/// rendered using dot.
147void BlockFrequencyInfo::view() const {
148// This code is only for debugging.
149#ifndef NDEBUG
150 ViewGraph(const_cast<BlockFrequencyInfo *>(this), "BlockFrequencyDAGs");
151#else
152 errs() << "BlockFrequencyInfo::view is only available in debug builds on "
153 "systems with Graphviz or gv!\n";
154#endif // NDEBUG
155}
156
157const Function *BlockFrequencyInfo::getFunction() const {
Duncan P. N. Exon Smith10be9a82014-04-21 17:57:07 +0000158 return BFI ? BFI->getFunction() : nullptr;
Michael Gottesmanfd8aee72013-11-14 02:27:46 +0000159}
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000160
Xinliang David Li55415f22016-06-28 03:41:29 +0000161const BranchProbabilityInfo *BlockFrequencyInfo::getBPI() const {
162 return BFI ? &BFI->getBPI() : nullptr;
163}
164
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000165raw_ostream &BlockFrequencyInfo::
166printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000167 return BFI ? BFI->printBlockFreq(OS, Freq) : OS;
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000168}
169
170raw_ostream &
171BlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
172 const BasicBlock *BB) const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000173 return BFI ? BFI->printBlockFreq(OS, BB) : OS;
Michael Gottesmanfd5c4b22013-12-14 00:06:03 +0000174}
Yuchen Wu5947c8f2013-12-20 22:11:11 +0000175
176uint64_t BlockFrequencyInfo::getEntryFreq() const {
Duncan P. N. Exon Smith3dbe1052014-03-25 18:01:38 +0000177 return BFI ? BFI->getEntryFreq() : 0;
Yuchen Wu5947c8f2013-12-20 22:11:11 +0000178}
Wei Mideee61e2015-07-14 23:40:50 +0000179
180void BlockFrequencyInfo::releaseMemory() { BFI.reset(); }
181
182void BlockFrequencyInfo::print(raw_ostream &OS) const {
183 if (BFI)
184 BFI->print(OS);
185}
186
187
188INITIALIZE_PASS_BEGIN(BlockFrequencyInfoWrapperPass, "block-freq",
189 "Block Frequency Analysis", true, true)
Cong Houab23bfb2015-07-15 22:48:29 +0000190INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
Wei Mideee61e2015-07-14 23:40:50 +0000191INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
192INITIALIZE_PASS_END(BlockFrequencyInfoWrapperPass, "block-freq",
193 "Block Frequency Analysis", true, true)
194
195char BlockFrequencyInfoWrapperPass::ID = 0;
196
197
198BlockFrequencyInfoWrapperPass::BlockFrequencyInfoWrapperPass()
199 : FunctionPass(ID) {
200 initializeBlockFrequencyInfoWrapperPassPass(*PassRegistry::getPassRegistry());
201}
202
203BlockFrequencyInfoWrapperPass::~BlockFrequencyInfoWrapperPass() {}
204
205void BlockFrequencyInfoWrapperPass::print(raw_ostream &OS,
206 const Module *) const {
207 BFI.print(OS);
208}
209
210void BlockFrequencyInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
Cong Houab23bfb2015-07-15 22:48:29 +0000211 AU.addRequired<BranchProbabilityInfoWrapperPass>();
Wei Mideee61e2015-07-14 23:40:50 +0000212 AU.addRequired<LoopInfoWrapperPass>();
213 AU.setPreservesAll();
214}
215
216void BlockFrequencyInfoWrapperPass::releaseMemory() { BFI.releaseMemory(); }
217
218bool BlockFrequencyInfoWrapperPass::runOnFunction(Function &F) {
Cong Houab23bfb2015-07-15 22:48:29 +0000219 BranchProbabilityInfo &BPI =
220 getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
Wei Mideee61e2015-07-14 23:40:50 +0000221 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
222 BFI.calculate(F, BPI, LI);
223 return false;
224}
Xinliang David Li28a93272016-05-05 21:13:27 +0000225
226char BlockFrequencyAnalysis::PassID;
227BlockFrequencyInfo BlockFrequencyAnalysis::run(Function &F,
228 AnalysisManager<Function> &AM) {
229 BlockFrequencyInfo BFI;
230 BFI.calculate(F, AM.getResult<BranchProbabilityAnalysis>(F),
231 AM.getResult<LoopAnalysis>(F));
232 return BFI;
233}
234
235PreservedAnalyses
236BlockFrequencyPrinterPass::run(Function &F, AnalysisManager<Function> &AM) {
237 OS << "Printing analysis results of BFI for function "
238 << "'" << F.getName() << "':"
239 << "\n";
240 AM.getResult<BlockFrequencyAnalysis>(F).print(OS);
241 return PreservedAnalyses::all();
242}