DomPrinter.cpp revision 198396
1189251Ssam//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
2189251Ssam//
3189251Ssam//                     The LLVM Compiler Infrastructure
4189251Ssam//
5252726Srpaulo// This file is distributed under the University of Illinois Open Source
6252726Srpaulo// License. See LICENSE.TXT for details.
7189251Ssam//
8189251Ssam//===----------------------------------------------------------------------===//
9189251Ssam//
10189251Ssam// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
11189251Ssam// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
12189251Ssam// program, with a graph of the dominance/postdominance tree of that
13189251Ssam// function.
14189251Ssam//
15189251Ssam// There are also passes available to directly call dotty ('-view-dom' or
16189251Ssam// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
17189251Ssam// names of the bbs are printed, but the content is hidden.
18189251Ssam//
19189251Ssam//===----------------------------------------------------------------------===//
20189251Ssam
21189251Ssam#include "llvm/Analysis/DomPrinter.h"
22189251Ssam#include "llvm/Pass.h"
23189251Ssam#include "llvm/Function.h"
24189251Ssam#include "llvm/Analysis/CFGPrinter.h"
25189251Ssam#include "llvm/Analysis/Dominators.h"
26189251Ssam#include "llvm/Analysis/PostDominators.h"
27189251Ssam
28189251Ssamusing namespace llvm;
29189251Ssam
30189251Ssamnamespace llvm {
31189251Ssamtemplate<>
32189251Ssamstruct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
33189251Ssam  static std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph,
34189251Ssam                                  bool ShortNames) {
35189251Ssam
36189251Ssam    BasicBlock *BB = Node->getBlock();
37214734Srpaulo
38189251Ssam    if (!BB)
39189251Ssam      return "Post dominance root node";
40189251Ssam
41189251Ssam    return DOTGraphTraits<const Function*>::getNodeLabel(BB, BB->getParent(),
42189251Ssam                                                         ShortNames);
43189251Ssam  }
44189251Ssam};
45189251Ssam
46189251Ssamtemplate<>
47189251Ssamstruct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
48189251Ssam
49189251Ssam  static std::string getGraphName(DominatorTree *DT) {
50189251Ssam    return "Dominator tree";
51189251Ssam  }
52189251Ssam
53209158Srpaulo  static std::string getNodeLabel(DomTreeNode *Node,
54209158Srpaulo                                  DominatorTree *G,
55209158Srpaulo                                  bool ShortNames) {
56209158Srpaulo    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode(),
57189251Ssam                                                      ShortNames);
58189251Ssam  }
59189251Ssam};
60209158Srpaulo
61189251Ssamtemplate<>
62189251Ssamstruct DOTGraphTraits<PostDominatorTree*>
63189251Ssam  : public DOTGraphTraits<DomTreeNode*> {
64189251Ssam  static std::string getGraphName(PostDominatorTree *DT) {
65189251Ssam    return "Post dominator tree";
66189251Ssam  }
67189251Ssam  static std::string getNodeLabel(DomTreeNode *Node,
68189251Ssam                                  PostDominatorTree *G,
69189251Ssam                                  bool ShortNames) {
70189251Ssam    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node,
71189251Ssam                                                      G->getRootNode(),
72189251Ssam                                                      ShortNames);
73189251Ssam  }
74189251Ssam};
75189251Ssam}
76189251Ssam
77189251Ssamnamespace {
78189251Ssamtemplate <class Analysis, bool OnlyBBS>
79189251Ssamstruct GenericGraphViewer : public FunctionPass {
80189251Ssam  std::string Name;
81189251Ssam
82189251Ssam  GenericGraphViewer(std::string GraphName, const void *ID) : FunctionPass(ID) {
83189251Ssam    Name = GraphName;
84189251Ssam  }
85189251Ssam
86189251Ssam  virtual bool runOnFunction(Function &F) {
87189251Ssam    Analysis *Graph;
88189251Ssam
89189251Ssam    Graph = &getAnalysis<Analysis>();
90189251Ssam    ViewGraph(Graph, Name, OnlyBBS);
91189251Ssam
92189251Ssam    return false;
93189251Ssam  }
94189251Ssam
95189251Ssam  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
96189251Ssam    AU.setPreservesAll();
97189251Ssam    AU.addRequired<Analysis>();
98189251Ssam  }
99189251Ssam};
100189251Ssam
101189251Ssamstruct DomViewer
102189251Ssam  : public GenericGraphViewer<DominatorTree, false> {
103189251Ssam  static char ID;
104189251Ssam  DomViewer() : GenericGraphViewer<DominatorTree, false>("dom", &ID){}
105189251Ssam};
106189251Ssam
107189251Ssamstruct DomOnlyViewer
108189251Ssam  : public GenericGraphViewer<DominatorTree, true> {
109189251Ssam  static char ID;
110189251Ssam  DomOnlyViewer() : GenericGraphViewer<DominatorTree, true>("domonly", &ID){}
111189251Ssam};
112189251Ssam
113189251Ssamstruct PostDomViewer
114189251Ssam  : public GenericGraphViewer<PostDominatorTree, false> {
115189251Ssam  static char ID;
116189251Ssam  PostDomViewer() :
117189251Ssam    GenericGraphViewer<PostDominatorTree, false>("postdom", &ID){}
118189251Ssam};
119189251Ssam
120189251Ssamstruct PostDomOnlyViewer
121189251Ssam  : public GenericGraphViewer<PostDominatorTree, true> {
122189251Ssam  static char ID;
123189251Ssam  PostDomOnlyViewer() :
124189251Ssam    GenericGraphViewer<PostDominatorTree, true>("postdomonly", &ID){}
125189251Ssam};
126189251Ssam} // end anonymous namespace
127189251Ssam
128189251Ssamchar DomViewer::ID = 0;
129189251SsamRegisterPass<DomViewer> A("view-dom",
130189251Ssam                          "View dominance tree of function");
131189251Ssam
132189251Ssamchar DomOnlyViewer::ID = 0;
133189251SsamRegisterPass<DomOnlyViewer> B("view-dom-only",
134189251Ssam                              "View dominance tree of function "
135189251Ssam                              "(with no function bodies)");
136189251Ssam
137189251Ssamchar PostDomViewer::ID = 0;
138189251SsamRegisterPass<PostDomViewer> C("view-postdom",
139189251Ssam                              "View postdominance tree of function");
140189251Ssam
141189251Ssamchar PostDomOnlyViewer::ID = 0;
142189251SsamRegisterPass<PostDomOnlyViewer> D("view-postdom-only",
143189251Ssam                                  "View postdominance tree of function "
144189251Ssam                                  "(with no function bodies)");
145189251Ssam
146189251Ssamnamespace {
147189251Ssamtemplate <class Analysis, bool OnlyBBS>
148189251Ssamstruct GenericGraphPrinter : public FunctionPass {
149189251Ssam
150189251Ssam  std::string Name;
151189251Ssam
152189251Ssam  GenericGraphPrinter(std::string GraphName, const void *ID)
153189251Ssam    : FunctionPass(ID) {
154189251Ssam    Name = GraphName;
155189251Ssam  }
156189251Ssam
157189251Ssam  virtual bool runOnFunction(Function &F) {
158189251Ssam    Analysis *Graph;
159189251Ssam    std::string Filename = Name + "." + F.getNameStr() + ".dot";
160189251Ssam    errs() << "Writing '" << Filename << "'...";
161189251Ssam
162189251Ssam    std::string ErrorInfo;
163189251Ssam    raw_fd_ostream File(Filename.c_str(), ErrorInfo);
164189251Ssam    Graph = &getAnalysis<Analysis>();
165189251Ssam
166189251Ssam    if (ErrorInfo.empty())
167189251Ssam      WriteGraph(File, Graph, OnlyBBS);
168189251Ssam    else
169189251Ssam      errs() << "  error opening file for writing!";
170189251Ssam    errs() << "\n";
171189251Ssam    return false;
172189251Ssam  }
173189251Ssam
174189251Ssam  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
175189251Ssam    AU.setPreservesAll();
176189251Ssam    AU.addRequired<Analysis>();
177189251Ssam  }
178189251Ssam};
179189251Ssam
180189251Ssamstruct DomPrinter
181189251Ssam  : public GenericGraphPrinter<DominatorTree, false> {
182189251Ssam  static char ID;
183189251Ssam  DomPrinter() : GenericGraphPrinter<DominatorTree, false>("dom", &ID) {}
184189251Ssam};
185189251Ssam
186189251Ssamstruct DomOnlyPrinter
187189251Ssam  : public GenericGraphPrinter<DominatorTree, true> {
188189251Ssam  static char ID;
189189251Ssam  DomOnlyPrinter() : GenericGraphPrinter<DominatorTree, true>("domonly", &ID) {}
190189251Ssam};
191189251Ssam
192189251Ssamstruct PostDomPrinter
193189251Ssam  : public GenericGraphPrinter<PostDominatorTree, false> {
194189251Ssam  static char ID;
195189251Ssam  PostDomPrinter() :
196189251Ssam    GenericGraphPrinter<PostDominatorTree, false>("postdom", &ID) {}
197189251Ssam};
198189251Ssam
199189251Ssamstruct PostDomOnlyPrinter
200189251Ssam  : public GenericGraphPrinter<PostDominatorTree, true> {
201189251Ssam  static char ID;
202189251Ssam  PostDomOnlyPrinter() :
203189251Ssam    GenericGraphPrinter<PostDominatorTree, true>("postdomonly", &ID) {}
204189251Ssam};
205189251Ssam} // end anonymous namespace
206189251Ssam
207189251Ssam
208189251Ssam
209189251Ssamchar DomPrinter::ID = 0;
210189251SsamRegisterPass<DomPrinter> E("dot-dom",
211189251Ssam                           "Print dominance tree of function "
212189251Ssam                           "to 'dot' file");
213189251Ssam
214189251Ssamchar DomOnlyPrinter::ID = 0;
215189251SsamRegisterPass<DomOnlyPrinter> F("dot-dom-only",
216189251Ssam                               "Print dominance tree of function "
217189251Ssam                               "to 'dot' file "
218189251Ssam                               "(with no function bodies)");
219189251Ssam
220189251Ssamchar PostDomPrinter::ID = 0;
221189251SsamRegisterPass<PostDomPrinter> G("dot-postdom",
222189251Ssam                               "Print postdominance tree of function "
223189251Ssam                               "to 'dot' file");
224189251Ssam
225189251Ssamchar PostDomOnlyPrinter::ID = 0;
226189251SsamRegisterPass<PostDomOnlyPrinter> H("dot-postdom-only",
227189251Ssam                                   "Print postdominance tree of function "
228189251Ssam                                   "to 'dot' file "
229189251Ssam                                   "(with no function bodies)");
230189251Ssam
231189251Ssam// Create methods available outside of this file, to use them
232189251Ssam// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
233189251Ssam// the link time optimization.
234189251Ssam
235189251SsamFunctionPass *llvm::createDomPrinterPass() {
236189251Ssam  return new DomPrinter();
237189251Ssam}
238189251Ssam
239189251SsamFunctionPass *llvm::createDomOnlyPrinterPass() {
240189251Ssam  return new DomOnlyPrinter();
241189251Ssam}
242189251Ssam
243189251SsamFunctionPass *llvm::createDomViewerPass() {
244189251Ssam  return new DomViewer();
245189251Ssam}
246189251Ssam
247189251SsamFunctionPass *llvm::createDomOnlyViewerPass() {
248189251Ssam  return new DomOnlyViewer();
249189251Ssam}
250189251Ssam
251189251SsamFunctionPass *llvm::createPostDomPrinterPass() {
252189251Ssam  return new PostDomPrinter();
253189251Ssam}
254189251Ssam
255189251SsamFunctionPass *llvm::createPostDomOnlyPrinterPass() {
256189251Ssam  return new PostDomOnlyPrinter();
257189251Ssam}
258189251Ssam
259189251SsamFunctionPass *llvm::createPostDomViewerPass() {
260189251Ssam  return new PostDomViewer();
261189251Ssam}
262189251Ssam
263189251SsamFunctionPass *llvm::createPostDomOnlyViewerPass() {
264189251Ssam  return new PostDomOnlyViewer();
265189251Ssam}
266189251Ssam