Skip to content

Commit 3bef17e

Browse files
authored
[mlir] Handle cycles and back edges in --view-op-graph (#82002)
Fixes #62128.
1 parent 80c25da commit 3bef17e

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

mlir/lib/Transforms/ViewOpGraph.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "mlir/IR/Operation.h"
1414
#include "mlir/Pass/Pass.h"
1515
#include "mlir/Support/IndentedOstream.h"
16+
#include "mlir/Transforms/TopologicalSortUtils.h"
1617
#include "llvm/Support/Format.h"
1718
#include "llvm/Support/GraphWriter.h"
1819
#include <map>
@@ -126,6 +127,12 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
126127
/// Emit all edges. This function should be called after all nodes have been
127128
/// emitted.
128129
void emitAllEdgeStmts() {
130+
if (printDataFlowEdges) {
131+
for (const auto &[value, node, label] : dataFlowEdges) {
132+
emitEdgeStmt(valueToNode[value], node, label, kLineStyleDataFlow);
133+
}
134+
}
135+
129136
for (const std::string &edge : edges)
130137
os << edge << ";\n";
131138
edges.clear();
@@ -313,9 +320,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
313320
if (printDataFlowEdges) {
314321
unsigned numOperands = op->getNumOperands();
315322
for (unsigned i = 0; i < numOperands; i++)
316-
emitEdgeStmt(valueToNode[op->getOperand(i)], node,
317-
/*label=*/numOperands == 1 ? "" : std::to_string(i),
318-
kLineStyleDataFlow);
323+
dataFlowEdges.push_back({op->getOperand(i), node,
324+
numOperands == 1 ? "" : std::to_string(i)});
319325
}
320326

321327
for (Value result : op->getResults())
@@ -344,6 +350,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
344350
std::vector<std::string> edges;
345351
/// Mapping of SSA values to Graphviz nodes/clusters.
346352
DenseMap<Value, Node> valueToNode;
353+
/// Output for data flow edges is delayed until the end to handle cycles
354+
std::vector<std::tuple<Value, Node, std::string>> dataFlowEdges;
347355
/// Counter for generating unique node/subgraph identifiers.
348356
int counter = 0;
349357

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: mlir-opt -view-op-graph %s -o %t 2>&1 | FileCheck -check-prefix=DFG %s
2+
3+
// DFG-LABEL: digraph G {
4+
// DFG: compound = true;
5+
// DFG: subgraph cluster_1 {
6+
// DFG: v2 [label = " ", shape = plain];
7+
// DFG: label = "builtin.module : ()\n";
8+
// DFG: subgraph cluster_3 {
9+
// DFG: v4 [label = " ", shape = plain];
10+
// DFG: label = "";
11+
// DFG: v5 [fillcolor = "0.000000 1.0 1.0", label = "arith.addi : (index)\n\noverflowFlags: #arith.overflow<none...", shape = ellipse, style = filled];
12+
// DFG: v6 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 0 : index", shape = ellipse, style = filled];
13+
// DFG: v7 [fillcolor = "0.333333 1.0 1.0", label = "arith.constant : (index)\n\nvalue: 1 : index", shape = ellipse, style = filled];
14+
// DFG: }
15+
// DFG: }
16+
// DFG: v6 -> v5 [label = "0", style = solid];
17+
// DFG: v7 -> v5 [label = "1", style = solid];
18+
// DFG: }
19+
20+
module {
21+
%add = arith.addi %c0, %c1 : index
22+
%c0 = arith.constant 0 : index
23+
%c1 = arith.constant 1 : index
24+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: mlir-opt -view-op-graph -allow-unregistered-dialect %s -o %t 2>&1 | FileCheck -check-prefix=DFG %s
2+
3+
// DFG-LABEL: digraph G {
4+
// DFG: compound = true;
5+
// DFG: subgraph cluster_1 {
6+
// DFG: v2 [label = " ", shape = plain];
7+
// DFG: label = "builtin.module : ()\n";
8+
// DFG: subgraph cluster_3 {
9+
// DFG: v4 [label = " ", shape = plain];
10+
// DFG: label = "";
11+
// DFG: subgraph cluster_5 {
12+
// DFG: v6 [label = " ", shape = plain];
13+
// DFG: label = "test.graph_region : ()\n";
14+
// DFG: subgraph cluster_7 {
15+
// DFG: v8 [label = " ", shape = plain];
16+
// DFG: label = "";
17+
// DFG: v9 [fillcolor = "0.000000 1.0 1.0", label = "op1 : (i32)\n", shape = ellipse, style = filled];
18+
// DFG: subgraph cluster_10 {
19+
// DFG: v11 [label = " ", shape = plain];
20+
// DFG: label = "test.ssacfg_region : (i32)\n";
21+
// DFG: subgraph cluster_12 {
22+
// DFG: v13 [label = " ", shape = plain];
23+
// DFG: label = "";
24+
// DFG: v14 [fillcolor = "0.166667 1.0 1.0", label = "op2 : (i32)\n", shape = ellipse, style = filled];
25+
// DFG: }
26+
// DFG: }
27+
// DFG: v15 [fillcolor = "0.166667 1.0 1.0", label = "op2 : (i32)\n", shape = ellipse, style = filled];
28+
// DFG: v16 [fillcolor = "0.500000 1.0 1.0", label = "op3 : (i32)\n", shape = ellipse, style = filled];
29+
// DFG: }
30+
// DFG: }
31+
// DFG: }
32+
// DFG: }
33+
// DFG: v9 -> v9 [label = "0", style = solid];
34+
// DFG: v15 -> v9 [label = "1", style = solid];
35+
// DFG: v9 -> v14 [label = "0", style = solid];
36+
// DFG: v11 -> v14 [ltail = cluster_10, style = solid];
37+
// DFG: v15 -> v14 [label = "2", style = solid];
38+
// DFG: v16 -> v14 [label = "3", style = solid];
39+
// DFG: v9 -> v15 [label = "0", style = solid];
40+
// DFG: v16 -> v15 [label = "1", style = solid];
41+
// DFG: v9 -> v16 [label = "", style = solid];
42+
// DFG: }
43+
44+
"test.graph_region"() ({ // A Graph region
45+
%1 = "op1"(%1, %3) : (i32, i32) -> (i32) // OK: %1, %3 allowed here
46+
%2 = "test.ssacfg_region"() ({
47+
%5 = "op2"(%1, %2, %3, %4) : (i32, i32, i32, i32) -> (i32) // OK: %1, %2, %3, %4 all defined in the containing region
48+
}) : () -> (i32)
49+
%3 = "op2"(%1, %4) : (i32, i32) -> (i32) // OK: %4 allowed here
50+
%4 = "op3"(%1) : (i32) -> (i32)
51+
}) : () -> ()

0 commit comments

Comments
 (0)