xref: /minix3/external/bsd/llvm/dist/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // Loops should be simplified before this analysis.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
15*0a6a1f1dSLionel Sambuc #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
16f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/CodeGen/MachineFunction.h"
18*0a6a1f1dSLionel Sambuc #include "llvm/CodeGen/MachineLoopInfo.h"
19f4a2713aSLionel Sambuc #include "llvm/CodeGen/Passes.h"
20f4a2713aSLionel Sambuc #include "llvm/InitializePasses.h"
21*0a6a1f1dSLionel Sambuc #include "llvm/Support/CommandLine.h"
22*0a6a1f1dSLionel Sambuc #include "llvm/Support/Debug.h"
23*0a6a1f1dSLionel Sambuc #include "llvm/Support/GraphWriter.h"
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc using namespace llvm;
26f4a2713aSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "block-freq"
28*0a6a1f1dSLionel Sambuc 
29*0a6a1f1dSLionel Sambuc #ifndef NDEBUG
30*0a6a1f1dSLionel Sambuc enum GVDAGType {
31*0a6a1f1dSLionel Sambuc   GVDT_None,
32*0a6a1f1dSLionel Sambuc   GVDT_Fraction,
33*0a6a1f1dSLionel Sambuc   GVDT_Integer
34*0a6a1f1dSLionel Sambuc };
35*0a6a1f1dSLionel Sambuc 
36*0a6a1f1dSLionel Sambuc static cl::opt<GVDAGType>
37*0a6a1f1dSLionel Sambuc ViewMachineBlockFreqPropagationDAG("view-machine-block-freq-propagation-dags",
38*0a6a1f1dSLionel Sambuc                                    cl::Hidden,
39*0a6a1f1dSLionel Sambuc           cl::desc("Pop up a window to show a dag displaying how machine block "
40*0a6a1f1dSLionel Sambuc                    "frequencies propagate through the CFG."),
41*0a6a1f1dSLionel Sambuc           cl::values(
42*0a6a1f1dSLionel Sambuc             clEnumValN(GVDT_None, "none",
43*0a6a1f1dSLionel Sambuc                        "do not display graphs."),
44*0a6a1f1dSLionel Sambuc             clEnumValN(GVDT_Fraction, "fraction", "display a graph using the "
45*0a6a1f1dSLionel Sambuc                        "fractional block frequency representation."),
46*0a6a1f1dSLionel Sambuc             clEnumValN(GVDT_Integer, "integer", "display a graph using the raw "
47*0a6a1f1dSLionel Sambuc                        "integer fractional block frequency representation."),
48*0a6a1f1dSLionel Sambuc             clEnumValEnd));
49*0a6a1f1dSLionel Sambuc 
50*0a6a1f1dSLionel Sambuc namespace llvm {
51*0a6a1f1dSLionel Sambuc 
52*0a6a1f1dSLionel Sambuc template <>
53*0a6a1f1dSLionel Sambuc struct GraphTraits<MachineBlockFrequencyInfo *> {
54*0a6a1f1dSLionel Sambuc   typedef const MachineBasicBlock NodeType;
55*0a6a1f1dSLionel Sambuc   typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
56*0a6a1f1dSLionel Sambuc   typedef MachineFunction::const_iterator nodes_iterator;
57*0a6a1f1dSLionel Sambuc 
58*0a6a1f1dSLionel Sambuc   static inline
getEntryNodellvm::GraphTraits59*0a6a1f1dSLionel Sambuc   const NodeType *getEntryNode(const MachineBlockFrequencyInfo *G) {
60*0a6a1f1dSLionel Sambuc     return G->getFunction()->begin();
61*0a6a1f1dSLionel Sambuc   }
62*0a6a1f1dSLionel Sambuc 
child_beginllvm::GraphTraits63*0a6a1f1dSLionel Sambuc   static ChildIteratorType child_begin(const NodeType *N) {
64*0a6a1f1dSLionel Sambuc     return N->succ_begin();
65*0a6a1f1dSLionel Sambuc   }
66*0a6a1f1dSLionel Sambuc 
child_endllvm::GraphTraits67*0a6a1f1dSLionel Sambuc   static ChildIteratorType child_end(const NodeType *N) {
68*0a6a1f1dSLionel Sambuc     return N->succ_end();
69*0a6a1f1dSLionel Sambuc   }
70*0a6a1f1dSLionel Sambuc 
nodes_beginllvm::GraphTraits71*0a6a1f1dSLionel Sambuc   static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
72*0a6a1f1dSLionel Sambuc     return G->getFunction()->begin();
73*0a6a1f1dSLionel Sambuc   }
74*0a6a1f1dSLionel Sambuc 
nodes_endllvm::GraphTraits75*0a6a1f1dSLionel Sambuc   static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
76*0a6a1f1dSLionel Sambuc     return G->getFunction()->end();
77*0a6a1f1dSLionel Sambuc   }
78*0a6a1f1dSLionel Sambuc };
79*0a6a1f1dSLionel Sambuc 
80*0a6a1f1dSLionel Sambuc template<>
81*0a6a1f1dSLionel Sambuc struct DOTGraphTraits<MachineBlockFrequencyInfo*> :
82*0a6a1f1dSLionel Sambuc     public DefaultDOTGraphTraits {
DOTGraphTraitsllvm::DOTGraphTraits83*0a6a1f1dSLionel Sambuc   explicit DOTGraphTraits(bool isSimple=false) :
84*0a6a1f1dSLionel Sambuc     DefaultDOTGraphTraits(isSimple) {}
85*0a6a1f1dSLionel Sambuc 
getGraphNamellvm::DOTGraphTraits86*0a6a1f1dSLionel Sambuc   static std::string getGraphName(const MachineBlockFrequencyInfo *G) {
87*0a6a1f1dSLionel Sambuc     return G->getFunction()->getName();
88*0a6a1f1dSLionel Sambuc   }
89*0a6a1f1dSLionel Sambuc 
getNodeLabelllvm::DOTGraphTraits90*0a6a1f1dSLionel Sambuc   std::string getNodeLabel(const MachineBasicBlock *Node,
91*0a6a1f1dSLionel Sambuc                            const MachineBlockFrequencyInfo *Graph) {
92*0a6a1f1dSLionel Sambuc     std::string Result;
93*0a6a1f1dSLionel Sambuc     raw_string_ostream OS(Result);
94*0a6a1f1dSLionel Sambuc 
95*0a6a1f1dSLionel Sambuc     OS << Node->getName().str() << ":";
96*0a6a1f1dSLionel Sambuc     switch (ViewMachineBlockFreqPropagationDAG) {
97*0a6a1f1dSLionel Sambuc     case GVDT_Fraction:
98*0a6a1f1dSLionel Sambuc       Graph->printBlockFreq(OS, Node);
99*0a6a1f1dSLionel Sambuc       break;
100*0a6a1f1dSLionel Sambuc     case GVDT_Integer:
101*0a6a1f1dSLionel Sambuc       OS << Graph->getBlockFreq(Node).getFrequency();
102*0a6a1f1dSLionel Sambuc       break;
103*0a6a1f1dSLionel Sambuc     case GVDT_None:
104*0a6a1f1dSLionel Sambuc       llvm_unreachable("If we are not supposed to render a graph we should "
105*0a6a1f1dSLionel Sambuc                        "never reach this point.");
106*0a6a1f1dSLionel Sambuc     }
107*0a6a1f1dSLionel Sambuc 
108*0a6a1f1dSLionel Sambuc     return Result;
109*0a6a1f1dSLionel Sambuc   }
110*0a6a1f1dSLionel Sambuc };
111*0a6a1f1dSLionel Sambuc 
112*0a6a1f1dSLionel Sambuc 
113*0a6a1f1dSLionel Sambuc } // end namespace llvm
114*0a6a1f1dSLionel Sambuc #endif
115*0a6a1f1dSLionel Sambuc 
116f4a2713aSLionel Sambuc INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, "machine-block-freq",
117f4a2713aSLionel Sambuc                       "Machine Block Frequency Analysis", true, true)
118f4a2713aSLionel Sambuc INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
119*0a6a1f1dSLionel Sambuc INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
120f4a2713aSLionel Sambuc INITIALIZE_PASS_END(MachineBlockFrequencyInfo, "machine-block-freq",
121f4a2713aSLionel Sambuc                     "Machine Block Frequency Analysis", true, true)
122f4a2713aSLionel Sambuc 
123f4a2713aSLionel Sambuc char MachineBlockFrequencyInfo::ID = 0;
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc 
126*0a6a1f1dSLionel Sambuc MachineBlockFrequencyInfo::
MachineBlockFrequencyInfo()127*0a6a1f1dSLionel Sambuc MachineBlockFrequencyInfo() :MachineFunctionPass(ID) {
128f4a2713aSLionel Sambuc   initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
129f4a2713aSLionel Sambuc }
130f4a2713aSLionel Sambuc 
~MachineBlockFrequencyInfo()131*0a6a1f1dSLionel Sambuc MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() {}
132f4a2713aSLionel Sambuc 
getAnalysisUsage(AnalysisUsage & AU) const133f4a2713aSLionel Sambuc void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
134f4a2713aSLionel Sambuc   AU.addRequired<MachineBranchProbabilityInfo>();
135*0a6a1f1dSLionel Sambuc   AU.addRequired<MachineLoopInfo>();
136f4a2713aSLionel Sambuc   AU.setPreservesAll();
137f4a2713aSLionel Sambuc   MachineFunctionPass::getAnalysisUsage(AU);
138f4a2713aSLionel Sambuc }
139f4a2713aSLionel Sambuc 
runOnMachineFunction(MachineFunction & F)140f4a2713aSLionel Sambuc bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
141*0a6a1f1dSLionel Sambuc   MachineBranchProbabilityInfo &MBPI =
142*0a6a1f1dSLionel Sambuc       getAnalysis<MachineBranchProbabilityInfo>();
143*0a6a1f1dSLionel Sambuc   MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
144*0a6a1f1dSLionel Sambuc   if (!MBFI)
145*0a6a1f1dSLionel Sambuc     MBFI.reset(new ImplType);
146*0a6a1f1dSLionel Sambuc   MBFI->doFunction(&F, &MBPI, &MLI);
147*0a6a1f1dSLionel Sambuc #ifndef NDEBUG
148*0a6a1f1dSLionel Sambuc   if (ViewMachineBlockFreqPropagationDAG != GVDT_None) {
149*0a6a1f1dSLionel Sambuc     view();
150*0a6a1f1dSLionel Sambuc   }
151*0a6a1f1dSLionel Sambuc #endif
152f4a2713aSLionel Sambuc   return false;
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc 
releaseMemory()155*0a6a1f1dSLionel Sambuc void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
156*0a6a1f1dSLionel Sambuc 
157*0a6a1f1dSLionel Sambuc /// Pop up a ghostview window with the current block frequency propagation
158*0a6a1f1dSLionel Sambuc /// rendered using dot.
view() const159*0a6a1f1dSLionel Sambuc void MachineBlockFrequencyInfo::view() const {
160*0a6a1f1dSLionel Sambuc // This code is only for debugging.
161*0a6a1f1dSLionel Sambuc #ifndef NDEBUG
162*0a6a1f1dSLionel Sambuc   ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this),
163*0a6a1f1dSLionel Sambuc             "MachineBlockFrequencyDAGs");
164*0a6a1f1dSLionel Sambuc #else
165*0a6a1f1dSLionel Sambuc   errs() << "MachineBlockFrequencyInfo::view is only available in debug builds "
166*0a6a1f1dSLionel Sambuc     "on systems with Graphviz or gv!\n";
167*0a6a1f1dSLionel Sambuc #endif // NDEBUG
168*0a6a1f1dSLionel Sambuc }
169*0a6a1f1dSLionel Sambuc 
170f4a2713aSLionel Sambuc BlockFrequency MachineBlockFrequencyInfo::
getBlockFreq(const MachineBasicBlock * MBB) const171f4a2713aSLionel Sambuc getBlockFreq(const MachineBasicBlock *MBB) const {
172*0a6a1f1dSLionel Sambuc   return MBFI ? MBFI->getBlockFreq(MBB) : 0;
173*0a6a1f1dSLionel Sambuc }
174*0a6a1f1dSLionel Sambuc 
getFunction() const175*0a6a1f1dSLionel Sambuc const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
176*0a6a1f1dSLionel Sambuc   return MBFI ? MBFI->getFunction() : nullptr;
177*0a6a1f1dSLionel Sambuc }
178*0a6a1f1dSLionel Sambuc 
179*0a6a1f1dSLionel Sambuc raw_ostream &
printBlockFreq(raw_ostream & OS,const BlockFrequency Freq) const180*0a6a1f1dSLionel Sambuc MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
181*0a6a1f1dSLionel Sambuc                                           const BlockFrequency Freq) const {
182*0a6a1f1dSLionel Sambuc   return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
183*0a6a1f1dSLionel Sambuc }
184*0a6a1f1dSLionel Sambuc 
185*0a6a1f1dSLionel Sambuc raw_ostream &
printBlockFreq(raw_ostream & OS,const MachineBasicBlock * MBB) const186*0a6a1f1dSLionel Sambuc MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
187*0a6a1f1dSLionel Sambuc                                           const MachineBasicBlock *MBB) const {
188*0a6a1f1dSLionel Sambuc   return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
189*0a6a1f1dSLionel Sambuc }
190*0a6a1f1dSLionel Sambuc 
getEntryFreq() const191*0a6a1f1dSLionel Sambuc uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
192*0a6a1f1dSLionel Sambuc   return MBFI ? MBFI->getEntryFreq() : 0;
193f4a2713aSLionel Sambuc }
194