DomPrinter.cpp revision 353358
1//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
10// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
11// program, with a graph of the dominance/postdominance tree of that
12// function.
13//
14// There are also passes available to directly call dotty ('-view-dom' or
15// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
16// names of the bbs are printed, but the content is hidden.
17//
18//===----------------------------------------------------------------------===//
19
20#include "llvm/Analysis/DomPrinter.h"
21#include "llvm/Analysis/DOTGraphTraitsPass.h"
22#include "llvm/Analysis/PostDominators.h"
23
24using namespace llvm;
25
26namespace llvm {
27template<>
28struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
29
30  DOTGraphTraits (bool isSimple=false)
31    : DefaultDOTGraphTraits(isSimple) {}
32
33  std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
34
35    BasicBlock *BB = Node->getBlock();
36
37    if (!BB)
38      return "Post dominance root node";
39
40
41    if (isSimple())
42      return DOTGraphTraits<const Function*>
43        ::getSimpleNodeLabel(BB, BB->getParent());
44    else
45      return DOTGraphTraits<const Function*>
46        ::getCompleteNodeLabel(BB, BB->getParent());
47  }
48};
49
50template<>
51struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
52
53  DOTGraphTraits (bool isSimple=false)
54    : DOTGraphTraits<DomTreeNode*>(isSimple) {}
55
56  static std::string getGraphName(DominatorTree *DT) {
57    return "Dominator tree";
58  }
59
60  std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
61    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
62  }
63};
64
65template<>
66struct DOTGraphTraits<PostDominatorTree*>
67  : public DOTGraphTraits<DomTreeNode*> {
68
69  DOTGraphTraits (bool isSimple=false)
70    : DOTGraphTraits<DomTreeNode*>(isSimple) {}
71
72  static std::string getGraphName(PostDominatorTree *DT) {
73    return "Post dominator tree";
74  }
75
76  std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
77    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
78  }
79};
80}
81
82void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
83#ifndef NDEBUG
84  ViewGraph(this, Name, false, Title);
85#else
86  errs() << "DomTree dump not available, build with DEBUG\n";
87#endif  // NDEBUG
88}
89
90void DominatorTree::viewGraph() {
91#ifndef NDEBUG
92  this->viewGraph("domtree", "Dominator Tree for function");
93#else
94  errs() << "DomTree dump not available, build with DEBUG\n";
95#endif  // NDEBUG
96}
97
98namespace {
99struct DominatorTreeWrapperPassAnalysisGraphTraits {
100  static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
101    return &DTWP->getDomTree();
102  }
103};
104
105struct DomViewer : public DOTGraphTraitsViewer<
106                       DominatorTreeWrapperPass, false, DominatorTree *,
107                       DominatorTreeWrapperPassAnalysisGraphTraits> {
108  static char ID;
109  DomViewer()
110      : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
111                             DominatorTreeWrapperPassAnalysisGraphTraits>(
112            "dom", ID) {
113    initializeDomViewerPass(*PassRegistry::getPassRegistry());
114  }
115};
116
117struct DomOnlyViewer : public DOTGraphTraitsViewer<
118                           DominatorTreeWrapperPass, true, DominatorTree *,
119                           DominatorTreeWrapperPassAnalysisGraphTraits> {
120  static char ID;
121  DomOnlyViewer()
122      : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
123                             DominatorTreeWrapperPassAnalysisGraphTraits>(
124            "domonly", ID) {
125    initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
126  }
127};
128
129struct PostDominatorTreeWrapperPassAnalysisGraphTraits {
130  static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
131    return &PDTWP->getPostDomTree();
132  }
133};
134
135struct PostDomViewer : public DOTGraphTraitsViewer<
136                          PostDominatorTreeWrapperPass, false,
137                          PostDominatorTree *,
138                          PostDominatorTreeWrapperPassAnalysisGraphTraits> {
139  static char ID;
140  PostDomViewer() :
141    DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
142                         PostDominatorTree *,
143                         PostDominatorTreeWrapperPassAnalysisGraphTraits>(
144        "postdom", ID){
145      initializePostDomViewerPass(*PassRegistry::getPassRegistry());
146    }
147};
148
149struct PostDomOnlyViewer : public DOTGraphTraitsViewer<
150                            PostDominatorTreeWrapperPass, true,
151                            PostDominatorTree *,
152                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
153  static char ID;
154  PostDomOnlyViewer() :
155    DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
156                         PostDominatorTree *,
157                         PostDominatorTreeWrapperPassAnalysisGraphTraits>(
158        "postdomonly", ID){
159      initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
160    }
161};
162} // end anonymous namespace
163
164char DomViewer::ID = 0;
165INITIALIZE_PASS(DomViewer, "view-dom",
166                "View dominance tree of function", false, false)
167
168char DomOnlyViewer::ID = 0;
169INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
170                "View dominance tree of function (with no function bodies)",
171                false, false)
172
173char PostDomViewer::ID = 0;
174INITIALIZE_PASS(PostDomViewer, "view-postdom",
175                "View postdominance tree of function", false, false)
176
177char PostDomOnlyViewer::ID = 0;
178INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
179                "View postdominance tree of function "
180                "(with no function bodies)",
181                false, false)
182
183namespace {
184struct DomPrinter : public DOTGraphTraitsPrinter<
185                        DominatorTreeWrapperPass, false, DominatorTree *,
186                        DominatorTreeWrapperPassAnalysisGraphTraits> {
187  static char ID;
188  DomPrinter()
189      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
190                              DominatorTreeWrapperPassAnalysisGraphTraits>(
191            "dom", ID) {
192    initializeDomPrinterPass(*PassRegistry::getPassRegistry());
193  }
194};
195
196struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
197                            DominatorTreeWrapperPass, true, DominatorTree *,
198                            DominatorTreeWrapperPassAnalysisGraphTraits> {
199  static char ID;
200  DomOnlyPrinter()
201      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
202                              DominatorTreeWrapperPassAnalysisGraphTraits>(
203            "domonly", ID) {
204    initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
205  }
206};
207
208struct PostDomPrinter
209  : public DOTGraphTraitsPrinter<
210                            PostDominatorTreeWrapperPass, false,
211                            PostDominatorTree *,
212                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
213  static char ID;
214  PostDomPrinter() :
215    DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
216                          PostDominatorTree *,
217                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
218        "postdom", ID) {
219      initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
220    }
221};
222
223struct PostDomOnlyPrinter
224  : public DOTGraphTraitsPrinter<
225                            PostDominatorTreeWrapperPass, true,
226                            PostDominatorTree *,
227                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
228  static char ID;
229  PostDomOnlyPrinter() :
230    DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
231                          PostDominatorTree *,
232                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
233        "postdomonly", ID) {
234      initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
235    }
236};
237} // end anonymous namespace
238
239
240
241char DomPrinter::ID = 0;
242INITIALIZE_PASS(DomPrinter, "dot-dom",
243                "Print dominance tree of function to 'dot' file",
244                false, false)
245
246char DomOnlyPrinter::ID = 0;
247INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
248                "Print dominance tree of function to 'dot' file "
249                "(with no function bodies)",
250                false, false)
251
252char PostDomPrinter::ID = 0;
253INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
254                "Print postdominance tree of function to 'dot' file",
255                false, false)
256
257char PostDomOnlyPrinter::ID = 0;
258INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
259                "Print postdominance tree of function to 'dot' file "
260                "(with no function bodies)",
261                false, false)
262
263// Create methods available outside of this file, to use them
264// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
265// the link time optimization.
266
267FunctionPass *llvm::createDomPrinterPass() {
268  return new DomPrinter();
269}
270
271FunctionPass *llvm::createDomOnlyPrinterPass() {
272  return new DomOnlyPrinter();
273}
274
275FunctionPass *llvm::createDomViewerPass() {
276  return new DomViewer();
277}
278
279FunctionPass *llvm::createDomOnlyViewerPass() {
280  return new DomOnlyViewer();
281}
282
283FunctionPass *llvm::createPostDomPrinterPass() {
284  return new PostDomPrinter();
285}
286
287FunctionPass *llvm::createPostDomOnlyPrinterPass() {
288  return new PostDomOnlyPrinter();
289}
290
291FunctionPass *llvm::createPostDomViewerPass() {
292  return new PostDomViewer();
293}
294
295FunctionPass *llvm::createPostDomOnlyViewerPass() {
296  return new PostDomOnlyViewer();
297}
298