1 //===- DomPrinter.cpp - DOT printer for the dominance trees ------------===//
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
7 //===----------------------------------------------------------------------===//
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
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.
18 //===----------------------------------------------------------------------===//
20 #include "llvm/Analysis/DomPrinter.h"
21 #include "llvm/Analysis/DOTGraphTraitsPass.h"
22 #include "llvm/Analysis/PostDominators.h"
28 struct DOTGraphTraits
<DomTreeNode
*> : public DefaultDOTGraphTraits
{
30 DOTGraphTraits (bool isSimple
=false)
31 : DefaultDOTGraphTraits(isSimple
) {}
33 std::string
getNodeLabel(DomTreeNode
*Node
, DomTreeNode
*Graph
) {
35 BasicBlock
*BB
= Node
->getBlock();
38 return "Post dominance root node";
42 return DOTGraphTraits
<const Function
*>
43 ::getSimpleNodeLabel(BB
, BB
->getParent());
45 return DOTGraphTraits
<const Function
*>
46 ::getCompleteNodeLabel(BB
, BB
->getParent());
51 struct DOTGraphTraits
<DominatorTree
*> : public DOTGraphTraits
<DomTreeNode
*> {
53 DOTGraphTraits (bool isSimple
=false)
54 : DOTGraphTraits
<DomTreeNode
*>(isSimple
) {}
56 static std::string
getGraphName(DominatorTree
*DT
) {
57 return "Dominator tree";
60 std::string
getNodeLabel(DomTreeNode
*Node
, DominatorTree
*G
) {
61 return DOTGraphTraits
<DomTreeNode
*>::getNodeLabel(Node
, G
->getRootNode());
66 struct DOTGraphTraits
<PostDominatorTree
*>
67 : public DOTGraphTraits
<DomTreeNode
*> {
69 DOTGraphTraits (bool isSimple
=false)
70 : DOTGraphTraits
<DomTreeNode
*>(isSimple
) {}
72 static std::string
getGraphName(PostDominatorTree
*DT
) {
73 return "Post dominator tree";
76 std::string
getNodeLabel(DomTreeNode
*Node
, PostDominatorTree
*G
) {
77 return DOTGraphTraits
<DomTreeNode
*>::getNodeLabel(Node
, G
->getRootNode());
82 void DominatorTree::viewGraph(const Twine
&Name
, const Twine
&Title
) {
84 ViewGraph(this, Name
, false, Title
);
86 errs() << "DomTree dump not available, build with DEBUG\n";
90 void DominatorTree::viewGraph() {
92 this->viewGraph("domtree", "Dominator Tree for function");
94 errs() << "DomTree dump not available, build with DEBUG\n";
99 struct DominatorTreeWrapperPassAnalysisGraphTraits
{
100 static DominatorTree
*getGraph(DominatorTreeWrapperPass
*DTWP
) {
101 return &DTWP
->getDomTree();
105 struct DomViewer
: public DOTGraphTraitsViewer
<
106 DominatorTreeWrapperPass
, false, DominatorTree
*,
107 DominatorTreeWrapperPassAnalysisGraphTraits
> {
110 : DOTGraphTraitsViewer
<DominatorTreeWrapperPass
, false, DominatorTree
*,
111 DominatorTreeWrapperPassAnalysisGraphTraits
>(
113 initializeDomViewerPass(*PassRegistry::getPassRegistry());
117 struct DomOnlyViewer
: public DOTGraphTraitsViewer
<
118 DominatorTreeWrapperPass
, true, DominatorTree
*,
119 DominatorTreeWrapperPassAnalysisGraphTraits
> {
122 : DOTGraphTraitsViewer
<DominatorTreeWrapperPass
, true, DominatorTree
*,
123 DominatorTreeWrapperPassAnalysisGraphTraits
>(
125 initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
129 struct PostDominatorTreeWrapperPassAnalysisGraphTraits
{
130 static PostDominatorTree
*getGraph(PostDominatorTreeWrapperPass
*PDTWP
) {
131 return &PDTWP
->getPostDomTree();
135 struct PostDomViewer
: public DOTGraphTraitsViewer
<
136 PostDominatorTreeWrapperPass
, false,
138 PostDominatorTreeWrapperPassAnalysisGraphTraits
> {
141 DOTGraphTraitsViewer
<PostDominatorTreeWrapperPass
, false,
143 PostDominatorTreeWrapperPassAnalysisGraphTraits
>(
145 initializePostDomViewerPass(*PassRegistry::getPassRegistry());
149 struct PostDomOnlyViewer
: public DOTGraphTraitsViewer
<
150 PostDominatorTreeWrapperPass
, true,
152 PostDominatorTreeWrapperPassAnalysisGraphTraits
> {
154 PostDomOnlyViewer() :
155 DOTGraphTraitsViewer
<PostDominatorTreeWrapperPass
, true,
157 PostDominatorTreeWrapperPassAnalysisGraphTraits
>(
159 initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
162 } // end anonymous namespace
164 char DomViewer::ID
= 0;
165 INITIALIZE_PASS(DomViewer
, "view-dom",
166 "View dominance tree of function", false, false)
168 char DomOnlyViewer::ID
= 0;
169 INITIALIZE_PASS(DomOnlyViewer
, "view-dom-only",
170 "View dominance tree of function (with no function bodies)",
173 char PostDomViewer::ID
= 0;
174 INITIALIZE_PASS(PostDomViewer
, "view-postdom",
175 "View postdominance tree of function", false, false)
177 char PostDomOnlyViewer::ID
= 0;
178 INITIALIZE_PASS(PostDomOnlyViewer
, "view-postdom-only",
179 "View postdominance tree of function "
180 "(with no function bodies)",
184 struct DomPrinter
: public DOTGraphTraitsPrinter
<
185 DominatorTreeWrapperPass
, false, DominatorTree
*,
186 DominatorTreeWrapperPassAnalysisGraphTraits
> {
189 : DOTGraphTraitsPrinter
<DominatorTreeWrapperPass
, false, DominatorTree
*,
190 DominatorTreeWrapperPassAnalysisGraphTraits
>(
192 initializeDomPrinterPass(*PassRegistry::getPassRegistry());
196 struct DomOnlyPrinter
: public DOTGraphTraitsPrinter
<
197 DominatorTreeWrapperPass
, true, DominatorTree
*,
198 DominatorTreeWrapperPassAnalysisGraphTraits
> {
201 : DOTGraphTraitsPrinter
<DominatorTreeWrapperPass
, true, DominatorTree
*,
202 DominatorTreeWrapperPassAnalysisGraphTraits
>(
204 initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
208 struct PostDomPrinter
209 : public DOTGraphTraitsPrinter
<
210 PostDominatorTreeWrapperPass
, false,
212 PostDominatorTreeWrapperPassAnalysisGraphTraits
> {
215 DOTGraphTraitsPrinter
<PostDominatorTreeWrapperPass
, false,
217 PostDominatorTreeWrapperPassAnalysisGraphTraits
>(
219 initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
223 struct PostDomOnlyPrinter
224 : public DOTGraphTraitsPrinter
<
225 PostDominatorTreeWrapperPass
, true,
227 PostDominatorTreeWrapperPassAnalysisGraphTraits
> {
229 PostDomOnlyPrinter() :
230 DOTGraphTraitsPrinter
<PostDominatorTreeWrapperPass
, true,
232 PostDominatorTreeWrapperPassAnalysisGraphTraits
>(
234 initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
237 } // end anonymous namespace
241 char DomPrinter::ID
= 0;
242 INITIALIZE_PASS(DomPrinter
, "dot-dom",
243 "Print dominance tree of function to 'dot' file",
246 char DomOnlyPrinter::ID
= 0;
247 INITIALIZE_PASS(DomOnlyPrinter
, "dot-dom-only",
248 "Print dominance tree of function to 'dot' file "
249 "(with no function bodies)",
252 char PostDomPrinter::ID
= 0;
253 INITIALIZE_PASS(PostDomPrinter
, "dot-postdom",
254 "Print postdominance tree of function to 'dot' file",
257 char PostDomOnlyPrinter::ID
= 0;
258 INITIALIZE_PASS(PostDomOnlyPrinter
, "dot-postdom-only",
259 "Print postdominance tree of function to 'dot' file "
260 "(with no function bodies)",
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.
267 FunctionPass
*llvm::createDomPrinterPass() {
268 return new DomPrinter();
271 FunctionPass
*llvm::createDomOnlyPrinterPass() {
272 return new DomOnlyPrinter();
275 FunctionPass
*llvm::createDomViewerPass() {
276 return new DomViewer();
279 FunctionPass
*llvm::createDomOnlyViewerPass() {
280 return new DomOnlyViewer();
283 FunctionPass
*llvm::createPostDomPrinterPass() {
284 return new PostDomPrinter();
287 FunctionPass
*llvm::createPostDomOnlyPrinterPass() {
288 return new PostDomOnlyPrinter();
291 FunctionPass
*llvm::createPostDomViewerPass() {
292 return new PostDomViewer();
295 FunctionPass
*llvm::createPostDomOnlyViewerPass() {
296 return new PostDomOnlyViewer();