Index: llvm/include/llvm/Analysis/DOTGraphTraitsPass.h =================================================================== --- llvm/include/llvm/Analysis/DOTGraphTraitsPass.h +++ llvm/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -181,6 +181,25 @@ std::string Name; }; +template +void WriteDOTGraphToFile(Function &F, GraphT &&Graph, + std::string FileNamePrefix, bool IsSimple = false) { + std::string Filename = FileNamePrefix + "." + 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"; +} + } // end namespace llvm #endif Index: llvm/include/llvm/Analysis/DomPrinter.h =================================================================== --- llvm/include/llvm/Analysis/DomPrinter.h +++ llvm/include/llvm/Analysis/DomPrinter.h @@ -14,6 +14,20 @@ #ifndef LLVM_ANALYSIS_DOMPRINTER_H #define LLVM_ANALYSIS_DOMPRINTER_H +#include "llvm/IR/PassManager.h" + +namespace llvm { +class DomTreePrinterPass : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + +class DomTreeOnlyPrinterPass : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // namespace llvm + namespace llvm { class FunctionPass; FunctionPass *createDomPrinterPass(); Index: llvm/lib/Analysis/DomPrinter.cpp =================================================================== --- llvm/lib/Analysis/DomPrinter.cpp +++ llvm/lib/Analysis/DomPrinter.cpp @@ -80,6 +80,19 @@ }; } +PreservedAnalyses DomTreePrinterPass::run(Function &F, + FunctionAnalysisManager &AM) { + WriteDOTGraphToFile(F, &AM.getResult(F), "dom"); + return PreservedAnalyses::all(); +} + +PreservedAnalyses DomTreeOnlyPrinterPass::run(Function &F, + FunctionAnalysisManager &AM) { + WriteDOTGraphToFile(F, &AM.getResult(F), "domonly", + true); + return PreservedAnalyses::all(); +} + void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) { #ifndef NDEBUG ViewGraph(this, Name, false, Title); Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -36,6 +36,7 @@ #include "llvm/Analysis/DependenceAnalysis.h" #include "llvm/Analysis/DivergenceAnalysis.h" #include "llvm/Analysis/DominanceFrontier.h" +#include "llvm/Analysis/DomPrinter.h" #include "llvm/Analysis/FunctionPropertiesAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/IRSimilarityIdentifier.h" Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -254,6 +254,8 @@ FUNCTION_PASS("dse", DSEPass()) FUNCTION_PASS("dot-cfg", CFGPrinterPass()) FUNCTION_PASS("dot-cfg-only", CFGOnlyPrinterPass()) +FUNCTION_PASS("dot-dom", DomTreePrinterPass()) +FUNCTION_PASS("dot-dom-only", DomTreeOnlyPrinterPass()) FUNCTION_PASS("fix-irreducible", FixIrreduciblePass()) FUNCTION_PASS("flattencfg", FlattenCFGPass()) FUNCTION_PASS("make-guards-explicit", MakeGuardsExplicitPass())