blob: f3d7c80cef7467751a1826f1d5725c08374b5892 [file] [log] [blame]
Jakub Staszak875ebd52011-07-25 19:25:40 +00001//====----- MachineBlockFrequencyInfo.cpp - Machine Block Frequency Analysis ----====//
Jakub Staszak27131172011-07-16 20:23:20 +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/CodeGen/MachineBlockFrequencyInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "llvm/Analysis/BlockFrequencyImpl.h"
Jakub Staszak27131172011-07-16 20:23:20 +000016#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/CodeGen/Passes.h"
18#include "llvm/InitializePasses.h"
Michael Gottesman65bbcdf2013-12-03 00:49:33 +000019#include "llvm/Support/CommandLine.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/GraphWriter.h"
Jakub Staszak27131172011-07-16 20:23:20 +000022
23using namespace llvm;
24
Michael Gottesman65bbcdf2013-12-03 00:49:33 +000025#ifndef NDEBUG
26enum GVDAGType {
27 GVDT_None,
28 GVDT_Fraction,
29 GVDT_Integer
30};
31
32static cl::opt<GVDAGType>
33ViewMachineBlockFreqPropagationDAG("view-machine-block-freq-propagation-dags",
34 cl::Hidden,
35 cl::desc("Pop up a window to show a dag displaying how machine block "
36 "frequencies propgate through the CFG."),
37 cl::values(
38 clEnumValN(GVDT_None, "none",
39 "do not display graphs."),
40 clEnumValN(GVDT_Fraction, "fraction", "display a graph using the "
41 "fractional block frequency representation."),
42 clEnumValN(GVDT_Integer, "integer", "display a graph using the raw "
43 "integer fractional block frequency representation."),
44 clEnumValEnd));
45
46namespace llvm {
47
48template <>
49struct GraphTraits<MachineBlockFrequencyInfo *> {
50 typedef const MachineBasicBlock NodeType;
51 typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
52 typedef MachineFunction::const_iterator nodes_iterator;
53
54 static inline const NodeType *getEntryNode(const MachineBlockFrequencyInfo *G) {
55 return G->getFunction()->begin();
56 }
57 static ChildIteratorType child_begin(const NodeType *N) {
58 return N->succ_begin();
59 }
60 static ChildIteratorType child_end(const NodeType *N) {
61 return N->succ_end();
62 }
63 static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
64 return G->getFunction()->begin();
65 }
66 static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
67 return G->getFunction()->end();
68 }
69};
70
71template<>
72struct DOTGraphTraits<MachineBlockFrequencyInfo*> : public DefaultDOTGraphTraits {
73 explicit DOTGraphTraits(bool isSimple=false) :
74 DefaultDOTGraphTraits(isSimple) {}
75
76 static std::string getGraphName(const MachineBlockFrequencyInfo *G) {
77 return G->getFunction()->getName();
78 }
79
80 std::string getNodeLabel(const MachineBasicBlock *Node,
81 const MachineBlockFrequencyInfo *Graph) {
82 std::string Result;
83 raw_string_ostream OS(Result);
84
85 OS << Node->getName().str() << ":";
86 switch (ViewMachineBlockFreqPropagationDAG) {
87 case GVDT_Fraction:
88 Graph->getBlockFreq(Node).print(OS);
89 break;
90 case GVDT_Integer:
91 OS << Graph->getBlockFreq(Node).getFrequency();
92 break;
93 case GVDT_None:
94 llvm_unreachable("If we are not supposed to render a graph we should "
95 "never reach this point.");
96 }
97
98 return Result;
99 }
100};
101
102
103} // end namespace llvm
104#endif
105
Jakub Staszak875ebd52011-07-25 19:25:40 +0000106INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, "machine-block-freq",
Jakub Staszak27131172011-07-16 20:23:20 +0000107 "Machine Block Frequency Analysis", true, true)
108INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
Jakub Staszak875ebd52011-07-25 19:25:40 +0000109INITIALIZE_PASS_END(MachineBlockFrequencyInfo, "machine-block-freq",
Jakub Staszak27131172011-07-16 20:23:20 +0000110 "Machine Block Frequency Analysis", true, true)
111
Jakub Staszak875ebd52011-07-25 19:25:40 +0000112char MachineBlockFrequencyInfo::ID = 0;
Jakub Staszak27131172011-07-16 20:23:20 +0000113
114
Jakub Staszak875ebd52011-07-25 19:25:40 +0000115MachineBlockFrequencyInfo::MachineBlockFrequencyInfo() : MachineFunctionPass(ID) {
116 initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
Jakub Staszak27131172011-07-16 20:23:20 +0000117 MBFI = new BlockFrequencyImpl<MachineBasicBlock, MachineFunction,
118 MachineBranchProbabilityInfo>();
119}
120
Jakub Staszak875ebd52011-07-25 19:25:40 +0000121MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() {
Jakub Staszak27131172011-07-16 20:23:20 +0000122 delete MBFI;
123}
124
Jakub Staszak875ebd52011-07-25 19:25:40 +0000125void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
Jakub Staszak27131172011-07-16 20:23:20 +0000126 AU.addRequired<MachineBranchProbabilityInfo>();
127 AU.setPreservesAll();
Jakub Staszakcb7c0a42011-07-21 22:59:09 +0000128 MachineFunctionPass::getAnalysisUsage(AU);
Jakub Staszak27131172011-07-16 20:23:20 +0000129}
130
Jakub Staszak875ebd52011-07-25 19:25:40 +0000131bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
Jakub Staszak27131172011-07-16 20:23:20 +0000132 MachineBranchProbabilityInfo &MBPI = getAnalysis<MachineBranchProbabilityInfo>();
133 MBFI->doFunction(&F, &MBPI);
Michael Gottesman65bbcdf2013-12-03 00:49:33 +0000134#ifndef NDEBUG
135 if (ViewMachineBlockFreqPropagationDAG != GVDT_None) {
136 view();
137 }
138#endif
Jakub Staszak27131172011-07-16 20:23:20 +0000139 return false;
140}
141
Michael Gottesman65bbcdf2013-12-03 00:49:33 +0000142/// Pop up a ghostview window with the current block frequency propagation
143/// rendered using dot.
144void MachineBlockFrequencyInfo::view() const {
145// This code is only for debugging.
146#ifndef NDEBUG
147 ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this),
148 "MachineBlockFrequencyDAGs");
149#else
150 errs() << "BlockFrequencyInfo::view is only available in debug builds on "
151 "systems with Graphviz or gv!\n";
152#endif // NDEBUG
153}
154
Jakub Staszaka60d1302011-08-03 21:30:57 +0000155BlockFrequency MachineBlockFrequencyInfo::
Jakub Staszak96f8c552011-12-20 20:03:10 +0000156getBlockFreq(const MachineBasicBlock *MBB) const {
Jakub Staszak27131172011-07-16 20:23:20 +0000157 return MBFI->getBlockFreq(MBB);
158}
Michael Gottesman65bbcdf2013-12-03 00:49:33 +0000159
160MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
161 return MBFI->Fn;
162}
163