X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FAnalysis%2FDOTGraphTraitsPass.h;h=3b2c0cb2b15e5f08162130d9fc2b5ef021f60b08;hb=dc0de228e265ffa060bc05227a8d18fffee89a02;hp=b701b8fca5d4df44749e929fdebbd6bc70f93ecc;hpb=a7b0cb759433c715065440ee2a963a04db7f2b0b;p=oota-llvm.git diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h index b701b8fca5d..3b2c0cb2b15 100644 --- a/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -11,73 +11,171 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H -#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H +#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H +#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H -#include "llvm/Pass.h" #include "llvm/Analysis/CFGPrinter.h" +#include "llvm/Pass.h" +#include "llvm/Support/FileSystem.h" namespace llvm { -template -struct DOTGraphTraitsViewer : public FunctionPass { - std::string Name; - DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) { - Name = GraphName; +/// \brief Default traits class for extracting a graph from an analysis pass. +/// +/// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through. +template +struct DefaultAnalysisGraphTraits { + static GraphT getGraph(AnalysisT *A) { return A; } +}; + +template < + typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, + typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > +class DOTGraphTraitsViewer : public FunctionPass { +public: + DOTGraphTraitsViewer(StringRef GraphName, char &ID) + : FunctionPass(ID), Name(GraphName) {} + + /// @brief Return true if this function should be processed. + /// + /// An implementation of this class my override this function to indicate that + /// only certain functions should be viewed. + virtual bool processFunction(Function &F) { + return true; } - virtual bool runOnFunction(Function &F) { - Analysis *Graph; - std::string Title, GraphName; - Graph = &getAnalysis(); - GraphName = DOTGraphTraits::getGraphName(Graph); - Title = GraphName + " for '" + F.getName().str() + "' function"; - ViewGraph(Graph, Name, Simple, Title); + bool runOnFunction(Function &F) override { + if (!processFunction(F)) + return false; + + GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis()); + std::string GraphName = DOTGraphTraits::getGraphName(Graph); + std::string Title = GraphName + " for '" + F.getName().str() + "' function"; + + ViewGraph(Graph, Name, IsSimple, Title); return false; } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); } -}; - -template -struct DOTGraphTraitsPrinter : public FunctionPass { +private: std::string Name; +}; + +template < + typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, + typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > +class DOTGraphTraitsPrinter : public FunctionPass { +public: + DOTGraphTraitsPrinter(StringRef GraphName, char &ID) + : FunctionPass(ID), Name(GraphName) {} - DOTGraphTraitsPrinter(std::string GraphName, char &ID) - : FunctionPass(ID) { - Name = GraphName; + /// @brief Return true if this function should be processed. + /// + /// An implementation of this class my override this function to indicate that + /// only certain functions should be printed. + virtual bool processFunction(Function &F) { + return true; } - virtual bool runOnFunction(Function &F) { - Analysis *Graph; + bool runOnFunction(Function &F) override { + if (!processFunction(F)) + return false; + + GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis()); std::string Filename = Name + "." + F.getName().str() + ".dot"; + std::error_code EC; + errs() << "Writing '" << Filename << "'..."; - std::string ErrorInfo; - raw_fd_ostream File(Filename.c_str(), ErrorInfo); - Graph = &getAnalysis(); + raw_fd_ostream File(Filename, EC, sys::fs::F_Text); + std::string GraphName = DOTGraphTraits::getGraphName(Graph); + std::string Title = GraphName + " for '" + F.getName().str() + "' function"; + + if (!EC) + WriteGraph(File, Graph, IsSimple, Title); + else + errs() << " error opening file for writing!"; + errs() << "\n"; + + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + } + +private: + std::string Name; +}; + +template < + typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, + typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > +class DOTGraphTraitsModuleViewer : public ModulePass { +public: + DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) + : ModulePass(ID), Name(GraphName) {} + + bool runOnModule(Module &M) override { + GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis()); + std::string Title = DOTGraphTraits::getGraphName(Graph); + + ViewGraph(Graph, Name, IsSimple, Title); + + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + } + +private: + std::string Name; +}; + +template < + typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, + typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > +class DOTGraphTraitsModulePrinter : public ModulePass { +public: + DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) + : ModulePass(ID), Name(GraphName) {} + + bool runOnModule(Module &M) override { + GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis()); + std::string Filename = Name + ".dot"; + std::error_code EC; + + errs() << "Writing '" << Filename << "'..."; - std::string Title, GraphName; - GraphName = DOTGraphTraits::getGraphName(Graph); - Title = GraphName + " for '" + F.getName().str() + "' function"; + raw_fd_ostream File(Filename, EC, sys::fs::F_Text); + std::string Title = DOTGraphTraits::getGraphName(Graph); - if (ErrorInfo.empty()) - WriteGraph(File, Graph, Simple, Title); + if (!EC) + WriteGraph(File, Graph, IsSimple, Title); else errs() << " error opening file for writing!"; errs() << "\n"; + return false; } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); } + +private: + std::string Name; }; -} + +} // end namespace llvm + #endif