DomPrinter.cpp revision 198396
1189251Ssam//===- DomPrinter.cpp - DOT printer for the dominance trees ------------===// 2189251Ssam// 3189251Ssam// The LLVM Compiler Infrastructure 4189251Ssam// 5252726Srpaulo// This file is distributed under the University of Illinois Open Source 6252726Srpaulo// License. See LICENSE.TXT for details. 7189251Ssam// 8189251Ssam//===----------------------------------------------------------------------===// 9189251Ssam// 10189251Ssam// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit 11189251Ssam// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the 12189251Ssam// program, with a graph of the dominance/postdominance tree of that 13189251Ssam// function. 14189251Ssam// 15189251Ssam// There are also passes available to directly call dotty ('-view-dom' or 16189251Ssam// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the 17189251Ssam// names of the bbs are printed, but the content is hidden. 18189251Ssam// 19189251Ssam//===----------------------------------------------------------------------===// 20189251Ssam 21189251Ssam#include "llvm/Analysis/DomPrinter.h" 22189251Ssam#include "llvm/Pass.h" 23189251Ssam#include "llvm/Function.h" 24189251Ssam#include "llvm/Analysis/CFGPrinter.h" 25189251Ssam#include "llvm/Analysis/Dominators.h" 26189251Ssam#include "llvm/Analysis/PostDominators.h" 27189251Ssam 28189251Ssamusing namespace llvm; 29189251Ssam 30189251Ssamnamespace llvm { 31189251Ssamtemplate<> 32189251Ssamstruct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits { 33189251Ssam static std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph, 34189251Ssam bool ShortNames) { 35189251Ssam 36189251Ssam BasicBlock *BB = Node->getBlock(); 37214734Srpaulo 38189251Ssam if (!BB) 39189251Ssam return "Post dominance root node"; 40189251Ssam 41189251Ssam return DOTGraphTraits<const Function*>::getNodeLabel(BB, BB->getParent(), 42189251Ssam ShortNames); 43189251Ssam } 44189251Ssam}; 45189251Ssam 46189251Ssamtemplate<> 47189251Ssamstruct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> { 48189251Ssam 49189251Ssam static std::string getGraphName(DominatorTree *DT) { 50189251Ssam return "Dominator tree"; 51189251Ssam } 52189251Ssam 53209158Srpaulo static std::string getNodeLabel(DomTreeNode *Node, 54209158Srpaulo DominatorTree *G, 55209158Srpaulo bool ShortNames) { 56209158Srpaulo return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode(), 57189251Ssam ShortNames); 58189251Ssam } 59189251Ssam}; 60209158Srpaulo 61189251Ssamtemplate<> 62189251Ssamstruct DOTGraphTraits<PostDominatorTree*> 63189251Ssam : public DOTGraphTraits<DomTreeNode*> { 64189251Ssam static std::string getGraphName(PostDominatorTree *DT) { 65189251Ssam return "Post dominator tree"; 66189251Ssam } 67189251Ssam static std::string getNodeLabel(DomTreeNode *Node, 68189251Ssam PostDominatorTree *G, 69189251Ssam bool ShortNames) { 70189251Ssam return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, 71189251Ssam G->getRootNode(), 72189251Ssam ShortNames); 73189251Ssam } 74189251Ssam}; 75189251Ssam} 76189251Ssam 77189251Ssamnamespace { 78189251Ssamtemplate <class Analysis, bool OnlyBBS> 79189251Ssamstruct GenericGraphViewer : public FunctionPass { 80189251Ssam std::string Name; 81189251Ssam 82189251Ssam GenericGraphViewer(std::string GraphName, const void *ID) : FunctionPass(ID) { 83189251Ssam Name = GraphName; 84189251Ssam } 85189251Ssam 86189251Ssam virtual bool runOnFunction(Function &F) { 87189251Ssam Analysis *Graph; 88189251Ssam 89189251Ssam Graph = &getAnalysis<Analysis>(); 90189251Ssam ViewGraph(Graph, Name, OnlyBBS); 91189251Ssam 92189251Ssam return false; 93189251Ssam } 94189251Ssam 95189251Ssam virtual void getAnalysisUsage(AnalysisUsage &AU) const { 96189251Ssam AU.setPreservesAll(); 97189251Ssam AU.addRequired<Analysis>(); 98189251Ssam } 99189251Ssam}; 100189251Ssam 101189251Ssamstruct DomViewer 102189251Ssam : public GenericGraphViewer<DominatorTree, false> { 103189251Ssam static char ID; 104189251Ssam DomViewer() : GenericGraphViewer<DominatorTree, false>("dom", &ID){} 105189251Ssam}; 106189251Ssam 107189251Ssamstruct DomOnlyViewer 108189251Ssam : public GenericGraphViewer<DominatorTree, true> { 109189251Ssam static char ID; 110189251Ssam DomOnlyViewer() : GenericGraphViewer<DominatorTree, true>("domonly", &ID){} 111189251Ssam}; 112189251Ssam 113189251Ssamstruct PostDomViewer 114189251Ssam : public GenericGraphViewer<PostDominatorTree, false> { 115189251Ssam static char ID; 116189251Ssam PostDomViewer() : 117189251Ssam GenericGraphViewer<PostDominatorTree, false>("postdom", &ID){} 118189251Ssam}; 119189251Ssam 120189251Ssamstruct PostDomOnlyViewer 121189251Ssam : public GenericGraphViewer<PostDominatorTree, true> { 122189251Ssam static char ID; 123189251Ssam PostDomOnlyViewer() : 124189251Ssam GenericGraphViewer<PostDominatorTree, true>("postdomonly", &ID){} 125189251Ssam}; 126189251Ssam} // end anonymous namespace 127189251Ssam 128189251Ssamchar DomViewer::ID = 0; 129189251SsamRegisterPass<DomViewer> A("view-dom", 130189251Ssam "View dominance tree of function"); 131189251Ssam 132189251Ssamchar DomOnlyViewer::ID = 0; 133189251SsamRegisterPass<DomOnlyViewer> B("view-dom-only", 134189251Ssam "View dominance tree of function " 135189251Ssam "(with no function bodies)"); 136189251Ssam 137189251Ssamchar PostDomViewer::ID = 0; 138189251SsamRegisterPass<PostDomViewer> C("view-postdom", 139189251Ssam "View postdominance tree of function"); 140189251Ssam 141189251Ssamchar PostDomOnlyViewer::ID = 0; 142189251SsamRegisterPass<PostDomOnlyViewer> D("view-postdom-only", 143189251Ssam "View postdominance tree of function " 144189251Ssam "(with no function bodies)"); 145189251Ssam 146189251Ssamnamespace { 147189251Ssamtemplate <class Analysis, bool OnlyBBS> 148189251Ssamstruct GenericGraphPrinter : public FunctionPass { 149189251Ssam 150189251Ssam std::string Name; 151189251Ssam 152189251Ssam GenericGraphPrinter(std::string GraphName, const void *ID) 153189251Ssam : FunctionPass(ID) { 154189251Ssam Name = GraphName; 155189251Ssam } 156189251Ssam 157189251Ssam virtual bool runOnFunction(Function &F) { 158189251Ssam Analysis *Graph; 159189251Ssam std::string Filename = Name + "." + F.getNameStr() + ".dot"; 160189251Ssam errs() << "Writing '" << Filename << "'..."; 161189251Ssam 162189251Ssam std::string ErrorInfo; 163189251Ssam raw_fd_ostream File(Filename.c_str(), ErrorInfo); 164189251Ssam Graph = &getAnalysis<Analysis>(); 165189251Ssam 166189251Ssam if (ErrorInfo.empty()) 167189251Ssam WriteGraph(File, Graph, OnlyBBS); 168189251Ssam else 169189251Ssam errs() << " error opening file for writing!"; 170189251Ssam errs() << "\n"; 171189251Ssam return false; 172189251Ssam } 173189251Ssam 174189251Ssam virtual void getAnalysisUsage(AnalysisUsage &AU) const { 175189251Ssam AU.setPreservesAll(); 176189251Ssam AU.addRequired<Analysis>(); 177189251Ssam } 178189251Ssam}; 179189251Ssam 180189251Ssamstruct DomPrinter 181189251Ssam : public GenericGraphPrinter<DominatorTree, false> { 182189251Ssam static char ID; 183189251Ssam DomPrinter() : GenericGraphPrinter<DominatorTree, false>("dom", &ID) {} 184189251Ssam}; 185189251Ssam 186189251Ssamstruct DomOnlyPrinter 187189251Ssam : public GenericGraphPrinter<DominatorTree, true> { 188189251Ssam static char ID; 189189251Ssam DomOnlyPrinter() : GenericGraphPrinter<DominatorTree, true>("domonly", &ID) {} 190189251Ssam}; 191189251Ssam 192189251Ssamstruct PostDomPrinter 193189251Ssam : public GenericGraphPrinter<PostDominatorTree, false> { 194189251Ssam static char ID; 195189251Ssam PostDomPrinter() : 196189251Ssam GenericGraphPrinter<PostDominatorTree, false>("postdom", &ID) {} 197189251Ssam}; 198189251Ssam 199189251Ssamstruct PostDomOnlyPrinter 200189251Ssam : public GenericGraphPrinter<PostDominatorTree, true> { 201189251Ssam static char ID; 202189251Ssam PostDomOnlyPrinter() : 203189251Ssam GenericGraphPrinter<PostDominatorTree, true>("postdomonly", &ID) {} 204189251Ssam}; 205189251Ssam} // end anonymous namespace 206189251Ssam 207189251Ssam 208189251Ssam 209189251Ssamchar DomPrinter::ID = 0; 210189251SsamRegisterPass<DomPrinter> E("dot-dom", 211189251Ssam "Print dominance tree of function " 212189251Ssam "to 'dot' file"); 213189251Ssam 214189251Ssamchar DomOnlyPrinter::ID = 0; 215189251SsamRegisterPass<DomOnlyPrinter> F("dot-dom-only", 216189251Ssam "Print dominance tree of function " 217189251Ssam "to 'dot' file " 218189251Ssam "(with no function bodies)"); 219189251Ssam 220189251Ssamchar PostDomPrinter::ID = 0; 221189251SsamRegisterPass<PostDomPrinter> G("dot-postdom", 222189251Ssam "Print postdominance tree of function " 223189251Ssam "to 'dot' file"); 224189251Ssam 225189251Ssamchar PostDomOnlyPrinter::ID = 0; 226189251SsamRegisterPass<PostDomOnlyPrinter> H("dot-postdom-only", 227189251Ssam "Print postdominance tree of function " 228189251Ssam "to 'dot' file " 229189251Ssam "(with no function bodies)"); 230189251Ssam 231189251Ssam// Create methods available outside of this file, to use them 232189251Ssam// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 233189251Ssam// the link time optimization. 234189251Ssam 235189251SsamFunctionPass *llvm::createDomPrinterPass() { 236189251Ssam return new DomPrinter(); 237189251Ssam} 238189251Ssam 239189251SsamFunctionPass *llvm::createDomOnlyPrinterPass() { 240189251Ssam return new DomOnlyPrinter(); 241189251Ssam} 242189251Ssam 243189251SsamFunctionPass *llvm::createDomViewerPass() { 244189251Ssam return new DomViewer(); 245189251Ssam} 246189251Ssam 247189251SsamFunctionPass *llvm::createDomOnlyViewerPass() { 248189251Ssam return new DomOnlyViewer(); 249189251Ssam} 250189251Ssam 251189251SsamFunctionPass *llvm::createPostDomPrinterPass() { 252189251Ssam return new PostDomPrinter(); 253189251Ssam} 254189251Ssam 255189251SsamFunctionPass *llvm::createPostDomOnlyPrinterPass() { 256189251Ssam return new PostDomOnlyPrinter(); 257189251Ssam} 258189251Ssam 259189251SsamFunctionPass *llvm::createPostDomViewerPass() { 260189251Ssam return new PostDomViewer(); 261189251Ssam} 262189251Ssam 263189251SsamFunctionPass *llvm::createPostDomOnlyViewerPass() { 264189251Ssam return new PostDomOnlyViewer(); 265189251Ssam} 266189251Ssam