Home | History | Annotate | Download | only in Analysis
      1 //===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
      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 // Templates to create dotty viewer and printer passes for GraphTraits graphs.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
     15 #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
     16 
     17 #include "llvm/Analysis/CFGPrinter.h"
     18 #include "llvm/Pass.h"
     19 #include "llvm/Support/FileSystem.h"
     20 
     21 namespace llvm {
     22 
     23 /// \brief Default traits class for extracting a graph from an analysis pass.
     24 ///
     25 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
     26 template <typename AnalysisT, typename GraphT = AnalysisT *>
     27 struct DefaultAnalysisGraphTraits {
     28   static GraphT getGraph(AnalysisT *A) { return A; }
     29 };
     30 
     31 template <
     32     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
     33     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
     34 class DOTGraphTraitsViewer : public FunctionPass {
     35 public:
     36   DOTGraphTraitsViewer(StringRef GraphName, char &ID)
     37       : FunctionPass(ID), Name(GraphName) {}
     38 
     39   bool runOnFunction(Function &F) override {
     40     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
     41     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
     42     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
     43 
     44     ViewGraph(Graph, Name, IsSimple, Title);
     45 
     46     return false;
     47   }
     48 
     49   void getAnalysisUsage(AnalysisUsage &AU) const override {
     50     AU.setPreservesAll();
     51     AU.addRequired<AnalysisT>();
     52   }
     53 
     54 private:
     55   std::string Name;
     56 };
     57 
     58 template <
     59     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
     60     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
     61 class DOTGraphTraitsPrinter : public FunctionPass {
     62 public:
     63   DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
     64       : FunctionPass(ID), Name(GraphName) {}
     65 
     66   bool runOnFunction(Function &F) override {
     67     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
     68     std::string Filename = Name + "." + F.getName().str() + ".dot";
     69     std::string ErrorInfo;
     70 
     71     errs() << "Writing '" << Filename << "'...";
     72 
     73     raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
     74     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
     75     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
     76 
     77     if (ErrorInfo.empty())
     78       WriteGraph(File, Graph, IsSimple, Title);
     79     else
     80       errs() << "  error opening file for writing!";
     81     errs() << "\n";
     82 
     83     return false;
     84   }
     85 
     86   void getAnalysisUsage(AnalysisUsage &AU) const override {
     87     AU.setPreservesAll();
     88     AU.addRequired<AnalysisT>();
     89   }
     90 
     91 private:
     92   std::string Name;
     93 };
     94 
     95 template <
     96     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
     97     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
     98 class DOTGraphTraitsModuleViewer : public ModulePass {
     99 public:
    100   DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
    101       : ModulePass(ID), Name(GraphName) {}
    102 
    103   bool runOnModule(Module &M) override {
    104     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
    105     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
    106 
    107     ViewGraph(Graph, Name, IsSimple, Title);
    108 
    109     return false;
    110   }
    111 
    112   void getAnalysisUsage(AnalysisUsage &AU) const override {
    113     AU.setPreservesAll();
    114     AU.addRequired<AnalysisT>();
    115   }
    116 
    117 private:
    118   std::string Name;
    119 };
    120 
    121 template <
    122     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
    123     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
    124 class DOTGraphTraitsModulePrinter : public ModulePass {
    125 public:
    126   DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
    127       : ModulePass(ID), Name(GraphName) {}
    128 
    129   bool runOnModule(Module &M) override {
    130     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
    131     std::string Filename = Name + ".dot";
    132     std::string ErrorInfo;
    133 
    134     errs() << "Writing '" << Filename << "'...";
    135 
    136     raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
    137     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
    138 
    139     if (ErrorInfo.empty())
    140       WriteGraph(File, Graph, IsSimple, Title);
    141     else
    142       errs() << "  error opening file for writing!";
    143     errs() << "\n";
    144 
    145     return false;
    146   }
    147 
    148   void getAnalysisUsage(AnalysisUsage &AU) const override {
    149     AU.setPreservesAll();
    150     AU.addRequired<AnalysisT>();
    151   }
    152 
    153 private:
    154   std::string Name;
    155 };
    156 
    157 } // end namespace llvm
    158 
    159 #endif
    160