LLVM API Documentation

DOTGraphTraitsPass.h
Go to the documentation of this file.
00001 //===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Templates to create dotty viewer and printer passes for GraphTraits graphs.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
00015 #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
00016 
00017 #include "llvm/Analysis/CFGPrinter.h"
00018 #include "llvm/Pass.h"
00019 #include "llvm/Support/FileSystem.h"
00020 
00021 namespace llvm {
00022 
00023 /// \brief Default traits class for extracting a graph from an analysis pass.
00024 ///
00025 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
00026 template <typename AnalysisT, typename GraphT = AnalysisT *>
00027 struct DefaultAnalysisGraphTraits {
00028   static GraphT getGraph(AnalysisT *A) { return A; }
00029 };
00030 
00031 template <
00032     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00033     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00034 class DOTGraphTraitsViewer : public FunctionPass {
00035 public:
00036   DOTGraphTraitsViewer(StringRef GraphName, char &ID)
00037       : FunctionPass(ID), Name(GraphName) {}
00038 
00039   bool runOnFunction(Function &F) override {
00040     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00041     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
00042     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
00043 
00044     ViewGraph(Graph, Name, IsSimple, Title);
00045 
00046     return false;
00047   }
00048 
00049   void getAnalysisUsage(AnalysisUsage &AU) const override {
00050     AU.setPreservesAll();
00051     AU.addRequired<AnalysisT>();
00052   }
00053 
00054 private:
00055   std::string Name;
00056 };
00057 
00058 template <
00059     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00060     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00061 class DOTGraphTraitsPrinter : public FunctionPass {
00062 public:
00063   DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
00064       : FunctionPass(ID), Name(GraphName) {}
00065 
00066   bool runOnFunction(Function &F) override {
00067     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00068     std::string Filename = Name + "." + F.getName().str() + ".dot";
00069     std::string ErrorInfo;
00070 
00071     errs() << "Writing '" << Filename << "'...";
00072 
00073     raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
00074     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
00075     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
00076 
00077     if (ErrorInfo.empty())
00078       WriteGraph(File, Graph, IsSimple, Title);
00079     else
00080       errs() << "  error opening file for writing!";
00081     errs() << "\n";
00082 
00083     return false;
00084   }
00085 
00086   void getAnalysisUsage(AnalysisUsage &AU) const override {
00087     AU.setPreservesAll();
00088     AU.addRequired<AnalysisT>();
00089   }
00090 
00091 private:
00092   std::string Name;
00093 };
00094 
00095 template <
00096     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00097     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00098 class DOTGraphTraitsModuleViewer : public ModulePass {
00099 public:
00100   DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
00101       : ModulePass(ID), Name(GraphName) {}
00102 
00103   bool runOnModule(Module &M) override {
00104     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00105     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
00106 
00107     ViewGraph(Graph, Name, IsSimple, Title);
00108 
00109     return false;
00110   }
00111 
00112   void getAnalysisUsage(AnalysisUsage &AU) const override {
00113     AU.setPreservesAll();
00114     AU.addRequired<AnalysisT>();
00115   }
00116 
00117 private:
00118   std::string Name;
00119 };
00120 
00121 template <
00122     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00123     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00124 class DOTGraphTraitsModulePrinter : public ModulePass {
00125 public:
00126   DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
00127       : ModulePass(ID), Name(GraphName) {}
00128 
00129   bool runOnModule(Module &M) override {
00130     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00131     std::string Filename = Name + ".dot";
00132     std::string ErrorInfo;
00133 
00134     errs() << "Writing '" << Filename << "'...";
00135 
00136     raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
00137     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
00138 
00139     if (ErrorInfo.empty())
00140       WriteGraph(File, Graph, IsSimple, Title);
00141     else
00142       errs() << "  error opening file for writing!";
00143     errs() << "\n";
00144 
00145     return false;
00146   }
00147 
00148   void getAnalysisUsage(AnalysisUsage &AU) const override {
00149     AU.setPreservesAll();
00150     AU.addRequired<AnalysisT>();
00151   }
00152 
00153 private:
00154   std::string Name;
00155 };
00156 
00157 } // end namespace llvm
00158 
00159 #endif