X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FAnalysis%2FDOTGraphTraitsPass.h;h=ca50ee2f829a55d82832b0c643b2507201190d7c;hp=4828eba5b5283f664d284d43ae53a8a9a9f0a502;hb=0bc653bad8c7de4fc88b3cb989769285087447ea;hpb=1f74590e9d1b9cf0f1f81a156efea73f76546e05 diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h index 4828eba5b52..ca50ee2f829 100644 --- a/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -11,73 +11,179 @@ // //===----------------------------------------------------------------------===// -#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, const void *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. + /// + /// @param Analysis The current analysis result for this function. + virtual bool processFunction(Function &F, AnalysisT &Analysis) { + return true; } - virtual bool runOnFunction(Function &F) { - Analysis *Graph; - std::string Title, GraphName; - Graph = &getAnalysis(); - GraphName = DOTGraphTraits::getGraphName(Graph); - Title = GraphName + " for '" + F.getNameStr() + "' function"; - ViewGraph(Graph, Name, Simple, Title); + bool runOnFunction(Function &F) override { + auto &Analysis = getAnalysis(); + + if (!processFunction(F, Analysis)) + return false; + + GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis); + 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(); } + +private: + std::string Name; }; -template -struct DOTGraphTraitsPrinter : public FunctionPass { +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) {} + + /// @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. + /// + /// @param Analysis The current analysis result for this function. + virtual bool processFunction(Function &F, AnalysisT &Analysis) { + return true; + } + + bool runOnFunction(Function &F) override { + auto &Analysis = getAnalysis(); + + if (!processFunction(F, Analysis)) + return false; + + GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis); + std::string Filename = Name + "." + F.getName().str() + ".dot"; + std::error_code EC; + + errs() << "Writing '" << Filename << "'..."; + + 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; +}; - DOTGraphTraitsPrinter(std::string GraphName, const void *ID) - : FunctionPass(ID) { - Name = GraphName; +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; } - virtual bool runOnFunction(Function &F) { - Analysis *Graph; - std::string Filename = Name + "." + F.getNameStr() + ".dot"; - errs() << "Writing '" << Filename << "'..."; + 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; - std::string ErrorInfo; - raw_fd_ostream File(Filename.c_str(), ErrorInfo); - Graph = &getAnalysis(); + errs() << "Writing '" << Filename << "'..."; - std::string Title, GraphName; - GraphName = DOTGraphTraits::getGraphName(Graph); - Title = GraphName + " for '" + F.getNameStr() + "' function"; + raw_fd_ostream File(Filename, EC, sys::fs::F_Text); + std::string Title = DOTGraphTraits::getGraphName(Graph); - if (ErrorInfo.empty()) - WriteGraph(File, Graph, Simple, Name, 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