[mlir][transform] Add VerifyOp

This transform op runs the verifier on the targeted payload ops. It is for debugging only.

Differential Revision: https://reviews.llvm.org/D154711
This commit is contained in:
Matthias Springer 2023-07-07 15:14:31 +02:00
parent 9a317516a5
commit 7dfcd4b7c9
5 changed files with 125 additions and 1 deletions

View File

@ -962,6 +962,36 @@ def SequenceOp : TransformDialectOp<"sequence",
let hasVerifier = 1;
}
def VerifyOp : TransformDialectOp<"verify",
[TransformOpInterface, TransformEachOpTrait,
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
ReportTrackingListenerFailuresOpTrait]> {
let summary = "Verifies the targeted ops";
let description = [{
This transform verifies the targeted ops. If at least one op fails to
verify, the transform fails definitely.
Note: This op was designed for debugging purposes and should be used like an
assertion. It is intentional that this op produces a definite failure and
not a silenceable one. Correctness of the program should not depend on this
op.
This transform reads the target handle.
}];
let arguments = (ins TransformHandleTypeInterface:$target);
let results = (outs);
let assemblyFormat = "$target attr-dict `:` type($target)";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
}];
}
def YieldOp : TransformDialectOp<"yield",
[Terminator, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
let summary = "Yields operation handles from a transform IR region";

View File

@ -17,6 +17,7 @@
#include "mlir/IR/Dominance.h"
#include "mlir/IR/FunctionImplementation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/Verifier.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
@ -2019,6 +2020,29 @@ void transform::PrintOp::getEffects(
effects.emplace_back(MemoryEffects::Write::get());
}
//===----------------------------------------------------------------------===//
// VerifyOp
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
transform::VerifyOp::applyToOne(transform::TransformRewriter &rewriter,
Operation *target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
if (failed(::mlir::verify(target))) {
DiagnosedDefiniteFailure diag = emitDefiniteFailure()
<< "failed to verify payload op";
diag.attachNote(target->getLoc()) << "payload op";
return diag;
}
return DiagnosedSilenceableFailure::success();
}
void transform::VerifyOp::getEffects(
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
transform::onlyReadsHandle(getTarget(), effects);
}
//===----------------------------------------------------------------------===//
// YieldOp
//===----------------------------------------------------------------------===//

View File

@ -1917,3 +1917,31 @@ transform.sequence failures(propagate) {
// CHECK: test_produce_param(#{{.*}}) : !transform.affine_map
transform.test_produce_param(affine_map<(d0) -> ()>) : !transform.affine_map
}
// -----
func.func @verify_success(%arg0: f64) -> f64 {
return %arg0 : f64
}
transform.sequence failures(propagate) {
^bb0(%arg0: !transform.any_op):
%0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op
transform.verify %0 : !transform.any_op
}
// -----
// expected-error @below{{fail_to_verify is set}}
// expected-note @below{{payload op}}
func.func @verify_failure(%arg0: f64) -> f64 {
return %arg0 : f64
}
transform.sequence failures(propagate) {
^bb0(%arg0: !transform.any_op):
%0 = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op
transform.test_produce_invalid_ir %0 : !transform.any_op
// expected-error @below{{failed to verify payload op}}
transform.verify %0 : !transform.any_op
}

View File

@ -747,6 +747,12 @@ void mlir::test::TestDummyPayloadOp::getEffects(
transform::producesHandle(result, effects);
}
LogicalResult mlir::test::TestDummyPayloadOp::verify() {
if (getFailToVerify())
return emitOpError() << "fail_to_verify is set";
return success();
}
DiagnosedSilenceableFailure
mlir::test::TestTrackedRewriteOp::apply(transform::TransformRewriter &rewriter,
transform::TransformResults &results,
@ -892,6 +898,23 @@ void mlir::test::TestNotifyPayloadOpReplacedOp::getEffects(
transform::onlyReadsHandle(getReplacement(), effects);
}
DiagnosedSilenceableFailure mlir::test::TestProduceInvalidIR::applyToOne(
transform::TransformRewriter &rewriter, Operation *target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
// Provide some IR that does not verify.
rewriter.setInsertionPointToStart(&target->getRegion(0).front());
rewriter.create<TestDummyPayloadOp>(target->getLoc(), TypeRange(),
ValueRange(), /*failToVerify=*/true);
return DiagnosedSilenceableFailure::success();
}
void mlir::test::TestProduceInvalidIR::getEffects(
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
transform::onlyReadsHandle(getTarget(), effects);
transform::modifiesPayload(effects);
}
namespace {
/// Test extension of the Transform dialect. Registers additional ops and
/// declares PDL as dependent dialect since the additional ops are using PDL

View File

@ -518,10 +518,12 @@ def TestDummyPayloadOp
: Op<Transform_Dialect, "test_dummy_payload_op",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
TransformOpInterface]> {
let arguments = (ins Variadic<AnyType>:$args);
let arguments = (ins Variadic<AnyType>:$args,
UnitAttr:$fail_to_verify);
let results = (outs Variadic<AnyType>:$outs);
let assemblyFormat = "$args attr-dict `:` functional-type(operands, results)";
let cppNamespace = "::mlir::test";
let hasVerifier = 1;
let extraClassDeclaration = [{
DiagnosedSilenceableFailure apply(transform::TransformRewriter &rewriter,
@ -574,4 +576,21 @@ def TestNotifyPayloadOpReplacedOp
let cppNamespace = "::mlir::test";
}
def TestProduceInvalidIR
: Op<Transform_Dialect, "test_produce_invalid_ir",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
TransformOpInterface, TransformEachOpTrait]> {
let arguments = (ins TransformHandleTypeInterface:$target);
let results = (outs);
let assemblyFormat = "$target attr-dict `:` type($target)";
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
}];
}
#endif // MLIR_TESTTRANSFORMDIALECTEXTENSION_TD