DomPrinter.cpp revision 202878
1//===- DomPrinter.cpp - DOT printer for the dominance trees ------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit 11// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the 12// program, with a graph of the dominance/postdominance tree of that 13// function. 14// 15// There are also passes available to directly call dotty ('-view-dom' or 16// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the 17// names of the bbs are printed, but the content is hidden. 18// 19//===----------------------------------------------------------------------===// 20 21#include "llvm/Analysis/DomPrinter.h" 22 23#include "llvm/Analysis/Dominators.h" 24#include "llvm/Analysis/DOTGraphTraitsPass.h" 25#include "llvm/Analysis/PostDominators.h" 26 27using namespace llvm; 28 29namespace llvm { 30template<> 31struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits { 32 33 DOTGraphTraits (bool isSimple=false) 34 : DefaultDOTGraphTraits(isSimple) {} 35 36 std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) { 37 38 BasicBlock *BB = Node->getBlock(); 39 40 if (!BB) 41 return "Post dominance root node"; 42 43 44 if (isSimple()) 45 return DOTGraphTraits<const Function*> 46 ::getSimpleNodeLabel(BB, BB->getParent()); 47 else 48 return DOTGraphTraits<const Function*> 49 ::getCompleteNodeLabel(BB, BB->getParent()); 50 } 51}; 52 53template<> 54struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> { 55 56 DOTGraphTraits (bool isSimple=false) 57 : DOTGraphTraits<DomTreeNode*>(isSimple) {} 58 59 static std::string getGraphName(DominatorTree *DT) { 60 return "Dominator tree"; 61 } 62 63 std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) { 64 return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); 65 } 66}; 67 68template<> 69struct DOTGraphTraits<PostDominatorTree*> 70 : public DOTGraphTraits<DomTreeNode*> { 71 72 DOTGraphTraits (bool isSimple=false) 73 : DOTGraphTraits<DomTreeNode*>(isSimple) {} 74 75 static std::string getGraphName(PostDominatorTree *DT) { 76 return "Post dominator tree"; 77 } 78 79 std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) { 80 return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); 81 } 82}; 83} 84 85namespace { 86template <class Analysis, bool OnlyBBS> 87struct GenericGraphViewer : public FunctionPass { 88 std::string Name; 89 90 GenericGraphViewer(std::string GraphName, const void *ID) : FunctionPass(ID) { 91 Name = GraphName; 92 } 93 94 virtual bool runOnFunction(Function &F) { 95 Analysis *Graph; 96 std::string Title, GraphName; 97 Graph = &getAnalysis<Analysis>(); 98 GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); 99 Title = GraphName + " for '" + F.getNameStr() + "' function"; 100 ViewGraph(Graph, Name, OnlyBBS, Title); 101 102 return false; 103 } 104 105 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 106 AU.setPreservesAll(); 107 AU.addRequired<Analysis>(); 108 } 109}; 110 111struct DomViewer 112 : public DOTGraphTraitsViewer<DominatorTree, false> { 113 static char ID; 114 DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", &ID){} 115}; 116 117struct DomOnlyViewer 118 : public DOTGraphTraitsViewer<DominatorTree, true> { 119 static char ID; 120 DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", &ID){} 121}; 122 123struct PostDomViewer 124 : public DOTGraphTraitsViewer<PostDominatorTree, false> { 125 static char ID; 126 PostDomViewer() : 127 DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", &ID){} 128}; 129 130struct PostDomOnlyViewer 131 : public DOTGraphTraitsViewer<PostDominatorTree, true> { 132 static char ID; 133 PostDomOnlyViewer() : 134 DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", &ID){} 135}; 136} // end anonymous namespace 137 138char DomViewer::ID = 0; 139RegisterPass<DomViewer> A("view-dom", 140 "View dominance tree of function"); 141 142char DomOnlyViewer::ID = 0; 143RegisterPass<DomOnlyViewer> B("view-dom-only", 144 "View dominance tree of function " 145 "(with no function bodies)"); 146 147char PostDomViewer::ID = 0; 148RegisterPass<PostDomViewer> C("view-postdom", 149 "View postdominance tree of function"); 150 151char PostDomOnlyViewer::ID = 0; 152RegisterPass<PostDomOnlyViewer> D("view-postdom-only", 153 "View postdominance tree of function " 154 "(with no function bodies)"); 155 156namespace { 157struct DomPrinter 158 : public DOTGraphTraitsPrinter<DominatorTree, false> { 159 static char ID; 160 DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {} 161}; 162 163struct DomOnlyPrinter 164 : public DOTGraphTraitsPrinter<DominatorTree, true> { 165 static char ID; 166 DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {} 167}; 168 169struct PostDomPrinter 170 : public DOTGraphTraitsPrinter<PostDominatorTree, false> { 171 static char ID; 172 PostDomPrinter() : 173 DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {} 174}; 175 176struct PostDomOnlyPrinter 177 : public DOTGraphTraitsPrinter<PostDominatorTree, true> { 178 static char ID; 179 PostDomOnlyPrinter() : 180 DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {} 181}; 182} // end anonymous namespace 183 184 185 186char DomPrinter::ID = 0; 187RegisterPass<DomPrinter> E("dot-dom", 188 "Print dominance tree of function " 189 "to 'dot' file"); 190 191char DomOnlyPrinter::ID = 0; 192RegisterPass<DomOnlyPrinter> F("dot-dom-only", 193 "Print dominance tree of function " 194 "to 'dot' file " 195 "(with no function bodies)"); 196 197char PostDomPrinter::ID = 0; 198RegisterPass<PostDomPrinter> G("dot-postdom", 199 "Print postdominance tree of function " 200 "to 'dot' file"); 201 202char PostDomOnlyPrinter::ID = 0; 203RegisterPass<PostDomOnlyPrinter> H("dot-postdom-only", 204 "Print postdominance tree of function " 205 "to 'dot' file " 206 "(with no function bodies)"); 207 208// Create methods available outside of this file, to use them 209// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 210// the link time optimization. 211 212FunctionPass *llvm::createDomPrinterPass() { 213 return new DomPrinter(); 214} 215 216FunctionPass *llvm::createDomOnlyPrinterPass() { 217 return new DomOnlyPrinter(); 218} 219 220FunctionPass *llvm::createDomViewerPass() { 221 return new DomViewer(); 222} 223 224FunctionPass *llvm::createDomOnlyViewerPass() { 225 return new DomOnlyViewer(); 226} 227 228FunctionPass *llvm::createPostDomPrinterPass() { 229 return new PostDomPrinter(); 230} 231 232FunctionPass *llvm::createPostDomOnlyPrinterPass() { 233 return new PostDomOnlyPrinter(); 234} 235 236FunctionPass *llvm::createPostDomViewerPass() { 237 return new PostDomViewer(); 238} 239 240FunctionPass *llvm::createPostDomOnlyViewerPass() { 241 return new PostDomOnlyViewer(); 242} 243