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,117 @@ namespace llvm { +/// Default traits class for extracting a graph from an analysis pass. +/// +/// This assumes that 'GraphT' is 'AnalysisT::Result *', and get it through +/// FunctionAnalysisManager. +template +struct DefaultAnalysisGraphTraits { + static GraphT getGraph(Result &R) { return R; } +}; + +template > +class DOTGraphTraitsViewer + : public PassInfoMixin> { +public: + 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(llvm::Function &F, llvm::FunctionAnalysisManager &FAM) { + auto &Result = FAM.getResult(F); + if (!processFunction(F, Result)) + return PreservedAnalyses::all(); + + GraphT Graph = AnalysisGraphTraitsT::getGraph(Result); + std::string GraphName = DOTGraphTraits::getGraphName(Graph); + std::string Title = GraphName + " for '" + F.getName().str() + "' function"; + + ViewGraph(Graph, Name, IsSimple, Title); + + return PreservedAnalyses::all(); + }; + +private: + std::string Name; +}; + +template > +class DOTGraphTraitsPrinter + : public PassInfoMixin> { +public: + 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(llvm::Function &F, + const typename AnalysisT::Result &Result) { + return true; + } + + PreservedAnalyses run(llvm::Function &F, llvm::FunctionAnalysisManager &FAM) { + auto &Result = FAM.getResult(F); + if (!processFunction(F, Result)) + return PreservedAnalyses::all(); + + GraphT Graph = AnalysisGraphTraitsT::getGraph(Result); + 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"; + + return PreservedAnalyses::all(); + }; + +private: + std::string 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 LegacyDOTGraphTraitsViewer : public FunctionPass { public: - DOTGraphTraitsViewer(StringRef GraphName, char &ID) + LegacyDOTGraphTraitsViewer(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} /// Return true if this function should be processed. @@ -69,12 +166,12 @@ std::string Name; }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsPrinter : public FunctionPass { +template > +class LegacyDOTGraphTraitsPrinter : public FunctionPass { public: - DOTGraphTraitsPrinter(StringRef GraphName, char &ID) + LegacyDOTGraphTraitsPrinter(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} /// Return true if this function should be processed. @@ -121,12 +218,12 @@ std::string Name; }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsModuleViewer : public ModulePass { +template > +class LegacyDOTGraphTraitsModuleViewer : public ModulePass { public: - DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) + LegacyDOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) : ModulePass(ID), Name(GraphName) {} bool runOnModule(Module &M) override { @@ -147,12 +244,12 @@ std::string Name; }; -template < - typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, - typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits > -class DOTGraphTraitsModulePrinter : public ModulePass { +template > +class LegacyDOTGraphTraitsModulePrinter : public ModulePass { public: - DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) + LegacyDOTGraphTraitsModulePrinter(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,25 +116,27 @@ } }; -struct DomViewer : public DOTGraphTraitsViewer< +struct DomViewer : public LegacyDOTGraphTraitsViewer< DominatorTreeWrapperPass, false, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomViewer() - : DOTGraphTraitsViewer( + : LegacyDOTGraphTraitsViewer( "dom", ID) { initializeDomViewerPass(*PassRegistry::getPassRegistry()); } }; -struct DomOnlyViewer : public DOTGraphTraitsViewer< +struct DomOnlyViewer : public LegacyDOTGraphTraitsViewer< DominatorTreeWrapperPass, true, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomOnlyViewer() - : DOTGraphTraitsViewer( + : LegacyDOTGraphTraitsViewer( "domonly", ID) { initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry()); } @@ -146,32 +148,31 @@ } }; -struct PostDomViewer : public DOTGraphTraitsViewer< - PostDominatorTreeWrapperPass, false, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { +struct PostDomViewer + : public LegacyDOTGraphTraitsViewer< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomViewer() : - DOTGraphTraitsViewer( - "postdom", ID){ - initializePostDomViewerPass(*PassRegistry::getPassRegistry()); - } + PostDomViewer() + : LegacyDOTGraphTraitsViewer< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom", ID) { + initializePostDomViewerPass(*PassRegistry::getPassRegistry()); + } }; -struct PostDomOnlyViewer : public DOTGraphTraitsViewer< - PostDominatorTreeWrapperPass, true, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { +struct PostDomOnlyViewer + : public LegacyDOTGraphTraitsViewer< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomOnlyViewer() : - DOTGraphTraitsViewer( - "postdomonly", ID){ - initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry()); - } + PostDomOnlyViewer() + : LegacyDOTGraphTraitsViewer< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdomonly", + ID) { + initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry()); + } }; } // end anonymous namespace @@ -195,58 +196,55 @@ false, false) namespace { -struct DomPrinter : public DOTGraphTraitsPrinter< +struct DomPrinter : public LegacyDOTGraphTraitsPrinter< DominatorTreeWrapperPass, false, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomPrinter() - : DOTGraphTraitsPrinter( - "dom", ID) { + : LegacyDOTGraphTraitsPrinter< + DominatorTreeWrapperPass, false, DominatorTree *, + DominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) { initializeDomPrinterPass(*PassRegistry::getPassRegistry()); } }; -struct DomOnlyPrinter : public DOTGraphTraitsPrinter< +struct DomOnlyPrinter : public LegacyDOTGraphTraitsPrinter< DominatorTreeWrapperPass, true, DominatorTree *, DominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; DomOnlyPrinter() - : DOTGraphTraitsPrinter( - "domonly", ID) { + : LegacyDOTGraphTraitsPrinter< + DominatorTreeWrapperPass, true, DominatorTree *, + DominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) { initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); } }; struct PostDomPrinter - : public DOTGraphTraitsPrinter< - PostDominatorTreeWrapperPass, false, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { + : public LegacyDOTGraphTraitsPrinter< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomPrinter() : - DOTGraphTraitsPrinter( - "postdom", ID) { - initializePostDomPrinterPass(*PassRegistry::getPassRegistry()); - } + PostDomPrinter() + : LegacyDOTGraphTraitsPrinter< + PostDominatorTreeWrapperPass, false, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom", ID) { + initializePostDomPrinterPass(*PassRegistry::getPassRegistry()); + } }; struct PostDomOnlyPrinter - : public DOTGraphTraitsPrinter< - PostDominatorTreeWrapperPass, true, - PostDominatorTree *, - PostDominatorTreeWrapperPassAnalysisGraphTraits> { + : public LegacyDOTGraphTraitsPrinter< + PostDominatorTreeWrapperPass, true, PostDominatorTree *, + PostDominatorTreeWrapperPassAnalysisGraphTraits> { static char ID; - PostDomOnlyPrinter() : - DOTGraphTraitsPrinter( - "postdomonly", ID) { - initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); - } + PostDomOnlyPrinter() + : LegacyDOTGraphTraitsPrinter< + 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,48 @@ }; struct RegionPrinter - : public DOTGraphTraitsPrinter { + : public LegacyDOTGraphTraitsPrinter { static char ID; RegionPrinter() - : DOTGraphTraitsPrinter("reg", ID) { + : LegacyDOTGraphTraitsPrinter("reg", ID) { initializeRegionPrinterPass(*PassRegistry::getPassRegistry()); } }; char RegionPrinter::ID = 0; struct RegionOnlyPrinter - : public DOTGraphTraitsPrinter { + : public LegacyDOTGraphTraitsPrinter { static char ID; RegionOnlyPrinter() - : DOTGraphTraitsPrinter("reg", ID) { + : LegacyDOTGraphTraitsPrinter("reg", ID) { initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry()); } }; char RegionOnlyPrinter::ID = 0; struct RegionViewer - : public DOTGraphTraitsViewer { + : public LegacyDOTGraphTraitsViewer { static char ID; RegionViewer() - : DOTGraphTraitsViewer("reg", ID) { + : LegacyDOTGraphTraitsViewer("reg", ID) { initializeRegionViewerPass(*PassRegistry::getPassRegistry()); } }; char RegionViewer::ID = 0; struct RegionOnlyViewer - : public DOTGraphTraitsViewer { + : public LegacyDOTGraphTraitsViewer { static char ID; RegionOnlyViewer() - : DOTGraphTraitsViewer("regonly", ID) { + : LegacyDOTGraphTraitsViewer("regonly", ID) { initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry()); } };