[llvm] 524abc6 - Introduce NewPM .dot printers for DomTree

Daniil Suchkov via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 5 15:29:22 PST 2022


Author: Daniil Suchkov
Date: 2022-01-05T23:25:40Z
New Revision: 524abc68f231101996e8142aadb3f382fe40d20b

URL: https://github.com/llvm/llvm-project/commit/524abc68f231101996e8142aadb3f382fe40d20b
DIFF: https://github.com/llvm/llvm-project/commit/524abc68f231101996e8142aadb3f382fe40d20b.diff

LOG: Introduce NewPM .dot printers for DomTree

This patch adds a couple of NewPM function passes (dot-dom and
dot-dom-only) that dump DomTree into .dot files.

Reviewed-By: aeubanks
Differential Revision: https://reviews.llvm.org/D116629

Added: 
    llvm/test/Analysis/Dominators/print-dot-dom.ll

Modified: 
    llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
    llvm/include/llvm/Analysis/DomPrinter.h
    llvm/lib/Analysis/DomPrinter.cpp
    llvm/lib/Passes/PassBuilder.cpp
    llvm/lib/Passes/PassRegistry.def

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h b/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
index 59737744f5767..d8021907b5b22 100644
--- a/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
+++ b/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -181,6 +181,25 @@ class DOTGraphTraitsModulePrinter : public ModulePass {
   std::string Name;
 };
 
+template <typename GraphT>
+void WriteDOTGraphToFile(Function &F, GraphT &&Graph,
+                         std::string FileNamePrefix, bool IsSimple) {
+  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<GraphT>::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

diff  --git a/llvm/include/llvm/Analysis/DomPrinter.h b/llvm/include/llvm/Analysis/DomPrinter.h
index a177f877b2952..e6df12d880726 100644
--- a/llvm/include/llvm/Analysis/DomPrinter.h
+++ b/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<DomTreePrinterPass> {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+class DomTreeOnlyPrinterPass : public PassInfoMixin<DomTreeOnlyPrinterPass> {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // namespace llvm
+
 namespace llvm {
   class FunctionPass;
   FunctionPass *createDomPrinterPass();

diff  --git a/llvm/lib/Analysis/DomPrinter.cpp b/llvm/lib/Analysis/DomPrinter.cpp
index ebbe0d3e2c5fb..6088de53028dd 100644
--- a/llvm/lib/Analysis/DomPrinter.cpp
+++ b/llvm/lib/Analysis/DomPrinter.cpp
@@ -80,6 +80,19 @@ struct DOTGraphTraits<PostDominatorTree*>
 };
 }
 
+PreservedAnalyses DomTreePrinterPass::run(Function &F,
+                                          FunctionAnalysisManager &AM) {
+  WriteDOTGraphToFile(F, &AM.getResult<DominatorTreeAnalysis>(F), "dom", false);
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses DomTreeOnlyPrinterPass::run(Function &F,
+                                              FunctionAnalysisManager &AM) {
+  WriteDOTGraphToFile(F, &AM.getResult<DominatorTreeAnalysis>(F), "domonly",
+                      true);
+  return PreservedAnalyses::all();
+}
+
 void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
 #ifndef NDEBUG
   ViewGraph(this, Name, false, Title);

diff  --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index d7615ef4e9bfa..6fdddff864036 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -35,6 +35,7 @@
 #include "llvm/Analysis/DemandedBits.h"
 #include "llvm/Analysis/DependenceAnalysis.h"
 #include "llvm/Analysis/DivergenceAnalysis.h"
+#include "llvm/Analysis/DomPrinter.h"
 #include "llvm/Analysis/DominanceFrontier.h"
 #include "llvm/Analysis/FunctionPropertiesAnalysis.h"
 #include "llvm/Analysis/GlobalsModRef.h"

diff  --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 74613a7fcce06..2fc4fa25897f7 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -254,6 +254,8 @@ FUNCTION_PASS("div-rem-pairs", DivRemPairsPass())
 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())

diff  --git a/llvm/test/Analysis/Dominators/print-dot-dom.ll b/llvm/test/Analysis/Dominators/print-dot-dom.ll
new file mode 100644
index 0000000000000..faad5a6a51db1
--- /dev/null
+++ b/llvm/test/Analysis/Dominators/print-dot-dom.ll
@@ -0,0 +1,71 @@
+; RUN: opt %s -passes=dot-dom -disable-output
+; RUN: FileCheck %s -input-file=dom.test1.dot -check-prefix=TEST1
+; RUN: FileCheck %s -input-file=dom.test2.dot -check-prefix=TEST2
+
+define void @test1() {
+; TEST1: digraph "Dominator tree for 'test1' function"
+; TEST1-NEXT: label="Dominator tree for 'test1' function"
+; TEST1:      Node0x[[EntryID:.*]] [shape=record,label="{entry:
+; TEST1-NEXT: Node0x[[EntryID]] -> Node0x[[A_ID:.*]];
+; TEST1-NEXT: Node0x[[EntryID]] -> Node0x[[C_ID:.*]];
+; TEST1-NEXT: Node0x[[EntryID]] -> Node0x[[B_ID:.*]];
+; TEST1-NEXT: Node0x[[A_ID]] [shape=record,label="{a:
+; TEST1-NEXT: Node0x[[C_ID]] [shape=record,label="{c:
+; TEST1-NEXT: Node0x[[C_ID]] -> Node0x[[D_ID:.*]];
+; TEST1-NEXT: Node0x[[C_ID]] -> Node0x[[E_ID:.*]];
+; TEST1-NEXT: Node0x[[D_ID]] [shape=record,label="{d:
+; TEST1-NEXT: Node0x[[E_ID]] [shape=record,label="{e:
+; TEST1-NEXT: Node0x[[B_ID]] [shape=record,label="{b:
+
+entry:
+  br i1 undef, label %a, label %b
+
+a:
+  br label %c
+
+b:
+  br label %c
+
+c:
+  br i1 undef, label %d, label %e
+
+d:
+  ret void
+
+e:
+  ret void
+}
+
+define void @test2() {
+; TEST2: digraph "Dominator tree for 'test2' function"
+; TEST2-NEXT: label="Dominator tree for 'test2' function"
+; TEST2: Node0x[[EntryID:.*]] [shape=record,label="{entry:
+; TEST2-NEXT: Node0x[[EntryID]] -> Node0x[[A_ID:.*]];
+; TEST2-NEXT: Node0x[[A_ID]] [shape=record,label="{a:
+; TEST2-NEXT: Node0x[[A_ID]] -> Node0x[[B_ID:.*]];
+; TEST2-NEXT: Node0x[[B_ID]] [shape=record,label="{b:
+; TEST2-NEXT: Node0x[[B_ID]] -> Node0x[[C_ID:.*]];
+; TEST2-NEXT: Node0x[[C_ID]] [shape=record,label="{c:
+; TEST2-NEXT: Node0x[[C_ID]] -> Node0x[[D_ID:.*]];
+; TEST2-NEXT: Node0x[[C_ID]] -> Node0x[[E_ID:.*]];
+; TEST2-NEXT: Node0x[[D_ID]] [shape=record,label="{d:
+; TEST2-NEXT: Node0x[[E_ID]] [shape=record,label="{e:
+
+entry:
+  br label %a
+
+a:
+  br label %b
+
+b:
+  br i1 undef, label %a, label %c
+
+c:
+  br i1 undef, label %d, label %e
+
+d:
+  br i1 undef, label %a, label %e
+
+e:
+  ret void
+}


        


More information about the llvm-commits mailing list