[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