[Mlir-commits] [mlir] 1f67070 - [ViewOpGraph] Improve GraphViz output (#125509)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Feb 7 07:45:51 PST 2025


Author: Eric Hein
Date: 2025-02-07T10:45:47-05:00
New Revision: 1f67070a3f6ca8d0bf5fdca90ceb6b607422c899

URL: https://github.com/llvm/llvm-project/commit/1f67070a3f6ca8d0bf5fdca90ceb6b607422c899
DIFF: https://github.com/llvm/llvm-project/commit/1f67070a3f6ca8d0bf5fdca90ceb6b607422c899.diff

LOG: [ViewOpGraph] Improve GraphViz output (#125509)

This patch improves the GraphViz output of ViewOpGraph
(--view-op-graph).

- Switch to rectangular record-based nodes, inspired by a similar
visualization in [Glow](https://github.com/pytorch/glow). Rectangles
make more efficient use of space when printing text.
- Add input and output ports for each operand and result, and remove
edge labels.
- Switch to a muted color palette to reduce eye strain.

Added: 
    

Modified: 
    mlir/lib/Transforms/ViewOpGraph.cpp
    mlir/test/Transforms/print-op-graph-back-edges.mlir
    mlir/test/Transforms/print-op-graph-cycles.mlir
    mlir/test/Transforms/print-op-graph.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index fa0af7665ba4c4c..75ee3ed74db5edf 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -14,6 +14,7 @@
 #include "mlir/IR/Operation.h"
 #include "mlir/Pass/Pass.h"
 #include "mlir/Support/IndentedOstream.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/GraphWriter.h"
 #include <map>
@@ -29,7 +30,7 @@ using namespace mlir;
 
 static const StringRef kLineStyleControlFlow = "dashed";
 static const StringRef kLineStyleDataFlow = "solid";
-static const StringRef kShapeNode = "ellipse";
+static const StringRef kShapeNode = "Mrecord";
 static const StringRef kShapeNone = "plain";
 
 /// Return the size limits for eliding large attributes.
@@ -49,16 +50,25 @@ static std::string strFromOs(function_ref<void(raw_ostream &)> func) {
   return buf;
 }
 
-/// Escape special characters such as '\n' and quotation marks.
-static std::string escapeString(std::string str) {
-  return strFromOs([&](raw_ostream &os) { os.write_escaped(str); });
-}
-
 /// Put quotation marks around a given string.
 static std::string quoteString(const std::string &str) {
   return "\"" + str + "\"";
 }
 
+/// For Graphviz record nodes:
+/// " Braces, vertical bars and angle brackets must be escaped with a backslash
+/// character if you wish them to appear as a literal character "
+std::string escapeLabelString(const std::string &str) {
+  std::string buf;
+  llvm::raw_string_ostream os(buf);
+  for (char c : str) {
+    if (llvm::is_contained({'{', '|', '<', '}', '>', '\n', '"'}, c))
+      os << '\\';
+    os << c;
+  }
+  return buf;
+}
+
 using AttributeMap = std::map<std::string, std::string>;
 
 namespace {
@@ -79,6 +89,12 @@ struct Node {
   std::optional<int> clusterId;
 };
 
+struct DataFlowEdge {
+  Value value;
+  Node node;
+  std::string port;
+};
+
 /// This pass generates a Graphviz dataflow visualization of an MLIR operation.
 /// Note: See https://www.graphviz.org/doc/info/lang.html for more information
 /// about the Graphviz DOT language.
@@ -107,7 +123,7 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
 private:
   /// Generate a color mapping that will color every operation with the same
   /// name the same way. It'll interpolate the hue in the HSV color-space,
-  /// attempting to keep the contrast suitable for black text.
+  /// using muted colors that provide good contrast for black text.
   template <typename T>
   void initColorMapping(T &irEntity) {
     backgroundColors.clear();
@@ -120,8 +136,10 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
     });
     for (auto indexedOps : llvm::enumerate(ops)) {
       double hue = ((double)indexedOps.index()) / ops.size();
+      // Use lower saturation (0.3) and higher value (0.95) for better
+      // readability
       backgroundColors[indexedOps.value()->getName()].second =
-          std::to_string(hue) + " 1.0 1.0";
+          std::to_string(hue) + " 0.3 0.95";
     }
   }
 
@@ -129,8 +147,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
   /// emitted.
   void emitAllEdgeStmts() {
     if (printDataFlowEdges) {
-      for (const auto &[value, node, label] : dataFlowEdges) {
-        emitEdgeStmt(valueToNode[value], node, label, kLineStyleDataFlow);
+      for (const auto &e : dataFlowEdges) {
+        emitEdgeStmt(valueToNode[e.value], e.node, e.port, kLineStyleDataFlow);
       }
     }
 
@@ -147,8 +165,7 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
     os.indent();
     // Emit invisible anchor node from/to which arrows can be drawn.
     Node anchorNode = emitNodeStmt(" ", kShapeNone);
-    os << attrStmt("label", quoteString(escapeString(std::move(label))))
-       << ";\n";
+    os << attrStmt("label", quoteString(label)) << ";\n";
     builder();
     os.unindent();
     os << "}\n";
@@ -176,7 +193,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
 
     // Always emit splat attributes.
     if (isa<SplatElementsAttr>(attr)) {
-      attr.print(os);
+      os << escapeLabelString(
+          strFromOs([&](raw_ostream &os) { attr.print(os); }));
       return;
     }
 
@@ -184,8 +202,8 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
     auto elements = dyn_cast<ElementsAttr>(attr);
     if (elements && elements.getNumElements() > largeAttrLimit) {
       os << std::string(elements.getShapedType().getRank(), '[') << "..."
-         << std::string(elements.getShapedType().getRank(), ']') << " : "
-         << elements.getType();
+         << std::string(elements.getShapedType().getRank(), ']') << " : ";
+      emitMlirType(os, elements.getType());
       return;
     }
 
@@ -199,19 +217,27 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
     std::string buf;
     llvm::raw_string_ostream ss(buf);
     attr.print(ss);
-    os << truncateString(buf);
+    os << escapeLabelString(truncateString(buf));
+  }
+
+  // Print a truncated and escaped MLIR type to `os`.
+  void emitMlirType(raw_ostream &os, Type type) {
+    std::string buf;
+    llvm::raw_string_ostream ss(buf);
+    type.print(ss);
+    os << escapeLabelString(truncateString(buf));
+  }
+
+  // Print a truncated and escaped MLIR operand to `os`.
+  void emitMlirOperand(raw_ostream &os, Value operand) {
+    operand.printAsOperand(os, OpPrintingFlags());
   }
 
   /// Append an edge to the list of edges.
   /// Note: Edges are written to the output stream via `emitAllEdgeStmts`.
-  void emitEdgeStmt(Node n1, Node n2, std::string label, StringRef style) {
+  void emitEdgeStmt(Node n1, Node n2, std::string port, StringRef style) {
     AttributeMap attrs;
     attrs["style"] = style.str();
-    // Do not label edges that start/end at a cluster boundary. Such edges are
-    // clipped at the boundary, but labels are not. This can lead to labels
-    // floating around without any edge next to them.
-    if (!n1.clusterId && !n2.clusterId)
-      attrs["label"] = quoteString(escapeString(std::move(label)));
     // Use `ltail` and `lhead` to draw edges between clusters.
     if (n1.clusterId)
       attrs["ltail"] = "cluster_" + std::to_string(*n1.clusterId);
@@ -219,7 +245,15 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
       attrs["lhead"] = "cluster_" + std::to_string(*n2.clusterId);
 
     edges.push_back(strFromOs([&](raw_ostream &os) {
-      os << llvm::format("v%i -> v%i ", n1.id, n2.id);
+      os << "v" << n1.id;
+      if (!port.empty() && !n1.clusterId)
+        // Attach edge to south compass point of the result
+        os << ":res" << port << ":s";
+      os << " -> ";
+      os << "v" << n2.id;
+      if (!port.empty() && !n2.clusterId)
+        // Attach edge to north compass point of the operand
+        os << ":arg" << port << ":n";
       emitAttrList(os, attrs);
     }));
   }
@@ -240,11 +274,11 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
                     StringRef background = "") {
     int nodeId = ++counter;
     AttributeMap attrs;
-    attrs["label"] = quoteString(escapeString(std::move(label)));
+    attrs["label"] = quoteString(label);
     attrs["shape"] = shape.str();
     if (!background.empty()) {
       attrs["style"] = "filled";
-      attrs["fillcolor"] = ("\"" + background + "\"").str();
+      attrs["fillcolor"] = quoteString(background.str());
     }
     os << llvm::format("v%i ", nodeId);
     emitAttrList(os, attrs);
@@ -252,8 +286,18 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
     return Node(nodeId);
   }
 
-  /// Generate a label for an operation.
-  std::string getLabel(Operation *op) {
+  std::string getValuePortName(Value operand) {
+    // Print value as an operand and omit the leading '%' character.
+    auto str = strFromOs([&](raw_ostream &os) {
+      operand.printAsOperand(os, OpPrintingFlags());
+    });
+    // Replace % and # with _
+    std::replace(str.begin(), str.end(), '%', '_');
+    std::replace(str.begin(), str.end(), '#', '_');
+    return str;
+  }
+
+  std::string getClusterLabel(Operation *op) {
     return strFromOs([&](raw_ostream &os) {
       // Print operation name and type.
       os << op->getName();
@@ -267,18 +311,73 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
 
       // Print attributes.
       if (printAttrs) {
-        os << "\n";
+        os << "\\l";
+        for (const NamedAttribute &attr : op->getAttrs()) {
+          os << escapeLabelString(attr.getName().getValue().str()) << ": ";
+          emitMlirAttr(os, attr.getValue());
+          os << "\\l";
+        }
+      }
+    });
+  }
+
+  /// Generate a label for an operation.
+  std::string getRecordLabel(Operation *op) {
+    return strFromOs([&](raw_ostream &os) {
+      os << "{";
+
+      // Print operation inputs.
+      if (op->getNumOperands() > 0) {
+        os << "{";
+        auto operandToPort = [&](Value operand) {
+          os << "<arg" << getValuePortName(operand) << "> ";
+          emitMlirOperand(os, operand);
+        };
+        interleave(op->getOperands(), os, operandToPort, "|");
+        os << "}|";
+      }
+      // Print operation name and type.
+      os << op->getName() << "\\l";
+
+      // Print attributes.
+      if (printAttrs && !op->getAttrs().empty()) {
+        // Extra line break to separate attributes from the operation name.
+        os << "\\l";
         for (const NamedAttribute &attr : op->getAttrs()) {
-          os << '\n' << attr.getName().getValue() << ": ";
+          os << attr.getName().getValue() << ": ";
           emitMlirAttr(os, attr.getValue());
+          os << "\\l";
         }
       }
+
+      if (op->getNumResults() > 0) {
+        os << "|{";
+        auto resultToPort = [&](Value result) {
+          os << "<res" << getValuePortName(result) << "> ";
+          emitMlirOperand(os, result);
+          if (printResultTypes) {
+            os << " ";
+            emitMlirType(os, result.getType());
+          }
+        };
+        interleave(op->getResults(), os, resultToPort, "|");
+        os << "}";
+      }
+
+      os << "}";
     });
   }
 
   /// Generate a label for a block argument.
   std::string getLabel(BlockArgument arg) {
-    return "arg" + std::to_string(arg.getArgNumber());
+    return strFromOs([&](raw_ostream &os) {
+      os << "<res" << getValuePortName(arg) << "> ";
+      arg.printAsOperand(os, OpPrintingFlags());
+      if (printResultTypes) {
+        os << " ";
+        emitMlirType(os, arg.getType());
+      }
+    });
   }
 
   /// Process a block. Emit a cluster and one node per block argument and
@@ -287,14 +386,12 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
     emitClusterStmt([&]() {
       for (BlockArgument &blockArg : block.getArguments())
         valueToNode[blockArg] = emitNodeStmt(getLabel(blockArg));
-
       // Emit a node for each operation.
       std::optional<Node> prevNode;
       for (Operation &op : block) {
         Node nextNode = processOperation(&op);
         if (printControlFlowEdges && prevNode)
-          emitEdgeStmt(*prevNode, nextNode, /*label=*/"",
-                       kLineStyleControlFlow);
+          emitEdgeStmt(*prevNode, nextNode, /*port=*/"", kLineStyleControlFlow);
         prevNode = nextNode;
       }
     });
@@ -311,18 +408,19 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
             for (Region &region : op->getRegions())
               processRegion(region);
           },
-          getLabel(op));
+          getClusterLabel(op));
     } else {
-      node = emitNodeStmt(getLabel(op), kShapeNode,
+      node = emitNodeStmt(getRecordLabel(op), kShapeNode,
                           backgroundColors[op->getName()].second);
     }
 
     // Insert data flow edges originating from each operand.
     if (printDataFlowEdges) {
       unsigned numOperands = op->getNumOperands();
-      for (unsigned i = 0; i < numOperands; i++)
-        dataFlowEdges.push_back({op->getOperand(i), node,
-                                 numOperands == 1 ? "" : std::to_string(i)});
+      for (unsigned i = 0; i < numOperands; i++) {
+        auto operand = op->getOperand(i);
+        dataFlowEdges.push_back({operand, node, getValuePortName(operand)});
+      }
     }
 
     for (Value result : op->getResults())
@@ -352,7 +450,7 @@ class PrintOpPass : public impl::ViewOpGraphBase<PrintOpPass> {
   /// 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;
+  std::vector<DataFlowEdge> dataFlowEdges;
   /// Counter for generating unique node/subgraph identifiers.
   int counter = 0;
 

diff  --git a/mlir/test/Transforms/print-op-graph-back-edges.mlir b/mlir/test/Transforms/print-op-graph-back-edges.mlir
index ed922dd7cb13bda..7950125e2f73546 100644
--- a/mlir/test/Transforms/print-op-graph-back-edges.mlir
+++ b/mlir/test/Transforms/print-op-graph-back-edges.mlir
@@ -1,21 +1,21 @@
 // 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.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:   v6 -> v5 [label = "0", style = solid];
-//       DFG:   v7 -> v5 [label = "1", style = solid];
-//       DFG: }
+//  DFG-NEXT:   compound = true;
+//  DFG-NEXT:   subgraph cluster_1 {
+//  DFG-NEXT:     v2 [label = " ", shape = plain];
+//  DFG-NEXT:     label = "builtin.module : ()\l";
+//  DFG-NEXT:     subgraph cluster_3 {
+//  DFG-NEXT:       v4 [label = " ", shape = plain];
+//  DFG-NEXT:       label = "";
+//  DFG-NEXT:       v5 [fillcolor = "0.000000 0.3 0.95", label = "{{\{\{}}<arg_c0> %c0|<arg_c1> %c1}|arith.addi\l\loverflowFlags: #arith.overflow\<none...\l|{<res_0> %0 index}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:       v6 [fillcolor = "0.333333 0.3 0.95", label = "{arith.constant\l\lvalue: 0 : index\l|{<res_c0> %c0 index}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:       v7 [fillcolor = "0.333333 0.3 0.95", label = "{arith.constant\l\lvalue: 1 : index\l|{<res_c1> %c1 index}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:     }
+//  DFG-NEXT:   }
+//  DFG-NEXT:   v6:res_c0:s -> v5:arg_c0:n[style = solid];
+//  DFG-NEXT:   v7:res_c1:s -> v5:arg_c1:n[style = solid];
+//  DFG-NEXT: }
 
 module {
   %add = arith.addi %c0, %c1 : index

diff  --git a/mlir/test/Transforms/print-op-graph-cycles.mlir b/mlir/test/Transforms/print-op-graph-cycles.mlir
index 7e4eb5616a28b39..ba989544419f33b 100644
--- a/mlir/test/Transforms/print-op-graph-cycles.mlir
+++ b/mlir/test/Transforms/print-op-graph-cycles.mlir
@@ -1,45 +1,45 @@
 // 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: }
+//  DFG-NEXT:   compound = true;
+//  DFG-NEXT:   subgraph cluster_1 {
+//  DFG-NEXT:     v2 [label = " ", shape = plain];
+//  DFG-NEXT:     label = "builtin.module : ()\l";
+//  DFG-NEXT:     subgraph cluster_3 {
+//  DFG-NEXT:       v4 [label = " ", shape = plain];
+//  DFG-NEXT:       label = "";
+//  DFG-NEXT:       subgraph cluster_5 {
+//  DFG-NEXT:         v6 [label = " ", shape = plain];
+//  DFG-NEXT:         label = "test.graph_region : ()\l";
+//  DFG-NEXT:         subgraph cluster_7 {
+//  DFG-NEXT:           v8 [label = " ", shape = plain];
+//  DFG-NEXT:           label = "";
+//  DFG-NEXT:           v9 [fillcolor = "0.000000 0.3 0.95", label = "{{\{\{}}<arg_0> %0|<arg_2> %2}|op1\l|{<res_0> %0 i32}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:           subgraph cluster_10 {
+//  DFG-NEXT:             v11 [label = " ", shape = plain];
+//  DFG-NEXT:             label = "test.ssacfg_region : (i32)\l";
+//  DFG-NEXT:             subgraph cluster_12 {
+//  DFG-NEXT:               v13 [label = " ", shape = plain];
+//  DFG-NEXT:               label = "";
+//  DFG-NEXT:               v14 [fillcolor = "0.166667 0.3 0.95", label = "{{\{\{}}<arg_0> %0|<arg_1> %1|<arg_2> %2|<arg_3> %3}|op2\l|{<res_4> %4 i32}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:             }
+//  DFG-NEXT:           }
+//  DFG-NEXT:           v15 [fillcolor = "0.166667 0.3 0.95", label = "{{\{\{}}<arg_0> %0|<arg_3> %3}|op2\l|{<res_2> %2 i32}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:           v16 [fillcolor = "0.500000 0.3 0.95", label = "{{\{\{}}<arg_0> %0}|op3\l|{<res_3> %3 i32}}", shape = Mrecord, style = filled];
+//  DFG-NEXT:         }
+//  DFG-NEXT:       }
+//  DFG-NEXT:     }
+//  DFG-NEXT:   }
+//  DFG-NEXT:   v9:res_0:s -> v9:arg_0:n[style = solid];
+//  DFG-NEXT:   v15:res_2:s -> v9:arg_2:n[style = solid];
+//  DFG-NEXT:   v9:res_0:s -> v14:arg_0:n[style = solid];
+//  DFG-NEXT:   v11 -> v14:arg_1:n[ltail = cluster_10, style = solid];
+//  DFG-NEXT:   v15:res_2:s -> v14:arg_2:n[style = solid];
+//  DFG-NEXT:   v16:res_3:s -> v14:arg_3:n[style = solid];
+//  DFG-NEXT:   v9:res_0:s -> v15:arg_0:n[style = solid];
+//  DFG-NEXT:   v16:res_3:s -> v15:arg_3:n[style = solid];
+//  DFG-NEXT:   v9:res_0:s -> v16:arg_0:n[style = solid];
+//  DFG-NEXT: }
 
 "test.graph_region"() ({ // A Graph region
   %1 = "op1"(%1, %3) : (i32, i32) -> (i32)  // OK: %1, %3 allowed here

diff  --git a/mlir/test/Transforms/print-op-graph.mlir b/mlir/test/Transforms/print-op-graph.mlir
index df03194a663d95f..440b037d780921b 100644
--- a/mlir/test/Transforms/print-op-graph.mlir
+++ b/mlir/test/Transforms/print-op-graph.mlir
@@ -6,49 +6,49 @@
 //       DFG:     subgraph {{.*}}
 //       DFG:       label = "func.func{{.*}}merge_blocks
 //       DFG:       subgraph {{.*}} {
-//       DFG:         v[[ARG0:.*]] [label = "arg0"
+//       DFG:         v[[ARG0:.*]] [label = "<res_arg0> %arg0 i32"
 //       DFG:         v[[CONST10:.*]] [{{.*}}label ={{.*}}10 : i32
 //       DFG:         subgraph [[CLUSTER_MERGE_BLOCKS:.*]] {
 //       DFG:           v[[ANCHOR:.*]] [label = " ", shape = plain]
 //       DFG:           label = "test.merge_blocks
 //       DFG:           subgraph {{.*}} {
-//       DFG:             v[[TEST_BR:.*]] [{{.*}}label = "test.br
+//       DFG:             v[[TEST_BR:.*]] [{{.*}}label = "{{.*}}test.br
 //       DFG:           }
 //       DFG:           subgraph {{.*}} {
 //       DFG:           }
 //       DFG:         }
-//       DFG:         v[[TEST_RET:.*]] [{{.*}}label = "test.return
-//       DFG:   v[[ARG0]] -> v[[TEST_BR]]
-//       DFG:   v[[CONST10]] -> v[[TEST_BR]]
-//       DFG:   v[[ANCHOR]] -> v[[TEST_RET]] [ltail = [[CLUSTER_MERGE_BLOCKS]], style = solid];
-//       DFG:   v[[ANCHOR]] -> v[[TEST_RET]] [ltail = [[CLUSTER_MERGE_BLOCKS]], style = solid];
+//       DFG:         v[[TEST_RET:.*]] [{{.*}}label = "{{.*}}test.return
+//       DFG:   v[[ARG0]]:res_arg0:s -> v[[TEST_BR]]:arg_arg0:n
+//       DFG:   v[[CONST10]]:res_c10_i32:s -> v[[TEST_BR]]
+//       DFG:   v[[ANCHOR]] -> v[[TEST_RET]]:arg_1_0:n[ltail = [[CLUSTER_MERGE_BLOCKS]], style = solid];
+//       DFG:   v[[ANCHOR]] -> v[[TEST_RET]]:arg_1_1:n[ltail = [[CLUSTER_MERGE_BLOCKS]], style = solid];
 
 // CFG-LABEL: digraph G {
 //       CFG:   subgraph {{.*}} {
 //       CFG:     subgraph {{.*}}
 //       CFG:       label = "func.func{{.*}}merge_blocks
 //       CFG:       subgraph {{.*}} {
-//       CFG:         v[[C1:.*]] [{{.*}}label = "arith.constant
-//       CFG:         v[[C2:.*]] [{{.*}}label = "arith.constant
-//       CFG:         v[[C3:.*]] [{{.*}}label = "arith.constant
-//       CFG:         v[[C4:.*]] [{{.*}}label = "arith.constant
-//       CFG:         v[[TEST_FUNC:.*]] [{{.*}}label = "test.func
+//       CFG:         v[[C1:.*]] [{{.*}}label = "{arith.constant
+//       CFG:         v[[C2:.*]] [{{.*}}label = "{arith.constant
+//       CFG:         v[[C3:.*]] [{{.*}}label = "{arith.constant
+//       CFG:         v[[C4:.*]] [{{.*}}label = "{arith.constant
+//       CFG:         v[[TEST_FUNC:.*]] [{{.*}}label = "{test.func
 //       CFG:         subgraph [[CLUSTER_MERGE_BLOCKS:.*]] {
 //       CFG:           v[[ANCHOR:.*]] [label = " ", shape = plain]
 //       CFG:           label = "test.merge_blocks
 //       CFG:           subgraph {{.*}} {
-//       CFG:             v[[TEST_BR:.*]] [{{.*}}label = "test.br
+//       CFG:             v[[TEST_BR:.*]] [{{.*}}label = "{{.*}}test.br
 //       CFG:           }
 //       CFG:           subgraph {{.*}} {
 //       CFG:           }
 //       CFG:         }
-//       CFG:         v[[TEST_RET:.*]] [{{.*}}label = "test.return
+//       CFG:         v[[TEST_RET:.*]] [{{.*}}label = "{{.*}}test.return
 //       CFG:   v[[C1]] -> v[[C2]]
 //       CFG:   v[[C2]] -> v[[C3]]
 //       CFG:   v[[C3]] -> v[[C4]]
 //       CFG:   v[[C4]] -> v[[TEST_FUNC]]
-//       CFG:   v[[TEST_FUNC]] -> v[[ANCHOR]] [lhead = [[CLUSTER_MERGE_BLOCKS]], style = dashed];
-//       CFG:   v[[ANCHOR]] -> v[[TEST_RET]] [ltail = [[CLUSTER_MERGE_BLOCKS]], style = dashed];
+//       CFG:   v[[TEST_FUNC]] -> v[[ANCHOR]][lhead = [[CLUSTER_MERGE_BLOCKS]], style = dashed];
+//       CFG:   v[[ANCHOR]] -> v[[TEST_RET]][ltail = [[CLUSTER_MERGE_BLOCKS]], style = dashed];
 
 func.func @merge_blocks(%arg0: i32, %arg1 : i32) -> () {
   %0 = arith.constant dense<[[0, 1], [2, 3]]> : tensor<2x2xi32>


        


More information about the Mlir-commits mailing list