diff --git a/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h b/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h --- a/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -19,20 +19,127 @@ namespace llvm { +/// Default traits class for extracting a graph from an analysis pass. +/// +/// This assumes that 'GraphT' is 'AnalysisT::Result *', and pass it through +template +struct DefaultAnalysisGraphTraits { + static GraphT getGraph(Result R) { return &R; } +}; + +template +void viewGraphForFunction(Function &F, GraphT Graph, StringRef Name, + bool IsSimple) { + std::string GraphName = DOTGraphTraits::getGraphName(&Graph); + + ViewGraph(Graph, Name, IsSimple, + GraphName + " for '" + F.getName() + "' function"); +} + +template > +struct DOTGraphTraitsViewer + : public PassInfoMixin> { + DOTGraphTraitsViewer(StringRef GraphName) : Name(GraphName) {} + + /// 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 Result The current analysis result for this function. + virtual bool processFunction(Function &F, + const typename AnalysisT::Result &Result) { + return true; + } + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) { + auto &Result = FAM.getResult(F); + if (!processFunction(F, Result)) + return PreservedAnalyses::all(); + + GraphT Graph = AnalysisGraphTraitsT::getGraph(Result); + viewGraphForFunction(F, Graph, Name, IsSimple); + + return PreservedAnalyses::all(); + }; + +private: + StringRef Name; +}; + +template +void printGraphForFunction(Function &F, GraphT Graph, StringRef Name, + bool IsSimple) { + std::string Filename = Name.str() + "." + F.getName().str() + ".dot"; + std::error_code EC; + + errs() << "Writing '" << Filename << "'..."; + + raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF); + std::string GraphName = DOTGraphTraits::getGraphName(Graph); + + if (!EC) + WriteGraph(File, Graph, IsSimple, + GraphName + " for '" + F.getName() + "' function"); + else + errs() << " error opening file for writing!"; + errs() << "\n"; +} + +template > +struct DOTGraphTraitsPrinter + : public PassInfoMixin> { + DOTGraphTraitsPrinter(StringRef GraphName) : Name(GraphName) {} + + /// 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, + const typename AnalysisT::Result &Result) { + return true; + } + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) { + auto &Result = FAM.getResult(F); + if (!processFunction(F, Result)) + return PreservedAnalyses::all(); + + GraphT Graph = AnalysisGraphTraitsT::getGraph(Result); + + printGraphForFunction(F, Graph, Name, IsSimple); + + return PreservedAnalyses::all(); + }; + +private: + StringRef Name; +}; + /// 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 { +struct LegacyDefaultAnalysisGraphTraits { static GraphT getGraph(AnalysisT *A) { return A; } }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsViewer : public FunctionPass { +template > +class DOTGraphTraitsViewerWrapperPass : public FunctionPass { public: - DOTGraphTraitsViewer(StringRef GraphName, char &ID) + DOTGraphTraitsViewerWrapperPass(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} /// Return true if this function should be processed. @@ -52,10 +159,7 @@ 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); + viewGraphForFunction(F, Graph, Name, IsSimple); return false; } @@ -69,12 +173,12 @@ std::string Name; }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsPrinter : public FunctionPass { +template > +class DOTGraphTraitsPrinterWrapperPass : public FunctionPass { public: - DOTGraphTraitsPrinter(StringRef GraphName, char &ID) + DOTGraphTraitsPrinterWrapperPass(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} /// Return true if this function should be processed. @@ -94,20 +198,7 @@ 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::OF_TextWithCRLF); - 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"; + printGraphForFunction(F, Graph, Name, IsSimple); return false; } @@ -121,12 +212,12 @@ std::string Name; }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsModuleViewer : public ModulePass { +template > +class DOTGraphTraitsModuleViewerWrapperPass : public ModulePass { public: - DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) + DOTGraphTraitsModuleViewerWrapperPass(StringRef GraphName, char &ID) : ModulePass(ID), Name(GraphName) {} bool runOnModule(Module &M) override { @@ -147,12 +238,12 @@ std::string Name; }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsModulePrinter : public ModulePass { +template > +class DOTGraphTraitsModulePrinterWrapperPass : public ModulePass { public: - DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) + DOTGraphTraitsModulePrinterWrapperPass(StringRef GraphName, char &ID) : ModulePass(ID), Name(GraphName) {} bool runOnModule(Module &M) override { diff --git a/llvm/lib/Analysis/DomPrinter.cpp b/llvm/lib/Analysis/DomPrinter.cpp --- a/llvm/lib/Analysis/DomPrinter.cpp +++ b/llvm/lib/Analysis/DomPrinter.cpp @@ -116,26 +116,26 @@ } }; -struct DomViewer : public DOTGraphTraitsViewer< +struct DomViewer : public DOTGraphTraitsViewerWrapperPass< DominatorTreeWrapperPass, false, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomViewer() - : DOTGraphTraitsViewer( - "dom", ID) { + : DOTGraphTraitsViewerWrapperPass< + DominatorTreeWrapperPass, false, DominatorTree *, + DominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) { initializeDomViewerPass(*PassRegistry::getPassRegistry()); } }; -struct DomOnlyViewer : public DOTGraphTraitsViewer< +struct DomOnlyViewer : public DOTGraphTraitsViewerWrapperPass< DominatorTreeWrapperPass, true, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomOnlyViewer() - : DOTGraphTraitsViewer( - "domonly", ID) { + : DOTGraphTraitsViewerWrapperPass< + DominatorTreeWrapperPass, true, DominatorTree *, + DominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) { initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry()); } }; @@ -146,32 +146,31 @@ } }; -struct PostDomViewer : public DOTGraphTraitsViewer< - PostDominatorTreeWrapperPass, false, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { +struct PostDomViewer + : public DOTGraphTraitsViewerWrapperPass< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomViewer() : - DOTGraphTraitsViewer( - "postdom", ID){ - initializePostDomViewerPass(*PassRegistry::getPassRegistry()); - } + PostDomViewer() + : DOTGraphTraitsViewerWrapperPass< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom", ID) { + initializePostDomViewerPass(*PassRegistry::getPassRegistry()); + } }; -struct PostDomOnlyViewer : public DOTGraphTraitsViewer< - PostDominatorTreeWrapperPass, true, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { +struct PostDomOnlyViewer + : public DOTGraphTraitsViewerWrapperPass< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomOnlyViewer() : - DOTGraphTraitsViewer( - "postdomonly", ID){ - initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry()); - } + PostDomOnlyViewer() + : DOTGraphTraitsViewerWrapperPass< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdomonly", + ID) { + initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry()); + } }; } // end anonymous namespace @@ -195,58 +194,55 @@ false, false) namespace { -struct DomPrinter : public DOTGraphTraitsPrinter< +struct DomPrinter : public DOTGraphTraitsPrinterWrapperPass< DominatorTreeWrapperPass, false, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomPrinter() - : DOTGraphTraitsPrinter( - "dom", ID) { + : DOTGraphTraitsPrinterWrapperPass< + DominatorTreeWrapperPass, false, DominatorTree *, + DominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) { initializeDomPrinterPass(*PassRegistry::getPassRegistry()); } }; -struct DomOnlyPrinter : public DOTGraphTraitsPrinter< +struct DomOnlyPrinter : public DOTGraphTraitsPrinterWrapperPass< DominatorTreeWrapperPass, true, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomOnlyPrinter() - : DOTGraphTraitsPrinter( - "domonly", ID) { + : DOTGraphTraitsPrinterWrapperPass< + DominatorTreeWrapperPass, true, DominatorTree *, + DominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) { initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); } }; struct PostDomPrinter - : public DOTGraphTraitsPrinter< - PostDominatorTreeWrapperPass, false, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { + : public DOTGraphTraitsPrinterWrapperPass< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomPrinter() : - DOTGraphTraitsPrinter( - "postdom", ID) { - initializePostDomPrinterPass(*PassRegistry::getPassRegistry()); - } + PostDomPrinter() + : DOTGraphTraitsPrinterWrapperPass< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom", ID) { + initializePostDomPrinterPass(*PassRegistry::getPassRegistry()); + } }; struct PostDomOnlyPrinter - : public DOTGraphTraitsPrinter< - PostDominatorTreeWrapperPass, true, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { + : public DOTGraphTraitsPrinterWrapperPass< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomOnlyPrinter() : - DOTGraphTraitsPrinter( - "postdomonly", ID) { - initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); - } + PostDomOnlyPrinter() + : DOTGraphTraitsPrinterWrapperPass< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdomonly", + ID) { + initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); + } }; } // end anonymous namespace diff --git a/llvm/lib/Analysis/RegionPrinter.cpp b/llvm/lib/Analysis/RegionPrinter.cpp --- a/llvm/lib/Analysis/RegionPrinter.cpp +++ b/llvm/lib/Analysis/RegionPrinter.cpp @@ -145,48 +145,49 @@ }; struct RegionPrinter - : public DOTGraphTraitsPrinter { + : public DOTGraphTraitsPrinterWrapperPass< + RegionInfoPass, false, RegionInfo *, RegionInfoPassGraphTraits> { static char ID; RegionPrinter() - : DOTGraphTraitsPrinter("reg", ID) { + : DOTGraphTraitsPrinterWrapperPass("reg", ID) { initializeRegionPrinterPass(*PassRegistry::getPassRegistry()); } }; char RegionPrinter::ID = 0; struct RegionOnlyPrinter - : public DOTGraphTraitsPrinter { + : public DOTGraphTraitsPrinterWrapperPass< + RegionInfoPass, true, RegionInfo *, RegionInfoPassGraphTraits> { static char ID; RegionOnlyPrinter() - : DOTGraphTraitsPrinter("reg", ID) { + : DOTGraphTraitsPrinterWrapperPass("reg", ID) { initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry()); } }; char RegionOnlyPrinter::ID = 0; struct RegionViewer - : public DOTGraphTraitsViewer { + : public DOTGraphTraitsViewerWrapperPass< + RegionInfoPass, false, RegionInfo *, RegionInfoPassGraphTraits> { static char ID; RegionViewer() - : DOTGraphTraitsViewer("reg", ID) { + : DOTGraphTraitsViewerWrapperPass("reg", ID) { initializeRegionViewerPass(*PassRegistry::getPassRegistry()); } }; char RegionViewer::ID = 0; struct RegionOnlyViewer - : public DOTGraphTraitsViewer { + : public DOTGraphTraitsViewerWrapperPass { static char ID; RegionOnlyViewer() - : DOTGraphTraitsViewer("regonly", ID) { + : DOTGraphTraitsViewerWrapperPass("regonly", + ID) { initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry()); } }; diff --git a/polly/lib/Analysis/ScopGraphPrinter.cpp b/polly/lib/Analysis/ScopGraphPrinter.cpp --- a/polly/lib/Analysis/ScopGraphPrinter.cpp +++ b/polly/lib/Analysis/ScopGraphPrinter.cpp @@ -198,10 +198,11 @@ } // end namespace llvm struct ScopViewer - : public DOTGraphTraitsViewer { + : public DOTGraphTraitsViewerWrapperPass { static char ID; ScopViewer() - : DOTGraphTraitsViewer("scops", ID) {} + : DOTGraphTraitsViewerWrapperPass( + "scops", ID) {} bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override { if (ViewFilter != "" && !F.getName().count(ViewFilter)) return false; @@ -216,27 +217,29 @@ char ScopViewer::ID = 0; struct ScopOnlyViewer - : public DOTGraphTraitsViewer { + : public DOTGraphTraitsViewerWrapperPass { static char ID; ScopOnlyViewer() - : DOTGraphTraitsViewer("scopsonly", ID) {} + : DOTGraphTraitsViewerWrapperPass( + "scopsonly", ID) {} }; char ScopOnlyViewer::ID = 0; struct ScopPrinter - : public DOTGraphTraitsPrinter { + : public DOTGraphTraitsPrinterWrapperPass { static char ID; ScopPrinter() - : DOTGraphTraitsPrinter("scops", ID) {} + : DOTGraphTraitsPrinterWrapperPass( + "scops", ID) {} }; char ScopPrinter::ID = 0; struct ScopOnlyPrinter - : public DOTGraphTraitsPrinter { + : public DOTGraphTraitsPrinterWrapperPass { static char ID; ScopOnlyPrinter() - : DOTGraphTraitsPrinter("scopsonly", ID) { - } + : DOTGraphTraitsPrinterWrapperPass( + "scopsonly", ID) {} }; char ScopOnlyPrinter::ID = 0;