| //===- DomPrinter.cpp - DOT printer for the dominance trees ------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit | |
| // a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the | |
| // program, with a graph of the dominance/postdominance tree of that | |
| // function. | |
| // | |
| // There are also passes available to directly call dotty ('-view-dom' or | |
| // '-view-postdom'). By appending '-only' like '-dot-dom-only' only the | |
| // names of the bbs are printed, but the content is hidden. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Analysis/DomPrinter.h" | |
| #include "llvm/Analysis/DOTGraphTraitsPass.h" | |
| #include "llvm/Analysis/PostDominators.h" | |
| using namespace llvm; | |
| namespace llvm { | |
| template<> | |
| struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits { | |
| DOTGraphTraits (bool isSimple=false) | |
| : DefaultDOTGraphTraits(isSimple) {} | |
| std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) { | |
| BasicBlock *BB = Node->getBlock(); | |
| if (!BB) | |
| return "Post dominance root node"; | |
| if (isSimple()) | |
| return DOTGraphTraits<const Function*> | |
| ::getSimpleNodeLabel(BB, BB->getParent()); | |
| else | |
| return DOTGraphTraits<const Function*> | |
| ::getCompleteNodeLabel(BB, BB->getParent()); | |
| } | |
| }; | |
| template<> | |
| struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> { | |
| DOTGraphTraits (bool isSimple=false) | |
| : DOTGraphTraits<DomTreeNode*>(isSimple) {} | |
| static std::string getGraphName(DominatorTree *DT) { | |
| return "Dominator tree"; | |
| } | |
| std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) { | |
| return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); | |
| } | |
| }; | |
| template<> | |
| struct DOTGraphTraits<PostDominatorTree*> | |
| : public DOTGraphTraits<DomTreeNode*> { | |
| DOTGraphTraits (bool isSimple=false) | |
| : DOTGraphTraits<DomTreeNode*>(isSimple) {} | |
| static std::string getGraphName(PostDominatorTree *DT) { | |
| return "Post dominator tree"; | |
| } | |
| std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) { | |
| return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); | |
| } | |
| }; | |
| } | |
| namespace { | |
| struct DomViewer | |
| : public DOTGraphTraitsViewer<DominatorTree, false> { | |
| static char ID; | |
| DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", ID){ | |
| initializeDomViewerPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| struct DomOnlyViewer | |
| : public DOTGraphTraitsViewer<DominatorTree, true> { | |
| static char ID; | |
| DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", ID){ | |
| initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| struct PostDomViewer | |
| : public DOTGraphTraitsViewer<PostDominatorTree, false> { | |
| static char ID; | |
| PostDomViewer() : | |
| DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){ | |
| initializePostDomViewerPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| struct PostDomOnlyViewer | |
| : public DOTGraphTraitsViewer<PostDominatorTree, true> { | |
| static char ID; | |
| PostDomOnlyViewer() : | |
| DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){ | |
| initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| } // end anonymous namespace | |
| char DomViewer::ID = 0; | |
| INITIALIZE_PASS(DomViewer, "view-dom", | |
| "View dominance tree of function", false, false) | |
| char DomOnlyViewer::ID = 0; | |
| INITIALIZE_PASS(DomOnlyViewer, "view-dom-only", | |
| "View dominance tree of function (with no function bodies)", | |
| false, false) | |
| char PostDomViewer::ID = 0; | |
| INITIALIZE_PASS(PostDomViewer, "view-postdom", | |
| "View postdominance tree of function", false, false) | |
| char PostDomOnlyViewer::ID = 0; | |
| INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only", | |
| "View postdominance tree of function " | |
| "(with no function bodies)", | |
| false, false) | |
| namespace { | |
| struct DomPrinter | |
| : public DOTGraphTraitsPrinter<DominatorTree, false> { | |
| static char ID; | |
| DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", ID) { | |
| initializeDomPrinterPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| struct DomOnlyPrinter | |
| : public DOTGraphTraitsPrinter<DominatorTree, true> { | |
| static char ID; | |
| DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", ID) { | |
| initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| struct PostDomPrinter | |
| : public DOTGraphTraitsPrinter<PostDominatorTree, false> { | |
| static char ID; | |
| PostDomPrinter() : | |
| DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) { | |
| initializePostDomPrinterPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| struct PostDomOnlyPrinter | |
| : public DOTGraphTraitsPrinter<PostDominatorTree, true> { | |
| static char ID; | |
| PostDomOnlyPrinter() : | |
| DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) { | |
| initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); | |
| } | |
| }; | |
| } // end anonymous namespace | |
| char DomPrinter::ID = 0; | |
| INITIALIZE_PASS(DomPrinter, "dot-dom", | |
| "Print dominance tree of function to 'dot' file", | |
| false, false) | |
| char DomOnlyPrinter::ID = 0; | |
| INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only", | |
| "Print dominance tree of function to 'dot' file " | |
| "(with no function bodies)", | |
| false, false) | |
| char PostDomPrinter::ID = 0; | |
| INITIALIZE_PASS(PostDomPrinter, "dot-postdom", | |
| "Print postdominance tree of function to 'dot' file", | |
| false, false) | |
| char PostDomOnlyPrinter::ID = 0; | |
| INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only", | |
| "Print postdominance tree of function to 'dot' file " | |
| "(with no function bodies)", | |
| false, false) | |
| // Create methods available outside of this file, to use them | |
| // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by | |
| // the link time optimization. | |
| FunctionPass *llvm::createDomPrinterPass() { | |
| return new DomPrinter(); | |
| } | |
| FunctionPass *llvm::createDomOnlyPrinterPass() { | |
| return new DomOnlyPrinter(); | |
| } | |
| FunctionPass *llvm::createDomViewerPass() { | |
| return new DomViewer(); | |
| } | |
| FunctionPass *llvm::createDomOnlyViewerPass() { | |
| return new DomOnlyViewer(); | |
| } | |
| FunctionPass *llvm::createPostDomPrinterPass() { | |
| return new PostDomPrinter(); | |
| } | |
| FunctionPass *llvm::createPostDomOnlyPrinterPass() { | |
| return new PostDomOnlyPrinter(); | |
| } | |
| FunctionPass *llvm::createPostDomViewerPass() { | |
| return new PostDomViewer(); | |
| } | |
| FunctionPass *llvm::createPostDomOnlyViewerPass() { | |
| return new PostDomOnlyViewer(); | |
| } |