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 
00020 namespace llvm {
00021 
00022 /// \brief Default traits class for extracting a graph from an analysis pass.
00023 ///
00024 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
00025 template <typename AnalysisT, typename GraphT = AnalysisT *>
00026 struct DefaultAnalysisGraphTraits {
00027   static GraphT getGraph(AnalysisT *A) { return A; }
00028 };
00029 
00030 template <
00031     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00032     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00033 class DOTGraphTraitsViewer : public FunctionPass {
00034 public:
00035   DOTGraphTraitsViewer(StringRef GraphName, char &ID)
00036       : FunctionPass(ID), Name(GraphName) {}
00037 
00038   bool runOnFunction(Function &F) override {
00039     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00040     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
00041     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
00042 
00043     ViewGraph(Graph, Name, IsSimple, Title);
00044 
00045     return false;
00046   }
00047 
00048   void getAnalysisUsage(AnalysisUsage &AU) const override {
00049     AU.setPreservesAll();
00050     AU.addRequired<AnalysisT>();
00051   }
00052 
00053 private:
00054   std::string Name;
00055 };
00056 
00057 template <
00058     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00059     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00060 class DOTGraphTraitsPrinter : public FunctionPass {
00061 public:
00062   DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
00063       : FunctionPass(ID), Name(GraphName) {}
00064 
00065   bool runOnFunction(Function &F) override {
00066     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00067     std::string Filename = Name + "." + F.getName().str() + ".dot";
00068     std::string ErrorInfo;
00069 
00070     errs() << "Writing '" << Filename << "'...";
00071 
00072     raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
00073     std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
00074     std::string Title = GraphName + " for '" + F.getName().str() + "' function";
00075 
00076     if (ErrorInfo.empty())
00077       WriteGraph(File, Graph, IsSimple, Title);
00078     else
00079       errs() << "  error opening file for writing!";
00080     errs() << "\n";
00081 
00082     return false;
00083   }
00084 
00085   void getAnalysisUsage(AnalysisUsage &AU) const override {
00086     AU.setPreservesAll();
00087     AU.addRequired<AnalysisT>();
00088   }
00089 
00090 private:
00091   std::string Name;
00092 };
00093 
00094 template <
00095     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00096     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00097 class DOTGraphTraitsModuleViewer : public ModulePass {
00098 public:
00099   DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
00100       : ModulePass(ID), Name(GraphName) {}
00101 
00102   bool runOnModule(Module &M) override {
00103     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00104     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
00105 
00106     ViewGraph(Graph, Name, IsSimple, Title);
00107 
00108     return false;
00109   }
00110 
00111   void getAnalysisUsage(AnalysisUsage &AU) const override {
00112     AU.setPreservesAll();
00113     AU.addRequired<AnalysisT>();
00114   }
00115 
00116 private:
00117   std::string Name;
00118 };
00119 
00120 template <
00121     typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
00122     typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
00123 class DOTGraphTraitsModulePrinter : public ModulePass {
00124 public:
00125   DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
00126       : ModulePass(ID), Name(GraphName) {}
00127 
00128   bool runOnModule(Module &M) override {
00129     GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
00130     std::string Filename = Name + ".dot";
00131     std::string ErrorInfo;
00132 
00133     errs() << "Writing '" << Filename << "'...";
00134 
00135     raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
00136     std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
00137 
00138     if (ErrorInfo.empty())
00139       WriteGraph(File, Graph, IsSimple, Title);
00140     else
00141       errs() << "  error opening file for writing!";
00142     errs() << "\n";
00143 
00144     return false;
00145   }
00146 
00147   void getAnalysisUsage(AnalysisUsage &AU) const override {
00148     AU.setPreservesAll();
00149     AU.addRequired<AnalysisT>();
00150   }
00151 
00152 private:
00153   std::string Name;
00154 };
00155 
00156 } // end namespace llvm
00157 
00158 #endif