DomPrinter.cpp revision 198396
1198396Srdivacky//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
2198396Srdivacky//
3198396Srdivacky//                     The LLVM Compiler Infrastructure
4198396Srdivacky//
5198396Srdivacky// This file is distributed under the University of Illinois Open Source
6198396Srdivacky// License. See LICENSE.TXT for details.
7198396Srdivacky//
8198396Srdivacky//===----------------------------------------------------------------------===//
9198396Srdivacky//
10198396Srdivacky// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
11198396Srdivacky// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
12198396Srdivacky// program, with a graph of the dominance/postdominance tree of that
13198396Srdivacky// function.
14198396Srdivacky//
15198396Srdivacky// There are also passes available to directly call dotty ('-view-dom' or
16198396Srdivacky// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
17198396Srdivacky// names of the bbs are printed, but the content is hidden.
18198396Srdivacky//
19198396Srdivacky//===----------------------------------------------------------------------===//
20198396Srdivacky
21198396Srdivacky#include "llvm/Analysis/DomPrinter.h"
22198396Srdivacky#include "llvm/Pass.h"
23198396Srdivacky#include "llvm/Function.h"
24198396Srdivacky#include "llvm/Analysis/CFGPrinter.h"
25198396Srdivacky#include "llvm/Analysis/Dominators.h"
26198396Srdivacky#include "llvm/Analysis/PostDominators.h"
27198396Srdivacky
28198396Srdivackyusing namespace llvm;
29198396Srdivacky
30198396Srdivackynamespace llvm {
31198396Srdivackytemplate<>
32198396Srdivackystruct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
33198396Srdivacky  static std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph,
34198396Srdivacky                                  bool ShortNames) {
35198396Srdivacky
36198396Srdivacky    BasicBlock *BB = Node->getBlock();
37198396Srdivacky
38198396Srdivacky    if (!BB)
39198396Srdivacky      return "Post dominance root node";
40198396Srdivacky
41198396Srdivacky    return DOTGraphTraits<const Function*>::getNodeLabel(BB, BB->getParent(),
42198396Srdivacky                                                         ShortNames);
43198396Srdivacky  }
44198396Srdivacky};
45198396Srdivacky
46198396Srdivackytemplate<>
47198396Srdivackystruct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
48198396Srdivacky
49198396Srdivacky  static std::string getGraphName(DominatorTree *DT) {
50198396Srdivacky    return "Dominator tree";
51198396Srdivacky  }
52198396Srdivacky
53198396Srdivacky  static std::string getNodeLabel(DomTreeNode *Node,
54198396Srdivacky                                  DominatorTree *G,
55198396Srdivacky                                  bool ShortNames) {
56198396Srdivacky    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode(),
57198396Srdivacky                                                      ShortNames);
58198396Srdivacky  }
59198396Srdivacky};
60198396Srdivacky
61198396Srdivackytemplate<>
62198396Srdivackystruct DOTGraphTraits<PostDominatorTree*>
63198396Srdivacky  : public DOTGraphTraits<DomTreeNode*> {
64198396Srdivacky  static std::string getGraphName(PostDominatorTree *DT) {
65198396Srdivacky    return "Post dominator tree";
66198396Srdivacky  }
67198396Srdivacky  static std::string getNodeLabel(DomTreeNode *Node,
68198396Srdivacky                                  PostDominatorTree *G,
69198396Srdivacky                                  bool ShortNames) {
70198396Srdivacky    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node,
71198396Srdivacky                                                      G->getRootNode(),
72198396Srdivacky                                                      ShortNames);
73198396Srdivacky  }
74198396Srdivacky};
75198396Srdivacky}
76198396Srdivacky
77198396Srdivackynamespace {
78198396Srdivackytemplate <class Analysis, bool OnlyBBS>
79198396Srdivackystruct GenericGraphViewer : public FunctionPass {
80198396Srdivacky  std::string Name;
81198396Srdivacky
82198396Srdivacky  GenericGraphViewer(std::string GraphName, const void *ID) : FunctionPass(ID) {
83198396Srdivacky    Name = GraphName;
84198396Srdivacky  }
85198396Srdivacky
86198396Srdivacky  virtual bool runOnFunction(Function &F) {
87198396Srdivacky    Analysis *Graph;
88198396Srdivacky
89198396Srdivacky    Graph = &getAnalysis<Analysis>();
90198396Srdivacky    ViewGraph(Graph, Name, OnlyBBS);
91198396Srdivacky
92198396Srdivacky    return false;
93198396Srdivacky  }
94198396Srdivacky
95198396Srdivacky  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
96198396Srdivacky    AU.setPreservesAll();
97198396Srdivacky    AU.addRequired<Analysis>();
98198396Srdivacky  }
99198396Srdivacky};
100198396Srdivacky
101198396Srdivackystruct DomViewer
102198396Srdivacky  : public GenericGraphViewer<DominatorTree, false> {
103198396Srdivacky  static char ID;
104198396Srdivacky  DomViewer() : GenericGraphViewer<DominatorTree, false>("dom", &ID){}
105198396Srdivacky};
106198396Srdivacky
107198396Srdivackystruct DomOnlyViewer
108198396Srdivacky  : public GenericGraphViewer<DominatorTree, true> {
109198396Srdivacky  static char ID;
110198396Srdivacky  DomOnlyViewer() : GenericGraphViewer<DominatorTree, true>("domonly", &ID){}
111198396Srdivacky};
112198396Srdivacky
113198396Srdivackystruct PostDomViewer
114198396Srdivacky  : public GenericGraphViewer<PostDominatorTree, false> {
115198396Srdivacky  static char ID;
116198396Srdivacky  PostDomViewer() :
117198396Srdivacky    GenericGraphViewer<PostDominatorTree, false>("postdom", &ID){}
118198396Srdivacky};
119198396Srdivacky
120198396Srdivackystruct PostDomOnlyViewer
121198396Srdivacky  : public GenericGraphViewer<PostDominatorTree, true> {
122198396Srdivacky  static char ID;
123198396Srdivacky  PostDomOnlyViewer() :
124198396Srdivacky    GenericGraphViewer<PostDominatorTree, true>("postdomonly", &ID){}
125198396Srdivacky};
126198396Srdivacky} // end anonymous namespace
127198396Srdivacky
128198396Srdivackychar DomViewer::ID = 0;
129198396SrdivackyRegisterPass<DomViewer> A("view-dom",
130198396Srdivacky                          "View dominance tree of function");
131198396Srdivacky
132198396Srdivackychar DomOnlyViewer::ID = 0;
133198396SrdivackyRegisterPass<DomOnlyViewer> B("view-dom-only",
134198396Srdivacky                              "View dominance tree of function "
135198396Srdivacky                              "(with no function bodies)");
136198396Srdivacky
137198396Srdivackychar PostDomViewer::ID = 0;
138198396SrdivackyRegisterPass<PostDomViewer> C("view-postdom",
139198396Srdivacky                              "View postdominance tree of function");
140198396Srdivacky
141198396Srdivackychar PostDomOnlyViewer::ID = 0;
142198396SrdivackyRegisterPass<PostDomOnlyViewer> D("view-postdom-only",
143198396Srdivacky                                  "View postdominance tree of function "
144198396Srdivacky                                  "(with no function bodies)");
145198396Srdivacky
146198396Srdivackynamespace {
147198396Srdivackytemplate <class Analysis, bool OnlyBBS>
148198396Srdivackystruct GenericGraphPrinter : public FunctionPass {
149198396Srdivacky
150198396Srdivacky  std::string Name;
151198396Srdivacky
152198396Srdivacky  GenericGraphPrinter(std::string GraphName, const void *ID)
153198396Srdivacky    : FunctionPass(ID) {
154198396Srdivacky    Name = GraphName;
155198396Srdivacky  }
156198396Srdivacky
157198396Srdivacky  virtual bool runOnFunction(Function &F) {
158198396Srdivacky    Analysis *Graph;
159198396Srdivacky    std::string Filename = Name + "." + F.getNameStr() + ".dot";
160198396Srdivacky    errs() << "Writing '" << Filename << "'...";
161198396Srdivacky
162198396Srdivacky    std::string ErrorInfo;
163198396Srdivacky    raw_fd_ostream File(Filename.c_str(), ErrorInfo);
164198396Srdivacky    Graph = &getAnalysis<Analysis>();
165198396Srdivacky
166198396Srdivacky    if (ErrorInfo.empty())
167198396Srdivacky      WriteGraph(File, Graph, OnlyBBS);
168198396Srdivacky    else
169198396Srdivacky      errs() << "  error opening file for writing!";
170198396Srdivacky    errs() << "\n";
171198396Srdivacky    return false;
172198396Srdivacky  }
173198396Srdivacky
174198396Srdivacky  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
175198396Srdivacky    AU.setPreservesAll();
176198396Srdivacky    AU.addRequired<Analysis>();
177198396Srdivacky  }
178198396Srdivacky};
179198396Srdivacky
180198396Srdivackystruct DomPrinter
181198396Srdivacky  : public GenericGraphPrinter<DominatorTree, false> {
182198396Srdivacky  static char ID;
183198396Srdivacky  DomPrinter() : GenericGraphPrinter<DominatorTree, false>("dom", &ID) {}
184198396Srdivacky};
185198396Srdivacky
186198396Srdivackystruct DomOnlyPrinter
187198396Srdivacky  : public GenericGraphPrinter<DominatorTree, true> {
188198396Srdivacky  static char ID;
189198396Srdivacky  DomOnlyPrinter() : GenericGraphPrinter<DominatorTree, true>("domonly", &ID) {}
190198396Srdivacky};
191198396Srdivacky
192198396Srdivackystruct PostDomPrinter
193198396Srdivacky  : public GenericGraphPrinter<PostDominatorTree, false> {
194198396Srdivacky  static char ID;
195198396Srdivacky  PostDomPrinter() :
196198396Srdivacky    GenericGraphPrinter<PostDominatorTree, false>("postdom", &ID) {}
197198396Srdivacky};
198198396Srdivacky
199198396Srdivackystruct PostDomOnlyPrinter
200198396Srdivacky  : public GenericGraphPrinter<PostDominatorTree, true> {
201198396Srdivacky  static char ID;
202198396Srdivacky  PostDomOnlyPrinter() :
203198396Srdivacky    GenericGraphPrinter<PostDominatorTree, true>("postdomonly", &ID) {}
204198396Srdivacky};
205198396Srdivacky} // end anonymous namespace
206198396Srdivacky
207198396Srdivacky
208198396Srdivacky
209198396Srdivackychar DomPrinter::ID = 0;
210198396SrdivackyRegisterPass<DomPrinter> E("dot-dom",
211198396Srdivacky                           "Print dominance tree of function "
212198396Srdivacky                           "to 'dot' file");
213198396Srdivacky
214198396Srdivackychar DomOnlyPrinter::ID = 0;
215198396SrdivackyRegisterPass<DomOnlyPrinter> F("dot-dom-only",
216198396Srdivacky                               "Print dominance tree of function "
217198396Srdivacky                               "to 'dot' file "
218198396Srdivacky                               "(with no function bodies)");
219198396Srdivacky
220198396Srdivackychar PostDomPrinter::ID = 0;
221198396SrdivackyRegisterPass<PostDomPrinter> G("dot-postdom",
222198396Srdivacky                               "Print postdominance tree of function "
223198396Srdivacky                               "to 'dot' file");
224198396Srdivacky
225198396Srdivackychar PostDomOnlyPrinter::ID = 0;
226198396SrdivackyRegisterPass<PostDomOnlyPrinter> H("dot-postdom-only",
227198396Srdivacky                                   "Print postdominance tree of function "
228198396Srdivacky                                   "to 'dot' file "
229198396Srdivacky                                   "(with no function bodies)");
230198396Srdivacky
231198396Srdivacky// Create methods available outside of this file, to use them
232198396Srdivacky// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
233198396Srdivacky// the link time optimization.
234198396Srdivacky
235198396SrdivackyFunctionPass *llvm::createDomPrinterPass() {
236198396Srdivacky  return new DomPrinter();
237198396Srdivacky}
238198396Srdivacky
239198396SrdivackyFunctionPass *llvm::createDomOnlyPrinterPass() {
240198396Srdivacky  return new DomOnlyPrinter();
241198396Srdivacky}
242198396Srdivacky
243198396SrdivackyFunctionPass *llvm::createDomViewerPass() {
244198396Srdivacky  return new DomViewer();
245198396Srdivacky}
246198396Srdivacky
247198396SrdivackyFunctionPass *llvm::createDomOnlyViewerPass() {
248198396Srdivacky  return new DomOnlyViewer();
249198396Srdivacky}
250198396Srdivacky
251198396SrdivackyFunctionPass *llvm::createPostDomPrinterPass() {
252198396Srdivacky  return new PostDomPrinter();
253198396Srdivacky}
254198396Srdivacky
255198396SrdivackyFunctionPass *llvm::createPostDomOnlyPrinterPass() {
256198396Srdivacky  return new PostDomOnlyPrinter();
257198396Srdivacky}
258198396Srdivacky
259198396SrdivackyFunctionPass *llvm::createPostDomViewerPass() {
260198396Srdivacky  return new PostDomViewer();
261198396Srdivacky}
262198396Srdivacky
263198396SrdivackyFunctionPass *llvm::createPostDomOnlyViewerPass() {
264198396Srdivacky  return new PostDomOnlyViewer();
265198396Srdivacky}
266