[mlir][transform] Add PrintOp to transform dialect
authorMatthias Springer <springerm@google.com>
Wed, 2 Nov 2022 09:09:46 +0000 (10:09 +0100)
committerMatthias Springer <springerm@google.com>
Wed, 2 Nov 2022 09:12:05 +0000 (10:12 +0100)
This op dumps the associated payload IR to stderr. It has proven useful for printf-style debugging.

Differential Revision: https://reviews.llvm.org/D137151

mlir/include/mlir/Dialect/Transform/IR/TransformOps.td
mlir/lib/Dialect/Transform/IR/TransformOps.cpp
mlir/test/Dialect/Transform/ops.mlir

index bc20edf..4b1bb02 100644 (file)
@@ -290,6 +290,25 @@ def PDLMatchOp : TransformDialectOp<"pdl_match",
                        "functional-type(operands, results)";
 }
 
+def PrintOp : TransformDialectOp<"print",
+    [DeclareOpInterfaceMethods<TransformOpInterface>,
+     DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+  let summary = "Dump each payload op";
+  let description = [{
+    This op dumps each payload op that is associated with the `target` operand
+    to stderr. It also prints the `name` string attribute. If no target is
+    specified, the top-level op is dumped.
+
+    This op is useful for printf-style debugging.
+  }];
+
+  let arguments = (ins Optional<TransformTypeInterface>:$target,
+                       OptionalAttr<StrAttr>:$name);
+  let results = (outs);
+  let assemblyFormat = "$target attr-dict (`:` type($target)^)?";
+}
+
+
 def ReplicateOp : TransformDialectOp<"replicate",
     [DeclareOpInterfaceMethods<TransformOpInterface>,
      DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
index 9d9f1ea..2be1bea 100644 (file)
@@ -807,3 +807,37 @@ LogicalResult transform::WithPDLPatternsOp::verify() {
 
   return success();
 }
+
+//===----------------------------------------------------------------------===//
+// PrintOp
+//===----------------------------------------------------------------------===//
+
+DiagnosedSilenceableFailure
+transform::PrintOp::apply(transform::TransformResults &results,
+                          transform::TransformState &state) {
+  llvm::errs() << "[[[ IR printer: ";
+  if (getName().has_value())
+    llvm::errs() << *getName() << " ";
+
+  if (!getTarget()) {
+    llvm::errs() << "top-level ]]]\n" << *state.getTopLevel() << "\n";
+    return DiagnosedSilenceableFailure::success();
+  }
+
+  llvm::errs() << "]]]\n";
+  ArrayRef<Operation *> targets = state.getPayloadOps(getTarget());
+  for (Operation *target : targets)
+    llvm::errs() << *target << "\n";
+
+  return DiagnosedSilenceableFailure::success();
+}
+
+void transform::PrintOp::getEffects(
+    SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
+  onlyReadsHandle(getTarget(), effects);
+  onlyReadsPayload(effects);
+
+  // There is no resource for stderr file descriptor, so just declare print
+  // writes into the default resource.
+  effects.emplace_back(MemoryEffects::Write::get());
+}
index 506fce0..0d27f92 100644 (file)
@@ -67,3 +67,16 @@ transform.sequence failures(propagate) {
   // CHECK: cast %{{.*}} : !transform.any_op to !transform.op<"builtin.module">
   %1 = cast %0: !transform.any_op to !transform.op<"builtin.module">
 }
+
+// CHECK: transform.sequence
+// CHECK: print
+// CHECK: print
+// CHECK: print
+// CHECK: print
+transform.sequence failures(propagate) {
+^bb0(%arg0: !pdl.operation):
+  transform.print %arg0 : !pdl.operation
+  transform.print
+  transform.print %arg0 {name = "test"} : !pdl.operation
+  transform.print {name = "test"}
+}