1198396Srdivacky//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
2198396Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6198396Srdivacky//
7198396Srdivacky//===----------------------------------------------------------------------===//
8198396Srdivacky//
9198396Srdivacky// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
10198396Srdivacky// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
11198396Srdivacky// program, with a graph of the dominance/postdominance tree of that
12198396Srdivacky// function.
13198396Srdivacky//
14198396Srdivacky// There are also passes available to directly call dotty ('-view-dom' or
15198396Srdivacky// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
16198396Srdivacky// names of the bbs are printed, but the content is hidden.
17198396Srdivacky//
18198396Srdivacky//===----------------------------------------------------------------------===//
19198396Srdivacky
20198396Srdivacky#include "llvm/Analysis/DomPrinter.h"
21202878Srdivacky#include "llvm/Analysis/DOTGraphTraitsPass.h"
22198396Srdivacky#include "llvm/Analysis/PostDominators.h"
23360784Sdim#include "llvm/InitializePasses.h"
24198396Srdivacky
25198396Srdivackyusing namespace llvm;
26198396Srdivacky
27198396Srdivackynamespace llvm {
28198396Srdivackytemplate<>
29198396Srdivackystruct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
30198396Srdivacky
31199989Srdivacky  DOTGraphTraits (bool isSimple=false)
32199989Srdivacky    : DefaultDOTGraphTraits(isSimple) {}
33199989Srdivacky
34199989Srdivacky  std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
35199989Srdivacky
36198396Srdivacky    BasicBlock *BB = Node->getBlock();
37198396Srdivacky
38198396Srdivacky    if (!BB)
39198396Srdivacky      return "Post dominance root node";
40198396Srdivacky
41199989Srdivacky
42199989Srdivacky    if (isSimple())
43199989Srdivacky      return DOTGraphTraits<const Function*>
44210299Sed        ::getSimpleNodeLabel(BB, BB->getParent());
45199989Srdivacky    else
46199989Srdivacky      return DOTGraphTraits<const Function*>
47210299Sed        ::getCompleteNodeLabel(BB, BB->getParent());
48198396Srdivacky  }
49198396Srdivacky};
50198396Srdivacky
51198396Srdivackytemplate<>
52198396Srdivackystruct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
53198396Srdivacky
54199989Srdivacky  DOTGraphTraits (bool isSimple=false)
55199989Srdivacky    : DOTGraphTraits<DomTreeNode*>(isSimple) {}
56199989Srdivacky
57198396Srdivacky  static std::string getGraphName(DominatorTree *DT) {
58198396Srdivacky    return "Dominator tree";
59198396Srdivacky  }
60198396Srdivacky
61199989Srdivacky  std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
62199989Srdivacky    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
63198396Srdivacky  }
64198396Srdivacky};
65198396Srdivacky
66198396Srdivackytemplate<>
67198396Srdivackystruct DOTGraphTraits<PostDominatorTree*>
68198396Srdivacky  : public DOTGraphTraits<DomTreeNode*> {
69199989Srdivacky
70199989Srdivacky  DOTGraphTraits (bool isSimple=false)
71199989Srdivacky    : DOTGraphTraits<DomTreeNode*>(isSimple) {}
72199989Srdivacky
73198396Srdivacky  static std::string getGraphName(PostDominatorTree *DT) {
74198396Srdivacky    return "Post dominator tree";
75198396Srdivacky  }
76199989Srdivacky
77199989Srdivacky  std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
78199989Srdivacky    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
79198396Srdivacky  }
80198396Srdivacky};
81198396Srdivacky}
82198396Srdivacky
83321369Sdimvoid DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
84321369Sdim#ifndef NDEBUG
85321369Sdim  ViewGraph(this, Name, false, Title);
86321369Sdim#else
87321369Sdim  errs() << "DomTree dump not available, build with DEBUG\n";
88321369Sdim#endif  // NDEBUG
89321369Sdim}
90321369Sdim
91321369Sdimvoid DominatorTree::viewGraph() {
92321369Sdim#ifndef NDEBUG
93321369Sdim  this->viewGraph("domtree", "Dominator Tree for function");
94321369Sdim#else
95321369Sdim  errs() << "DomTree dump not available, build with DEBUG\n";
96321369Sdim#endif  // NDEBUG
97321369Sdim}
98321369Sdim
99198396Srdivackynamespace {
100276479Sdimstruct DominatorTreeWrapperPassAnalysisGraphTraits {
101276479Sdim  static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
102276479Sdim    return &DTWP->getDomTree();
103276479Sdim  }
104276479Sdim};
105276479Sdim
106276479Sdimstruct DomViewer : public DOTGraphTraitsViewer<
107276479Sdim                       DominatorTreeWrapperPass, false, DominatorTree *,
108276479Sdim                       DominatorTreeWrapperPassAnalysisGraphTraits> {
109198396Srdivacky  static char ID;
110276479Sdim  DomViewer()
111276479Sdim      : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
112276479Sdim                             DominatorTreeWrapperPassAnalysisGraphTraits>(
113276479Sdim            "dom", ID) {
114218893Sdim    initializeDomViewerPass(*PassRegistry::getPassRegistry());
115218893Sdim  }
116198396Srdivacky};
117198396Srdivacky
118276479Sdimstruct DomOnlyViewer : public DOTGraphTraitsViewer<
119276479Sdim                           DominatorTreeWrapperPass, true, DominatorTree *,
120276479Sdim                           DominatorTreeWrapperPassAnalysisGraphTraits> {
121198396Srdivacky  static char ID;
122276479Sdim  DomOnlyViewer()
123276479Sdim      : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
124276479Sdim                             DominatorTreeWrapperPassAnalysisGraphTraits>(
125276479Sdim            "domonly", ID) {
126218893Sdim    initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
127218893Sdim  }
128198396Srdivacky};
129198396Srdivacky
130309124Sdimstruct PostDominatorTreeWrapperPassAnalysisGraphTraits {
131309124Sdim  static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
132309124Sdim    return &PDTWP->getPostDomTree();
133309124Sdim  }
134309124Sdim};
135309124Sdim
136309124Sdimstruct PostDomViewer : public DOTGraphTraitsViewer<
137309124Sdim                          PostDominatorTreeWrapperPass, false,
138309124Sdim                          PostDominatorTree *,
139309124Sdim                          PostDominatorTreeWrapperPassAnalysisGraphTraits> {
140198396Srdivacky  static char ID;
141198396Srdivacky  PostDomViewer() :
142309124Sdim    DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
143309124Sdim                         PostDominatorTree *,
144309124Sdim                         PostDominatorTreeWrapperPassAnalysisGraphTraits>(
145309124Sdim        "postdom", ID){
146218893Sdim      initializePostDomViewerPass(*PassRegistry::getPassRegistry());
147218893Sdim    }
148198396Srdivacky};
149198396Srdivacky
150309124Sdimstruct PostDomOnlyViewer : public DOTGraphTraitsViewer<
151309124Sdim                            PostDominatorTreeWrapperPass, true,
152309124Sdim                            PostDominatorTree *,
153309124Sdim                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
154198396Srdivacky  static char ID;
155198396Srdivacky  PostDomOnlyViewer() :
156309124Sdim    DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
157309124Sdim                         PostDominatorTree *,
158309124Sdim                         PostDominatorTreeWrapperPassAnalysisGraphTraits>(
159309124Sdim        "postdomonly", ID){
160218893Sdim      initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
161218893Sdim    }
162198396Srdivacky};
163198396Srdivacky} // end anonymous namespace
164198396Srdivacky
165198396Srdivackychar DomViewer::ID = 0;
166212904SdimINITIALIZE_PASS(DomViewer, "view-dom",
167218893Sdim                "View dominance tree of function", false, false)
168198396Srdivacky
169198396Srdivackychar DomOnlyViewer::ID = 0;
170212904SdimINITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
171212904Sdim                "View dominance tree of function (with no function bodies)",
172218893Sdim                false, false)
173198396Srdivacky
174198396Srdivackychar PostDomViewer::ID = 0;
175212904SdimINITIALIZE_PASS(PostDomViewer, "view-postdom",
176218893Sdim                "View postdominance tree of function", false, false)
177198396Srdivacky
178198396Srdivackychar PostDomOnlyViewer::ID = 0;
179212904SdimINITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
180212904Sdim                "View postdominance tree of function "
181212904Sdim                "(with no function bodies)",
182218893Sdim                false, false)
183198396Srdivacky
184198396Srdivackynamespace {
185276479Sdimstruct DomPrinter : public DOTGraphTraitsPrinter<
186276479Sdim                        DominatorTreeWrapperPass, false, DominatorTree *,
187276479Sdim                        DominatorTreeWrapperPassAnalysisGraphTraits> {
188198396Srdivacky  static char ID;
189276479Sdim  DomPrinter()
190276479Sdim      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
191276479Sdim                              DominatorTreeWrapperPassAnalysisGraphTraits>(
192276479Sdim            "dom", ID) {
193218893Sdim    initializeDomPrinterPass(*PassRegistry::getPassRegistry());
194218893Sdim  }
195198396Srdivacky};
196198396Srdivacky
197276479Sdimstruct DomOnlyPrinter : public DOTGraphTraitsPrinter<
198276479Sdim                            DominatorTreeWrapperPass, true, DominatorTree *,
199276479Sdim                            DominatorTreeWrapperPassAnalysisGraphTraits> {
200198396Srdivacky  static char ID;
201276479Sdim  DomOnlyPrinter()
202276479Sdim      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
203276479Sdim                              DominatorTreeWrapperPassAnalysisGraphTraits>(
204276479Sdim            "domonly", ID) {
205218893Sdim    initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
206218893Sdim  }
207198396Srdivacky};
208198396Srdivacky
209198396Srdivackystruct PostDomPrinter
210309124Sdim  : public DOTGraphTraitsPrinter<
211309124Sdim                            PostDominatorTreeWrapperPass, false,
212309124Sdim                            PostDominatorTree *,
213309124Sdim                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
214198396Srdivacky  static char ID;
215198396Srdivacky  PostDomPrinter() :
216309124Sdim    DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
217309124Sdim                          PostDominatorTree *,
218309124Sdim                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
219309124Sdim        "postdom", ID) {
220218893Sdim      initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
221218893Sdim    }
222198396Srdivacky};
223198396Srdivacky
224198396Srdivackystruct PostDomOnlyPrinter
225309124Sdim  : public DOTGraphTraitsPrinter<
226309124Sdim                            PostDominatorTreeWrapperPass, true,
227309124Sdim                            PostDominatorTree *,
228309124Sdim                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
229198396Srdivacky  static char ID;
230198396Srdivacky  PostDomOnlyPrinter() :
231309124Sdim    DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
232309124Sdim                          PostDominatorTree *,
233309124Sdim                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
234309124Sdim        "postdomonly", ID) {
235218893Sdim      initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
236218893Sdim    }
237198396Srdivacky};
238198396Srdivacky} // end anonymous namespace
239198396Srdivacky
240198396Srdivacky
241198396Srdivacky
242198396Srdivackychar DomPrinter::ID = 0;
243212904SdimINITIALIZE_PASS(DomPrinter, "dot-dom",
244212904Sdim                "Print dominance tree of function to 'dot' file",
245218893Sdim                false, false)
246198396Srdivacky
247198396Srdivackychar DomOnlyPrinter::ID = 0;
248212904SdimINITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
249212904Sdim                "Print dominance tree of function to 'dot' file "
250212904Sdim                "(with no function bodies)",
251218893Sdim                false, false)
252198396Srdivacky
253198396Srdivackychar PostDomPrinter::ID = 0;
254212904SdimINITIALIZE_PASS(PostDomPrinter, "dot-postdom",
255212904Sdim                "Print postdominance tree of function to 'dot' file",
256218893Sdim                false, false)
257198396Srdivacky
258198396Srdivackychar PostDomOnlyPrinter::ID = 0;
259212904SdimINITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
260212904Sdim                "Print postdominance tree of function to 'dot' file "
261212904Sdim                "(with no function bodies)",
262218893Sdim                false, false)
263198396Srdivacky
264198396Srdivacky// Create methods available outside of this file, to use them
265198396Srdivacky// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
266198396Srdivacky// the link time optimization.
267198396Srdivacky
268198396SrdivackyFunctionPass *llvm::createDomPrinterPass() {
269198396Srdivacky  return new DomPrinter();
270198396Srdivacky}
271198396Srdivacky
272198396SrdivackyFunctionPass *llvm::createDomOnlyPrinterPass() {
273198396Srdivacky  return new DomOnlyPrinter();
274198396Srdivacky}
275198396Srdivacky
276198396SrdivackyFunctionPass *llvm::createDomViewerPass() {
277198396Srdivacky  return new DomViewer();
278198396Srdivacky}
279198396Srdivacky
280198396SrdivackyFunctionPass *llvm::createDomOnlyViewerPass() {
281198396Srdivacky  return new DomOnlyViewer();
282198396Srdivacky}
283198396Srdivacky
284198396SrdivackyFunctionPass *llvm::createPostDomPrinterPass() {
285198396Srdivacky  return new PostDomPrinter();
286198396Srdivacky}
287198396Srdivacky
288198396SrdivackyFunctionPass *llvm::createPostDomOnlyPrinterPass() {
289198396Srdivacky  return new PostDomOnlyPrinter();
290198396Srdivacky}
291198396Srdivacky
292198396SrdivackyFunctionPass *llvm::createPostDomViewerPass() {
293198396Srdivacky  return new PostDomViewer();
294198396Srdivacky}
295198396Srdivacky
296198396SrdivackyFunctionPass *llvm::createPostDomOnlyViewerPass() {
297198396Srdivacky  return new PostDomOnlyViewer();
298198396Srdivacky}
299