DomPrinter.cpp revision 198396
1198396Srdivacky//===- DomPrinter.cpp - DOT printer for the dominance trees ------------===// 2198396Srdivacky// 3198396Srdivacky// The LLVM Compiler Infrastructure 4198396Srdivacky// 5198396Srdivacky// This file is distributed under the University of Illinois Open Source 6198396Srdivacky// License. See LICENSE.TXT for details. 7198396Srdivacky// 8198396Srdivacky//===----------------------------------------------------------------------===// 9198396Srdivacky// 10198396Srdivacky// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit 11198396Srdivacky// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the 12198396Srdivacky// program, with a graph of the dominance/postdominance tree of that 13198396Srdivacky// function. 14198396Srdivacky// 15198396Srdivacky// There are also passes available to directly call dotty ('-view-dom' or 16198396Srdivacky// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the 17198396Srdivacky// names of the bbs are printed, but the content is hidden. 18198396Srdivacky// 19198396Srdivacky//===----------------------------------------------------------------------===// 20198396Srdivacky 21198396Srdivacky#include "llvm/Analysis/DomPrinter.h" 22198396Srdivacky#include "llvm/Pass.h" 23198396Srdivacky#include "llvm/Function.h" 24198396Srdivacky#include "llvm/Analysis/CFGPrinter.h" 25198396Srdivacky#include "llvm/Analysis/Dominators.h" 26198396Srdivacky#include "llvm/Analysis/PostDominators.h" 27198396Srdivacky 28198396Srdivackyusing namespace llvm; 29198396Srdivacky 30198396Srdivackynamespace llvm { 31198396Srdivackytemplate<> 32198396Srdivackystruct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits { 33198396Srdivacky static std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph, 34198396Srdivacky bool ShortNames) { 35198396Srdivacky 36198396Srdivacky BasicBlock *BB = Node->getBlock(); 37198396Srdivacky 38198396Srdivacky if (!BB) 39198396Srdivacky return "Post dominance root node"; 40198396Srdivacky 41198396Srdivacky return DOTGraphTraits<const Function*>::getNodeLabel(BB, BB->getParent(), 42198396Srdivacky ShortNames); 43198396Srdivacky } 44198396Srdivacky}; 45198396Srdivacky 46198396Srdivackytemplate<> 47198396Srdivackystruct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> { 48198396Srdivacky 49198396Srdivacky static std::string getGraphName(DominatorTree *DT) { 50198396Srdivacky return "Dominator tree"; 51198396Srdivacky } 52198396Srdivacky 53198396Srdivacky static std::string getNodeLabel(DomTreeNode *Node, 54198396Srdivacky DominatorTree *G, 55198396Srdivacky bool ShortNames) { 56198396Srdivacky return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode(), 57198396Srdivacky ShortNames); 58198396Srdivacky } 59198396Srdivacky}; 60198396Srdivacky 61198396Srdivackytemplate<> 62198396Srdivackystruct DOTGraphTraits<PostDominatorTree*> 63198396Srdivacky : public DOTGraphTraits<DomTreeNode*> { 64198396Srdivacky static std::string getGraphName(PostDominatorTree *DT) { 65198396Srdivacky return "Post dominator tree"; 66198396Srdivacky } 67198396Srdivacky static std::string getNodeLabel(DomTreeNode *Node, 68198396Srdivacky PostDominatorTree *G, 69198396Srdivacky bool ShortNames) { 70198396Srdivacky return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, 71198396Srdivacky G->getRootNode(), 72198396Srdivacky ShortNames); 73198396Srdivacky } 74198396Srdivacky}; 75198396Srdivacky} 76198396Srdivacky 77198396Srdivackynamespace { 78198396Srdivackytemplate <class Analysis, bool OnlyBBS> 79198396Srdivackystruct GenericGraphViewer : public FunctionPass { 80198396Srdivacky std::string Name; 81198396Srdivacky 82198396Srdivacky GenericGraphViewer(std::string GraphName, const void *ID) : FunctionPass(ID) { 83198396Srdivacky Name = GraphName; 84198396Srdivacky } 85198396Srdivacky 86198396Srdivacky virtual bool runOnFunction(Function &F) { 87198396Srdivacky Analysis *Graph; 88198396Srdivacky 89198396Srdivacky Graph = &getAnalysis<Analysis>(); 90198396Srdivacky ViewGraph(Graph, Name, OnlyBBS); 91198396Srdivacky 92198396Srdivacky return false; 93198396Srdivacky } 94198396Srdivacky 95198396Srdivacky virtual void getAnalysisUsage(AnalysisUsage &AU) const { 96198396Srdivacky AU.setPreservesAll(); 97198396Srdivacky AU.addRequired<Analysis>(); 98198396Srdivacky } 99198396Srdivacky}; 100198396Srdivacky 101198396Srdivackystruct DomViewer 102198396Srdivacky : public GenericGraphViewer<DominatorTree, false> { 103198396Srdivacky static char ID; 104198396Srdivacky DomViewer() : GenericGraphViewer<DominatorTree, false>("dom", &ID){} 105198396Srdivacky}; 106198396Srdivacky 107198396Srdivackystruct DomOnlyViewer 108198396Srdivacky : public GenericGraphViewer<DominatorTree, true> { 109198396Srdivacky static char ID; 110198396Srdivacky DomOnlyViewer() : GenericGraphViewer<DominatorTree, true>("domonly", &ID){} 111198396Srdivacky}; 112198396Srdivacky 113198396Srdivackystruct PostDomViewer 114198396Srdivacky : public GenericGraphViewer<PostDominatorTree, false> { 115198396Srdivacky static char ID; 116198396Srdivacky PostDomViewer() : 117198396Srdivacky GenericGraphViewer<PostDominatorTree, false>("postdom", &ID){} 118198396Srdivacky}; 119198396Srdivacky 120198396Srdivackystruct PostDomOnlyViewer 121198396Srdivacky : public GenericGraphViewer<PostDominatorTree, true> { 122198396Srdivacky static char ID; 123198396Srdivacky PostDomOnlyViewer() : 124198396Srdivacky GenericGraphViewer<PostDominatorTree, true>("postdomonly", &ID){} 125198396Srdivacky}; 126198396Srdivacky} // end anonymous namespace 127198396Srdivacky 128198396Srdivackychar DomViewer::ID = 0; 129198396SrdivackyRegisterPass<DomViewer> A("view-dom", 130198396Srdivacky "View dominance tree of function"); 131198396Srdivacky 132198396Srdivackychar DomOnlyViewer::ID = 0; 133198396SrdivackyRegisterPass<DomOnlyViewer> B("view-dom-only", 134198396Srdivacky "View dominance tree of function " 135198396Srdivacky "(with no function bodies)"); 136198396Srdivacky 137198396Srdivackychar PostDomViewer::ID = 0; 138198396SrdivackyRegisterPass<PostDomViewer> C("view-postdom", 139198396Srdivacky "View postdominance tree of function"); 140198396Srdivacky 141198396Srdivackychar PostDomOnlyViewer::ID = 0; 142198396SrdivackyRegisterPass<PostDomOnlyViewer> D("view-postdom-only", 143198396Srdivacky "View postdominance tree of function " 144198396Srdivacky "(with no function bodies)"); 145198396Srdivacky 146198396Srdivackynamespace { 147198396Srdivackytemplate <class Analysis, bool OnlyBBS> 148198396Srdivackystruct GenericGraphPrinter : public FunctionPass { 149198396Srdivacky 150198396Srdivacky std::string Name; 151198396Srdivacky 152198396Srdivacky GenericGraphPrinter(std::string GraphName, const void *ID) 153198396Srdivacky : FunctionPass(ID) { 154198396Srdivacky Name = GraphName; 155198396Srdivacky } 156198396Srdivacky 157198396Srdivacky virtual bool runOnFunction(Function &F) { 158198396Srdivacky Analysis *Graph; 159198396Srdivacky std::string Filename = Name + "." + F.getNameStr() + ".dot"; 160198396Srdivacky errs() << "Writing '" << Filename << "'..."; 161198396Srdivacky 162198396Srdivacky std::string ErrorInfo; 163198396Srdivacky raw_fd_ostream File(Filename.c_str(), ErrorInfo); 164198396Srdivacky Graph = &getAnalysis<Analysis>(); 165198396Srdivacky 166198396Srdivacky if (ErrorInfo.empty()) 167198396Srdivacky WriteGraph(File, Graph, OnlyBBS); 168198396Srdivacky else 169198396Srdivacky errs() << " error opening file for writing!"; 170198396Srdivacky errs() << "\n"; 171198396Srdivacky return false; 172198396Srdivacky } 173198396Srdivacky 174198396Srdivacky virtual void getAnalysisUsage(AnalysisUsage &AU) const { 175198396Srdivacky AU.setPreservesAll(); 176198396Srdivacky AU.addRequired<Analysis>(); 177198396Srdivacky } 178198396Srdivacky}; 179198396Srdivacky 180198396Srdivackystruct DomPrinter 181198396Srdivacky : public GenericGraphPrinter<DominatorTree, false> { 182198396Srdivacky static char ID; 183198396Srdivacky DomPrinter() : GenericGraphPrinter<DominatorTree, false>("dom", &ID) {} 184198396Srdivacky}; 185198396Srdivacky 186198396Srdivackystruct DomOnlyPrinter 187198396Srdivacky : public GenericGraphPrinter<DominatorTree, true> { 188198396Srdivacky static char ID; 189198396Srdivacky DomOnlyPrinter() : GenericGraphPrinter<DominatorTree, true>("domonly", &ID) {} 190198396Srdivacky}; 191198396Srdivacky 192198396Srdivackystruct PostDomPrinter 193198396Srdivacky : public GenericGraphPrinter<PostDominatorTree, false> { 194198396Srdivacky static char ID; 195198396Srdivacky PostDomPrinter() : 196198396Srdivacky GenericGraphPrinter<PostDominatorTree, false>("postdom", &ID) {} 197198396Srdivacky}; 198198396Srdivacky 199198396Srdivackystruct PostDomOnlyPrinter 200198396Srdivacky : public GenericGraphPrinter<PostDominatorTree, true> { 201198396Srdivacky static char ID; 202198396Srdivacky PostDomOnlyPrinter() : 203198396Srdivacky GenericGraphPrinter<PostDominatorTree, true>("postdomonly", &ID) {} 204198396Srdivacky}; 205198396Srdivacky} // end anonymous namespace 206198396Srdivacky 207198396Srdivacky 208198396Srdivacky 209198396Srdivackychar DomPrinter::ID = 0; 210198396SrdivackyRegisterPass<DomPrinter> E("dot-dom", 211198396Srdivacky "Print dominance tree of function " 212198396Srdivacky "to 'dot' file"); 213198396Srdivacky 214198396Srdivackychar DomOnlyPrinter::ID = 0; 215198396SrdivackyRegisterPass<DomOnlyPrinter> F("dot-dom-only", 216198396Srdivacky "Print dominance tree of function " 217198396Srdivacky "to 'dot' file " 218198396Srdivacky "(with no function bodies)"); 219198396Srdivacky 220198396Srdivackychar PostDomPrinter::ID = 0; 221198396SrdivackyRegisterPass<PostDomPrinter> G("dot-postdom", 222198396Srdivacky "Print postdominance tree of function " 223198396Srdivacky "to 'dot' file"); 224198396Srdivacky 225198396Srdivackychar PostDomOnlyPrinter::ID = 0; 226198396SrdivackyRegisterPass<PostDomOnlyPrinter> H("dot-postdom-only", 227198396Srdivacky "Print postdominance tree of function " 228198396Srdivacky "to 'dot' file " 229198396Srdivacky "(with no function bodies)"); 230198396Srdivacky 231198396Srdivacky// Create methods available outside of this file, to use them 232198396Srdivacky// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 233198396Srdivacky// the link time optimization. 234198396Srdivacky 235198396SrdivackyFunctionPass *llvm::createDomPrinterPass() { 236198396Srdivacky return new DomPrinter(); 237198396Srdivacky} 238198396Srdivacky 239198396SrdivackyFunctionPass *llvm::createDomOnlyPrinterPass() { 240198396Srdivacky return new DomOnlyPrinter(); 241198396Srdivacky} 242198396Srdivacky 243198396SrdivackyFunctionPass *llvm::createDomViewerPass() { 244198396Srdivacky return new DomViewer(); 245198396Srdivacky} 246198396Srdivacky 247198396SrdivackyFunctionPass *llvm::createDomOnlyViewerPass() { 248198396Srdivacky return new DomOnlyViewer(); 249198396Srdivacky} 250198396Srdivacky 251198396SrdivackyFunctionPass *llvm::createPostDomPrinterPass() { 252198396Srdivacky return new PostDomPrinter(); 253198396Srdivacky} 254198396Srdivacky 255198396SrdivackyFunctionPass *llvm::createPostDomOnlyPrinterPass() { 256198396Srdivacky return new PostDomOnlyPrinter(); 257198396Srdivacky} 258198396Srdivacky 259198396SrdivackyFunctionPass *llvm::createPostDomViewerPass() { 260198396Srdivacky return new PostDomViewer(); 261198396Srdivacky} 262198396Srdivacky 263198396SrdivackyFunctionPass *llvm::createPostDomOnlyViewerPass() { 264198396Srdivacky return new PostDomOnlyViewer(); 265198396Srdivacky} 266