[Mlir-commits] [mlir] [mlir] Handle backedges in --view-op-graph (PR #82002)
Artem Tyurin
llvmlistbot at llvm.org
Sat Feb 17 05:07:28 PST 2024
https://github.com/agentcooper updated https://github.com/llvm/llvm-project/pull/82002
>From 8dc6364a6e68d032d161bf2f9316edf1adf03e41 Mon Sep 17 00:00:00 2001
From: Artem Tyurin <artem.tyurin at gmail.com>
Date: Fri, 16 Feb 2024 16:42:42 +0100
Subject: [PATCH 1/4] [mlir] Handle backedges in --view-op-graph
---
mlir/lib/Transforms/ViewOpGraph.cpp | 3 +++
.../Transforms/print-op-graph-backedges.mlir | 24 +++++++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 mlir/test/Transforms/print-op-graph-backedges.mlir
diff --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index 3d2723839957c4..485f93aeb9c3c4 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -13,6 +13,7 @@
#include "mlir/IR/Operation.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/IndentedOstream.h"
+#include "mlir/Transforms/TopologicalSortUtils.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/GraphWriter.h"
#include <map>
@@ -276,6 +277,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
/// Process a block. Emit a cluster and one node per block argument and
/// operation inside the cluster.
void processBlock(Block &block) {
+ sortTopologically(&block);
+
emitClusterStmt([&]() {
for (BlockArgument &blockArg : block.getArguments())
valueToNode[blockArg] = emitNodeStmt(getLabel(blockArg));
diff --git a/mlir/test/Transforms/print-op-graph-backedges.mlir b/mlir/test/Transforms/print-op-graph-backedges.mlir
new file mode 100644
index 00000000000000..cd03bd0c1c298f
--- /dev/null
+++ b/mlir/test/Transforms/print-op-graph-backedges.mlir
@@ -0,0 +1,24 @@
+// RUN: mlir-opt -view-op-graph %s -o %t 2>&1 | FileCheck -check-prefix=DFG %s
+
+// DFG-LABEL: digraph G {
+// DFG: compound = true;
+// DFG: subgraph cluster_1 {
+// DFG: v2 [label = " ", shape = plain];
+// DFG: label = "builtin.module : ()\n";
+// DFG: subgraph cluster_3 {
+// DFG: v4 [label = " ", shape = plain];
+// DFG: label = "";
+// DFG: v5 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 0 : index", shape = ellipse, style = filled];
+// DFG: v6 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 1 : index", shape = ellipse, style = filled];
+// DFG: v7 [fillcolor = "0.000000 1.0 1.0", label = "arith.addi : (index)\n\noverflowFlags: #arith.overflow<none...", shape = ellipse, style = filled];
+// DFG: }
+// DFG: }
+// DFG: v5 -> v7 [label = "0", style = solid];
+// DFG: v6 -> v7 [label = "1", style = solid];
+// DFG: }
+
+module {
+ %add = arith.addi %c0, %c1 : index
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+}
>From 96abe87d71acff42c34b43b4bf86c4d849b7cb2e Mon Sep 17 00:00:00 2001
From: Artem Tyurin <artem.tyurin at gmail.com>
Date: Sat, 17 Feb 2024 00:24:24 +0100
Subject: [PATCH 2/4] Do not modify existing blocks
---
mlir/lib/Transforms/ViewOpGraph.cpp | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index 485f93aeb9c3c4..8ebd8e631bb57f 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -277,16 +277,20 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
/// Process a block. Emit a cluster and one node per block argument and
/// operation inside the cluster.
void processBlock(Block &block) {
- sortTopologically(&block);
-
emitClusterStmt([&]() {
for (BlockArgument &blockArg : block.getArguments())
valueToNode[blockArg] = emitNodeStmt(getLabel(blockArg));
+ SmallVector<Operation*> sortedOperations;
+ for (Operation &op : block) {
+ sortedOperations.push_back(&op);
+ }
+ computeTopologicalSorting(sortedOperations);
+
// Emit a node for each operation.
std::optional<Node> prevNode;
- for (Operation &op : block) {
- Node nextNode = processOperation(&op);
+ for (Operation *op : sortedOperations) {
+ Node nextNode = processOperation(op);
if (printControlFlowEdges && prevNode)
emitEdgeStmt(*prevNode, nextNode, /*label=*/"",
kLineStyleControlFlow);
>From 51ed372d125e8b55a3f665df0a090b1f7c210e31 Mon Sep 17 00:00:00 2001
From: Artem Tyurin <artem.tyurin at gmail.com>
Date: Sat, 17 Feb 2024 00:25:40 +0100
Subject: [PATCH 3/4] Format code
---
mlir/lib/Transforms/ViewOpGraph.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index 8ebd8e631bb57f..bbd95252ee614d 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -281,7 +281,7 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
for (BlockArgument &blockArg : block.getArguments())
valueToNode[blockArg] = emitNodeStmt(getLabel(blockArg));
- SmallVector<Operation*> sortedOperations;
+ SmallVector<Operation *> sortedOperations;
for (Operation &op : block) {
sortedOperations.push_back(&op);
}
>From e22ffd671479834f1b7bea3db5b189e4680c1ff8 Mon Sep 17 00:00:00 2001
From: Artem Tyurin <artem.tyurin at gmail.com>
Date: Sat, 17 Feb 2024 14:07:11 +0100
Subject: [PATCH 4/4] Handle cycles
---
mlir/lib/Transforms/ViewOpGraph.cpp | 23 +++++----
...es.mlir => print-op-graph-back-edges.mlir} | 10 ++--
.../Transforms/print-op-graph-cycles.mlir | 51 +++++++++++++++++++
3 files changed, 68 insertions(+), 16 deletions(-)
rename mlir/test/Transforms/{print-op-graph-backedges.mlir => print-op-graph-back-edges.mlir} (79%)
create mode 100644 mlir/test/Transforms/print-op-graph-cycles.mlir
diff --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index bbd95252ee614d..c2eb2b893cea4c 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -127,6 +127,12 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
/// Emit all edges. This function should be called after all nodes have been
/// emitted.
void emitAllEdgeStmts() {
+ if (printDataFlowEdges) {
+ for (const auto &[value, node, label] : dataFlowEdges) {
+ emitEdgeStmt(valueToNode[value], node, label, kLineStyleDataFlow);
+ }
+ }
+
for (const std::string &edge : edges)
os << edge << ";\n";
edges.clear();
@@ -281,16 +287,10 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
for (BlockArgument &blockArg : block.getArguments())
valueToNode[blockArg] = emitNodeStmt(getLabel(blockArg));
- SmallVector<Operation *> sortedOperations;
- for (Operation &op : block) {
- sortedOperations.push_back(&op);
- }
- computeTopologicalSorting(sortedOperations);
-
// Emit a node for each operation.
std::optional<Node> prevNode;
- for (Operation *op : sortedOperations) {
- Node nextNode = processOperation(op);
+ for (Operation &op : block) {
+ Node nextNode = processOperation(&op);
if (printControlFlowEdges && prevNode)
emitEdgeStmt(*prevNode, nextNode, /*label=*/"",
kLineStyleControlFlow);
@@ -320,9 +320,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
if (printDataFlowEdges) {
unsigned numOperands = op->getNumOperands();
for (unsigned i = 0; i < numOperands; i++)
- emitEdgeStmt(valueToNode[op->getOperand(i)], node,
- /*label=*/numOperands == 1 ? "" : std::to_string(i),
- kLineStyleDataFlow);
+ dataFlowEdges.push_back({op->getOperand(i), node,
+ numOperands == 1 ? "" : std::to_string(i)});
}
for (Value result : op->getResults())
@@ -351,6 +350,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
std::vector<std::string> edges;
/// Mapping of SSA values to Graphviz nodes/clusters.
DenseMap<Value, Node> valueToNode;
+ /// Output for data flow edges is delayed until the end to handle cycles
+ std::vector<std::tuple<Value, Node, std::string>> dataFlowEdges;
/// Counter for generating unique node/subgraph identifiers.
int counter = 0;
diff --git a/mlir/test/Transforms/print-op-graph-backedges.mlir b/mlir/test/Transforms/print-op-graph-back-edges.mlir
similarity index 79%
rename from mlir/test/Transforms/print-op-graph-backedges.mlir
rename to mlir/test/Transforms/print-op-graph-back-edges.mlir
index cd03bd0c1c298f..ed922dd7cb13bd 100644
--- a/mlir/test/Transforms/print-op-graph-backedges.mlir
+++ b/mlir/test/Transforms/print-op-graph-back-edges.mlir
@@ -8,13 +8,13 @@
// DFG: subgraph cluster_3 {
// DFG: v4 [label = " ", shape = plain];
// DFG: label = "";
-// DFG: v5 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 0 : index", shape = ellipse, style = filled];
-// DFG: v6 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 1 : index", shape = ellipse, style = filled];
-// DFG: v7 [fillcolor = "0.000000 1.0 1.0", label = "arith.addi : (index)\n\noverflowFlags: #arith.overflow<none...", shape = ellipse, style = filled];
+// DFG: v5 [fillcolor = "0.000000 1.0 1.0", label = "arith.addi : (index)\n\noverflowFlags: #arith.overflow<none...", shape = ellipse, style = filled];
+// DFG: v6 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 0 : index", shape = ellipse, style = filled];
+// DFG: v7 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 1 : index", shape = ellipse, style = filled];
// DFG: }
// DFG: }
-// DFG: v5 -> v7 [label = "0", style = solid];
-// DFG: v6 -> v7 [label = "1", style = solid];
+// DFG: v6 -> v5 [label = "0", style = solid];
+// DFG: v7 -> v5 [label = "1", style = solid];
// DFG: }
module {
diff --git a/mlir/test/Transforms/print-op-graph-cycles.mlir b/mlir/test/Transforms/print-op-graph-cycles.mlir
new file mode 100644
index 00000000000000..7e4eb5616a28b3
--- /dev/null
+++ b/mlir/test/Transforms/print-op-graph-cycles.mlir
@@ -0,0 +1,51 @@
+// RUN: mlir-opt -view-op-graph -allow-unregistered-dialect %s -o %t 2>&1 | FileCheck -check-prefix=DFG %s
+
+// DFG-LABEL: digraph G {
+// DFG: compound = true;
+// DFG: subgraph cluster_1 {
+// DFG: v2 [label = " ", shape = plain];
+// DFG: label = "builtin.module : ()\n";
+// DFG: subgraph cluster_3 {
+// DFG: v4 [label = " ", shape = plain];
+// DFG: label = "";
+// DFG: subgraph cluster_5 {
+// DFG: v6 [label = " ", shape = plain];
+// DFG: label = "test.graph_region : ()\n";
+// DFG: subgraph cluster_7 {
+// DFG: v8 [label = " ", shape = plain];
+// DFG: label = "";
+// DFG: v9 [fillcolor = "0.000000 1.0 1.0", label = "op1 : (i32)\n", shape = ellipse, style = filled];
+// DFG: subgraph cluster_10 {
+// DFG: v11 [label = " ", shape = plain];
+// DFG: label = "test.ssacfg_region : (i32)\n";
+// DFG: subgraph cluster_12 {
+// DFG: v13 [label = " ", shape = plain];
+// DFG: label = "";
+// DFG: v14 [fillcolor = "0.166667 1.0 1.0", label = "op2 : (i32)\n", shape = ellipse, style = filled];
+// DFG: }
+// DFG: }
+// DFG: v15 [fillcolor = "0.166667 1.0 1.0", label = "op2 : (i32)\n", shape = ellipse, style = filled];
+// DFG: v16 [fillcolor = "0.500000 1.0 1.0", label = "op3 : (i32)\n", shape = ellipse, style = filled];
+// DFG: }
+// DFG: }
+// DFG: }
+// DFG: }
+// DFG: v9 -> v9 [label = "0", style = solid];
+// DFG: v15 -> v9 [label = "1", style = solid];
+// DFG: v9 -> v14 [label = "0", style = solid];
+// DFG: v11 -> v14 [ltail = cluster_10, style = solid];
+// DFG: v15 -> v14 [label = "2", style = solid];
+// DFG: v16 -> v14 [label = "3", style = solid];
+// DFG: v9 -> v15 [label = "0", style = solid];
+// DFG: v16 -> v15 [label = "1", style = solid];
+// DFG: v9 -> v16 [label = "", style = solid];
+// DFG: }
+
+"test.graph_region"() ({ // A Graph region
+ %1 = "op1"(%1, %3) : (i32, i32) -> (i32) // OK: %1, %3 allowed here
+ %2 = "test.ssacfg_region"() ({
+ %5 = "op2"(%1, %2, %3, %4) : (i32, i32, i32, i32) -> (i32) // OK: %1, %2, %3, %4 all defined in the containing region
+ }) : () -> (i32)
+ %3 = "op2"(%1, %4) : (i32, i32) -> (i32) // OK: %4 allowed here
+ %4 = "op3"(%1) : (i32) -> (i32)
+}) : () -> ()
More information about the Mlir-commits
mailing list