diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td --- a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.td @@ -290,6 +290,25 @@ "functional-type(operands, results)"; } +def PrintOp : TransformDialectOp<"print", + [DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods]> { + 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:$target, + OptionalAttr:$name); + let results = (outs); + let assemblyFormat = "$target attr-dict (`:` type($target)^)?"; +} + + def ReplicateOp : TransformDialectOp<"replicate", [DeclareOpInterfaceMethods, DeclareOpInterfaceMethods, diff --git a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp --- a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp @@ -807,3 +807,41 @@ 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"; + // dump() prints to stderr. + state.getTopLevel()->dump(); + return DiagnosedSilenceableFailure::success(); + } + + llvm::errs() << "]]]\n"; + ArrayRef targets = state.getPayloadOps(getTarget()); + for (Operation *target : targets) + target->dump(); + + return DiagnosedSilenceableFailure::success(); +} + +void transform::PrintOp::getEffects( + SmallVectorImpl &effects) { + effects.emplace_back(MemoryEffects::Read::get(), getTarget(), + mlir::transform::TransformMappingResource::get()); + effects.emplace_back(MemoryEffects::Read::get(), + mlir::transform::PayloadIRResource::get()); + + // There is no resource for stderr file descriptor, so just declare print + // writes into the default resource. + effects.emplace_back(MemoryEffects::Write::get()); +} diff --git a/mlir/test/Dialect/Transform/ops.mlir b/mlir/test/Dialect/Transform/ops.mlir --- a/mlir/test/Dialect/Transform/ops.mlir +++ b/mlir/test/Dialect/Transform/ops.mlir @@ -67,3 +67,16 @@ // 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"} +}