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