Home | History | Annotate | Download | only in Analysis
      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 #include "llvm/Analysis/DOTGraphTraitsPass.h"
     23 #include "llvm/Analysis/PostDominators.h"
     24 
     25 using namespace llvm;
     26 
     27 namespace llvm {
     28 template<>
     29 struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
     30 
     31   DOTGraphTraits (bool isSimple=false)
     32     : DefaultDOTGraphTraits(isSimple) {}
     33 
     34   std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
     35 
     36     BasicBlock *BB = Node->getBlock();
     37 
     38     if (!BB)
     39       return "Post dominance root node";
     40 
     41 
     42     if (isSimple())
     43       return DOTGraphTraits<const Function*>
     44         ::getSimpleNodeLabel(BB, BB->getParent());
     45     else
     46       return DOTGraphTraits<const Function*>
     47         ::getCompleteNodeLabel(BB, BB->getParent());
     48   }
     49 };
     50 
     51 template<>
     52 struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
     53 
     54   DOTGraphTraits (bool isSimple=false)
     55     : DOTGraphTraits<DomTreeNode*>(isSimple) {}
     56 
     57   static std::string getGraphName(DominatorTree *DT) {
     58     return "Dominator tree";
     59   }
     60 
     61   std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
     62     return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
     63   }
     64 };
     65 
     66 template<>
     67 struct DOTGraphTraits<PostDominatorTree*>
     68   : public DOTGraphTraits<DomTreeNode*> {
     69 
     70   DOTGraphTraits (bool isSimple=false)
     71     : DOTGraphTraits<DomTreeNode*>(isSimple) {}
     72 
     73   static std::string getGraphName(PostDominatorTree *DT) {
     74     return "Post dominator tree";
     75   }
     76 
     77   std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
     78     return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
     79   }
     80 };
     81 }
     82 
     83 namespace {
     84 struct DomViewer
     85   : public DOTGraphTraitsViewer<DominatorTree, false> {
     86   static char ID;
     87   DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", ID){
     88     initializeDomViewerPass(*PassRegistry::getPassRegistry());
     89   }
     90 };
     91 
     92 struct DomOnlyViewer
     93   : public DOTGraphTraitsViewer<DominatorTree, true> {
     94   static char ID;
     95   DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", ID){
     96     initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
     97   }
     98 };
     99 
    100 struct PostDomViewer
    101   : public DOTGraphTraitsViewer<PostDominatorTree, false> {
    102   static char ID;
    103   PostDomViewer() :
    104     DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){
    105       initializePostDomViewerPass(*PassRegistry::getPassRegistry());
    106     }
    107 };
    108 
    109 struct PostDomOnlyViewer
    110   : public DOTGraphTraitsViewer<PostDominatorTree, true> {
    111   static char ID;
    112   PostDomOnlyViewer() :
    113     DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){
    114       initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
    115     }
    116 };
    117 } // end anonymous namespace
    118 
    119 char DomViewer::ID = 0;
    120 INITIALIZE_PASS(DomViewer, "view-dom",
    121                 "View dominance tree of function", false, false)
    122 
    123 char DomOnlyViewer::ID = 0;
    124 INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
    125                 "View dominance tree of function (with no function bodies)",
    126                 false, false)
    127 
    128 char PostDomViewer::ID = 0;
    129 INITIALIZE_PASS(PostDomViewer, "view-postdom",
    130                 "View postdominance tree of function", false, false)
    131 
    132 char PostDomOnlyViewer::ID = 0;
    133 INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
    134                 "View postdominance tree of function "
    135                 "(with no function bodies)",
    136                 false, false)
    137 
    138 namespace {
    139 struct DomPrinter
    140   : public DOTGraphTraitsPrinter<DominatorTree, false> {
    141   static char ID;
    142   DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", ID) {
    143     initializeDomPrinterPass(*PassRegistry::getPassRegistry());
    144   }
    145 };
    146 
    147 struct DomOnlyPrinter
    148   : public DOTGraphTraitsPrinter<DominatorTree, true> {
    149   static char ID;
    150   DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", ID) {
    151     initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
    152   }
    153 };
    154 
    155 struct PostDomPrinter
    156   : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
    157   static char ID;
    158   PostDomPrinter() :
    159     DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) {
    160       initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
    161     }
    162 };
    163 
    164 struct PostDomOnlyPrinter
    165   : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
    166   static char ID;
    167   PostDomOnlyPrinter() :
    168     DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) {
    169       initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
    170     }
    171 };
    172 } // end anonymous namespace
    173 
    174 
    175 
    176 char DomPrinter::ID = 0;
    177 INITIALIZE_PASS(DomPrinter, "dot-dom",
    178                 "Print dominance tree of function to 'dot' file",
    179                 false, false)
    180 
    181 char DomOnlyPrinter::ID = 0;
    182 INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
    183                 "Print dominance tree of function to 'dot' file "
    184                 "(with no function bodies)",
    185                 false, false)
    186 
    187 char PostDomPrinter::ID = 0;
    188 INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
    189                 "Print postdominance tree of function to 'dot' file",
    190                 false, false)
    191 
    192 char PostDomOnlyPrinter::ID = 0;
    193 INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
    194                 "Print postdominance tree of function to 'dot' file "
    195                 "(with no function bodies)",
    196                 false, false)
    197 
    198 // Create methods available outside of this file, to use them
    199 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
    200 // the link time optimization.
    201 
    202 FunctionPass *llvm::createDomPrinterPass() {
    203   return new DomPrinter();
    204 }
    205 
    206 FunctionPass *llvm::createDomOnlyPrinterPass() {
    207   return new DomOnlyPrinter();
    208 }
    209 
    210 FunctionPass *llvm::createDomViewerPass() {
    211   return new DomViewer();
    212 }
    213 
    214 FunctionPass *llvm::createDomOnlyViewerPass() {
    215   return new DomOnlyViewer();
    216 }
    217 
    218 FunctionPass *llvm::createPostDomPrinterPass() {
    219   return new PostDomPrinter();
    220 }
    221 
    222 FunctionPass *llvm::createPostDomOnlyPrinterPass() {
    223   return new PostDomOnlyPrinter();
    224 }
    225 
    226 FunctionPass *llvm::createPostDomViewerPass() {
    227   return new PostDomViewer();
    228 }
    229 
    230 FunctionPass *llvm::createPostDomOnlyViewerPass() {
    231   return new PostDomOnlyViewer();
    232 }
    233