All `apply` functions now have a `TransformRewriter &` parameter. This rewriter should be used to modify the IR. It has a `TrackingListener` attached and updates the internal handle-payload mappings based on rewrites.
Implementations no longer need to create their own `TrackingListener` and `IRRewriter`. Error checking is integrated into `applyTransform`. Tracking listener errors are reported only for ops with the `ReportTrackingListenerFailuresOpTrait` trait attached, allowing for a gradual migration. Furthermore, errors can be silenced with an op attribute.
Additional API will be added to `TransformRewriter` in subsequent revisions. This revision just adds an "empty" `TransformRewriter` class and updates all `apply` implementations.
Differential Revision: https://reviews.llvm.org/D152427
Note that the “add” elementwise operation is indicated as payload ancestor because it was used to produce the tile loop, and the loop therefore has its location.
Finally, we would like to replace the call to the outlined function with a call to the microkernel. Unfortunately, the Transform dialect doesn’t have support for this transformation (and cannot have if the call is rewritten to a custom, out-of-tree operation). Therefore, we need to define new transform operations. The next chapters will describe how this can be done.
+
+## Tracking IR Modifications
+
+The transform dialect automatically tracks all IR changes that are made as part
+of transform ops. (Implementations must use the provided rewriter to modify IR.)
+If a payload op is erased, it is automatically removed from all handles that it
+is currently associated with. If a payload op is replaced, the transform dialect
+tries to find the replacement op and updates all handles accordingly. If a
+multi-result op is replaced with values that are defined by multiple ops, or if
+an op is replaced with an op of a different type, an error is produced. This is
+because it is unclear whether the direct replacements actually represent the
+computation of the original op. There are ways to customize this behavior. More
+details can be found at the documentation of `transform::TrackingListener`.
}
```
-To finalize the definition of the transform operation, we need to implement the interface methods. The `TransformOpInterface` currently requires only one method – `apply` – that performs the actual transformation. It is a good practice to limit the body of the method to manipulation of the Transform dialect constructs and have the actual transformation implemented as a standalone function so it can be used from other places in the code.
-
+To finalize the definition of the transform operation, we need to implement the
+interface methods. The `TransformOpInterface` currently requires only one method
+– `apply` – that performs the actual transformation. It is a good practice to
+limit the body of the method to manipulation of the Transform dialect constructs
+and have the actual transformation implemented as a standalone function so it
+can be used from other places in the code. Similar to rewrite patterns, all IR
+must be modified with the provided rewriter.
```c++
// In MyExtension.cpp
// Implementation of our transform dialect operation.
// This operation returns a tri-state result that can be one of:
// - success when the transformation succeeded;
-// - definite failure when the transformation failed in such a way that following
-// transformations are impossible or undesirable, typically it could have left payload
-// IR in an invalid state; it is expected that a diagnostic is emitted immediately
-// before returning the definite error;
-// - silenceable failure when the transformation failed but following transformations
-// are still applicable, typically this means a precondition for the transformation is
-// not satisfied and the payload IR has not been modified.
-// The silenceable failure additionally carries a Diagnostic that can be emitted to the
-// user.
-::mlir::DiagnosedSilenceableFailure ChangeCallTargetOp::apply(
- // The list of payload IR entities that will be associated with the transform IR
- // values defined by this transform operation. In this case, it can remain empty as
- // there are no results.
+// - definite failure when the transformation failed in such a way that
+// following transformations are impossible or undesirable, typically it could
+// have left payload IR in an invalid state; it is expected that a diagnostic
+// is emitted immediately before returning the definite error;
+// - silenceable failure when the transformation failed but following
+// transformations are still applicable, typically this means a precondition
+// for the transformation is not satisfied and the payload IR has not been
+// modified. The silenceable failure additionally carries a Diagnostic that
+// can be emitted to the user.
+::mlir::DiagnosedSilenceableFailure mlir::transform::ChangeCallTargetOp::apply(
+ // The rewriter that should be used when modifying IR.
+ ::mlir::transform::TransformRewriter &rewriter,
+ // The list of payload IR entities that will be associated with the
+ // transform IR values defined by this transform operation. In this case, it
+ // can remain empty as there are no results.
::mlir::transform::TransformResults &results,
- // The transform application state. This object can be used to query the current
- // associations between transform IR values and payload IR entities. It can also
- // carry additional user-defined state.
+ // The transform application state. This object can be used to query the
+ // current associations between transform IR values and payload IR entities.
+ // It can also carry additional user-defined state.
::mlir::transform::TransformState &state) {
- // First, we need to obtain the list of payload operations that are associated with
+ // First, we need to obtain the list of payload operations that are associated with
// the operand handle.
auto payload = state.getPayloadOps(getCall());
-
- // Then, we iterate over the list of operands and call the actual IR-mutating
+
+ // Then, we iterate over the list of operands and call the actual IR-mutating
// function. We also check the preconditions here.
for (Operation *payloadOp : payload) {
auto call = dyn_cast<::mlir::func::CallOp>(payloadOp);
diag.attachNote(payloadOp->getLoc()) << "offending payload";
return diag;
}
-
+
updateCallee(call, getNewTarget());
}
// Define the new operation. By convention, prefix its name with the name of the dialect extension, "my.". The full operation name will be further prefixed with "transform.".
def ChangeCallTargetOp : Op<Transform_Dialect, "my.change_call_target",
// Indicate that the operation implements the required TransformOpInterface and
- // MemoryEffectsOpInterface. Use the TransformEach trait to provide the
+ // MemoryEffectsOpInterface. Use the TransformEach trait to provide the
// implementation for TransformOpInterface.
[TransformOpInterface, TransformEachOpTrait,
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
- // Provide a brief and a full description. It is recommended that the latter describes
+ // Provide a brief and a full description. It is recommended that the latter describes
// the effects on the operands and how the operation processes various failure modes.
let summary = "Changes the callee of a call operation to the specified one";
let description = [{
- For each `func.call` payload operation associated with the handle, changes its
+ For each `func.call` payload operation associated with the handle, changes its
callee to be the symbol whose name is provided as an attribute to this operation.
- Generates a silenceable failure if the operand is associated with payload operations
+ Generates a silenceable failure if the operand is associated with payload operations
that are not `func.call`.
Only reads the operand.
}];
- // The arguments include the handle to the payload operations and the attribute that
- // specifies the new callee. The handle must implement TransformHandleTypeInterface.
- // We use a string attribute as the symbol may not exist in the transform IR so the
- // verification may fail.
+ // The arguments include the handle to the payload operations and the attribute that
+ // specifies the new callee. The handle must implement TransformHandleTypeInterface.
+ // We use a string attribute as the symbol may not exist in the transform IR so the
+ // verification may fail.
let arguments = (ins
Transform_ConcreteOpType<"func.call">:$call,
StrAttr:$new_target);
// Declare the function implementing the interface for a single payload operation.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::func::CallOp call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
```c++
::mlir::DiagnosedSilenceableFailure ChangeCallTargetOp::applyToOne(
- ::mlir::func::CallOp call,,
+ ::mlir::transform::TransformRewriter &rewriter,
+ ::mlir::func::CallOp call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state) {
// Call the actual transformation function.
As an exercise, let us modify the rewriting operation to consume the operand. This would be necessary, for example, if the transformation were to rewrite the `func.call` operation into a custom operation `my.mm4`. Since the operand handle is now consumed, the operation can return a new handle to the newly produced payload operation. Otherwise, the ODS definition of the transform operation remains unchanged.
-
```tablegen
// In MyExtension.td.
// Define another transform operation.
def CallToOp : Op<Transform_Dialect, "my.call_to_op",
// Indicate that the operation implements the required TransformOpInterface and
- // MemoryEffectsOpInterface. Use the TransformEach trait to provide the
+ // MemoryEffectsOpInterface. Use the TransformEach trait to provide the
// implementation for TransformOpInterface.
[TransformOpInterface, TransformEachOpTrait,
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
// The argument is the handle to the payload operations.
let arguments = (ins CallOpInterfaceHandle:$call);
- // The result is the handle to the payload operations produced during the
+ // The result is the handle to the payload operations produced during the
// transformation.
let results = (outs TransformHandleTypeInterface:$transformed);
// Declare the function implementing the interface for a single payload operation.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::CallOpInterface call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
// In MyExtension.cpp.
::mlir::DiagnosedSilenceableFailure CallToOp::applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::CallOpInterface call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state) {
// Call the actual rewrite.
Operation *rewritten = rewriteToOp(call);
- // Report an error if the rewriter produced a null pointer. Note that it may have
+ // Report an error if the rewriter produced a null pointer. Note that it may have
// irreversibly modified the payload IR, so we produce a definite failure.
if (!rewritten) {
return emitDefiniteError() << "failed to rewrite call to operation";
}
- // On success, push the resulting operation into the result list. The list is expected
- // to contain exactly one entity per result and per application. The handles will be
+ // On success, push the resulting operation into the result list. The list is expected
+ // to contain exactly one entity per result and per application. The handles will be
// associated with lists of the respective values produced by each application.
results.push_back(rewritten);
-
+
// If everything is fine, return success.
return DiagnosedSilenceableFailure::success();
}
```c++
::mlir::DiagnosedSilenceableFailure SomeOtherOp::apply(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::transform::TransformResults &results,
::mlir::transform::TransformState &state) {
// ...
// The argument is the handle to the payload operations.
let arguments = (ins CallOpInterfaceHandle:$call);
- // The result is the handle to the payload operations produced during the
+ // The result is the handle to the payload operations produced during the
// transformation.
let results = (outs TransformHandleTypeInterface:$transformed);
// Declare the function implementing the interface for a single payload operation.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::CallOpInterface call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
// This operation returns a tri-state result that can be one of:
// - success when the transformation succeeded;
// - definite failure when the transformation failed in such a way that
-// following
-// transformations are impossible or undesirable, typically it could have left
-// payload IR in an invalid state; it is expected that a diagnostic is emitted
-// immediately before returning the definite error;
+// following transformations are impossible or undesirable, typically it could
+// have left payload IR in an invalid state; it is expected that a diagnostic
+// is emitted immediately before returning the definite error;
// - silenceable failure when the transformation failed but following
-// transformations
-// are still applicable, typically this means a precondition for the
-// transformation is not satisfied and the payload IR has not been modified.
-// The silenceable failure additionally carries a Diagnostic that can be emitted
-// to the user.
+// transformations are still applicable, typically this means a precondition
+// for the transformation is not satisfied and the payload IR has not been
+// modified. The silenceable failure additionally carries a Diagnostic that
+// can be emitted to the user.
::mlir::DiagnosedSilenceableFailure mlir::transform::ChangeCallTargetOp::apply(
+ // The rewriter that should be used when modifying IR.
+ ::mlir::transform::TransformRewriter &rewriter,
// The list of payload IR entities that will be associated with the
// transform IR values defined by this transform operation. In this case, it
// can remain empty as there are no results.
// Declare the function implementing the interface for a single payload operation.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::func::CallOp call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
// Declare the function implementing the interface for a single payload operation.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::CallOpInterface call,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
// to the user.
::mlir::DiagnosedSilenceableFailure
mlir::transform::ChangeCallTargetOp::applyToOne(
+ // The rewriter that should be used when modifying IR.
+ ::mlir::transform::TransformRewriter &rewriter,
// The single payload operation to which the transformation is applied.
::mlir::func::CallOp call,
// The payload IR entities that will be appended to lists associated with
// CallToOp
//===---------------------------------------------------------------------===//
-static mlir::Operation *replaceCallWithOp(mlir::CallOpInterface call) {
+static mlir::Operation *replaceCallWithOp(mlir::RewriterBase &rewriter,
+ mlir::CallOpInterface call) {
// Construct an operation from an unregistered dialect. This is discouraged
// and is only used here for brevity of the overall example.
mlir::OperationState state(call.getLoc(), "my.mm4");
state.types.assign(call->result_type_begin(), call->result_type_end());
state.operands.assign(call->operand_begin(), call->operand_end());
- mlir::OpBuilder builder(call);
- mlir::Operation *replacement = builder.create(state);
- call->replaceAllUsesWith(replacement->getResults());
- call->erase();
+ mlir::Operation *replacement = rewriter.create(state);
+ rewriter.replaceOp(call, replacement->getResults());
return replacement;
}
// See above for the signature description.
mlir::DiagnosedSilenceableFailure mlir::transform::CallToOp::applyToOne(
- mlir::CallOpInterface call, mlir::transform::ApplyToEachResultList &results,
+ mlir::transform::TransformRewriter &rewriter, mlir::CallOpInterface call,
+ mlir::transform::ApplyToEachResultList &results,
mlir::transform::TransformState &state) {
// Dispatch to the actual transformation.
- Operation *replacement = replaceCallWithOp(call);
+ Operation *replacement = replaceCallWithOp(rewriter, call);
// Associate the payload operation produced by the rewrite with the result
// handle of this transform operation.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::tensor::EmptyOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
}];
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
}];
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def BufferizeToAllocationOp : Op<Transform_Dialect,
"structured.bufferize_to_allocation",
[DeclareOpInterfaceMethods<TransformOpInterface>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
This transform materializes an allocation for the targeted tensor value. It
replaces all original uses of the target with the newly allocated buffer,
[FunctionalStyleTransformOpTrait,
MemoryEffectsOpInterface,
TransformOpInterface,
- TransformEachOpTrait]> {
+ TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Decomposes named complex operations, such as higher-dimensional
(depthwise) convolutions, into combinations of lower-dimensional equivalents
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def FuseOp : Op<Transform_Dialect, "structured.fuse",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- DeclareOpInterfaceMethods<TransformOpInterface>]> {
+ DeclareOpInterfaceMethods<TransformOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Tiles the operations pointed to by the target handle and fuses their
producers greedily using the options provided as attributes.
Op<Transform_Dialect, "structured.fuse_into_containing_op",
[DeclareOpInterfaceMethods<TransformOpInterface,
["allowsRepeatedHandleOperands"]>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let summary = "Fuse a producer into a containing operation.";
let description = [{
def GeneralizeOp : Op<Transform_Dialect, "structured.generalize",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformOpInterface, TransformEachOpTrait]> {
+ TransformOpInterface, TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Transforms a named structured operation into the generic form with the
explicit attached region.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def InterchangeOp : Op<Transform_Dialect, "structured.interchange",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformOpInterface, TransformEachOpTrait]> {
+ TransformOpInterface, TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Interchanges the iterators of the operations pointed to by the target handle
using the iterator interchange attribute.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::GenericOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
FunctionalStyleTransformOpTrait,
MemoryEffectsOpInterface,
TransformEachOpTrait,
- TransformOpInterface]> {
+ TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Rewrite a tensor.pack into tensor.pad + tensor.expand_shape + linalg.transpose.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::tensor::PackOp target,
::mlir::transform::ApplyToEachResultList &transformResults,
::mlir::transform::TransformState &state);
FunctionalStyleTransformOpTrait,
MemoryEffectsOpInterface,
TransformEachOpTrait,
- TransformOpInterface]> {
+ TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Lower a tensor.unpack into empty + linalg.transpose + tensor.collapse_shape +
tensor.extract_slice.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::tensor::UnPackOp target,
::mlir::transform::ApplyToEachResultList &transformResults,
::mlir::transform::TransformState &state);
def MultiTileSizesOp : Op<Transform_Dialect, "structured.multitile_sizes",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
- TransformOpInterface, TransformEachOpTrait]> {
+ TransformOpInterface, TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Emits the IR computing the tile sizes `s1` and `s2` such that:
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
TransformState &state);
def PackOp : Op<Transform_Dialect, "structured.pack", [
DeclareOpInterfaceMethods<TransformOpInterface>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Pack a LinalgOp by applying a data tiling transformation on the op and
packing the operands according to the `packed_sizes` specification.
//===----------------------------------------------------------------------===//
def PackGreedilyOp : Op<Transform_Dialect, "structured.pack_greedily", [
DeclareOpInterfaceMethods<TransformOpInterface>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Target a Linalg op and rewrite it into packed LinalgOp form by trying to
infer whether a known suboperation is embedded
def PackTransposeOp : Op<Transform_Dialect, "structured.pack_transpose", [
FunctionalStyleTransformOpTrait,
MemoryEffectsOpInterface,
- DeclareOpInterfaceMethods<TransformOpInterface>]> {
+ DeclareOpInterfaceMethods<TransformOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Apply a transposition to a single `tensor.pack` (resp. `tensor.unpack`) and
update the `linalg.generic` op that consumes (resp. produces) the operation.
def PadOp : Op<Transform_Dialect, "structured.pad",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformOpInterface, TransformEachOpTrait]> {
+ TransformOpInterface, TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Pads the operations pointed to by the target handle using the options
provides as operation attributes.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
Op<Transform_Dialect,
"structured.hoist_pad.build_packing_loop_nest",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
- DeclareOpInterfaceMethods<TransformOpInterface>]> {
+ DeclareOpInterfaceMethods<TransformOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Helper transform used to hoist a tensor.pad target operation. This operation
creates the packing loop nest required by the hoist_pad operation and makes
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::tensor::PadOp,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def PromoteOp : Op<Transform_Dialect, "structured.promote",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformOpInterface, TransformEachOpTrait]> {
+ TransformOpInterface, TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Promotes the specified operands of the target into a separate memory buffer.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def ReplaceOp : Op<Transform_Dialect, "structured.replace",
[IsolatedFromAbove, DeclareOpInterfaceMethods<TransformOpInterface>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>] # GraphRegionNoTerminator.traits> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait] # GraphRegionNoTerminator.traits> {
let description = [{
Replace all `target` payload ops with the single op that is contained in
this op's region. All targets must have zero arguments and must be isolated
def ScalarizeOp : Op<Transform_Dialect, "structured.scalarize",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformOpInterface, TransformEachOpTrait]> {
+ TransformOpInterface, TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that ops of a specific kind in the given function should be
scalarized (i.e. their dynamic dimensions tiled by 1).
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
[FunctionalStyleTransformOpTrait,
MemoryEffectsOpInterface,
TransformOpInterface,
- TransformEachOpTrait]> {
+ TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Rewrite a supported tensor operation that is not in destination-passing style
into a form that is in destination-passing style.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def SplitOp : Op<Transform_Dialect, "structured.split",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
- DeclareOpInterfaceMethods<TransformOpInterface>]> {
+ DeclareOpInterfaceMethods<TransformOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that the given `target` op should be split into two complementary
parts, which combined cover the entire iteration domain of the original op.
def SplitReductionOp : Op<Transform_Dialect, "structured.split_reduction",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformEachOpTrait, TransformOpInterface]> {
+ TransformEachOpTrait, TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that the given `target` op should be transformed with the
`splitReduction` transformation and split factor provided as attribute.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def TileReductionUsingScfOp : Op<Transform_Dialect, "structured.tile_reduction_using_scf",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformEachOpTrait, TransformOpInterface]> {
+ TransformEachOpTrait, TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that the given `target` op should be transformed with the
`tileReduction` transformation with the tile size provided as attribute.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def TileReductionUsingForallOp :
Op<Transform_Dialect, "structured.tile_reduction_using_forall",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformEachOpTrait, TransformOpInterface]> {
+ TransformEachOpTrait, TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Tile a PartialReductionOpInterface op to a tiled `scf.forall` doing
partial reduction.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def TileOp : Op<Transform_Dialect, "structured.tile",
[DeclareOpInterfaceMethods<TransformOpInterface>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that the given `target` op should be tiled with the given sizes.
This transform generates a loop nest with a smaller ("tiled") target
Op<Transform_Dialect, "structured.tile_to_forall_op",
[AttrSizedOperandSegments,
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
- TransformOpInterface]> {
+ TransformOpInterface, ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Tile a TilingInterface op to a tiled `scf.forall`.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure apply(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::transform::TransformResults &transformResults,
::mlir::transform::TransformState &state);
def TileToScfForOp : Op<Transform_Dialect, "structured.tile_to_scf_for",
[DeclareOpInterfaceMethods<TransformOpInterface>,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that the given `target` op should be tiled with the given sizes.
This transform generates a loop nest with a smaller ("tiled") target
def VectorizeOp : Op<Transform_Dialect, "structured.vectorize",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformEachOpTrait, TransformOpInterface]> {
+ TransformEachOpTrait, TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Indicates that the given `target` op all the ops it contains should be
vectorized with the configuration specified by the attributes of this op.
];
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
def MaskedVectorizeOp : Op<Transform_Dialect, "structured.masked_vectorize",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
- TransformOpInterface]> {
+ TransformOpInterface, ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Vectorize the target ops, which must be Linalg ops, with masked vectors
of the specified size.
let extraClassDeclaration = [{
// TODO: applyToOne.
::mlir::DiagnosedSilenceableFailure apply(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::transform::TransformResults &transformResults,
::mlir::transform::TransformState &state);
def HoistRedundantVectorTransfersOp :
Op<Transform_Dialect, "structured.hoist_redundant_vector_transfers",
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
- TransformEachOpTrait, TransformOpInterface]> {
+ TransformEachOpTrait, TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Hoist vector.transfer_read / vector.transfer_write pairs out of immediately
enclosing scf::ForOp iteratively, if the following conditions are true:
];
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
- ::mlir::func::FuncOp target,
+ ::mlir::transform::TransformRewriter &rewriter,
+ ::mlir::func::FuncOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
}];
[FunctionalStyleTransformOpTrait,
MemoryEffectsOpInterface,
TransformOpInterface,
- TransformEachOpTrait]> {
+ TransformEachOpTrait,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Convert linalg.conv_2d_xxx into linalg.generic (for img2col packing)
and linalg.matmul.
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::linalg::LinalgOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
Op<Transform_Dialect, "structured.hoist_redundant_tensor_subsets",
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
TransformEachOpTrait,
- TransformOpInterface]> {
+ TransformOpInterface,
+ ReportTrackingListenerFailuresOpTrait]> {
let description = [{
Hoists supported tensor subset extract/insert operation pairs out of
immediately enclosing loop iteratively, if the following conditions
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
];
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::scf::ForOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::scf::ForOp target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::scf::IfOp ifOp,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
return success();
}
- DiagnosedSilenceableFailure apply(TransformResults &results,
+ DiagnosedSilenceableFailure apply(TransformRewriter &rewriter,
+ TransformResults &results,
TransformState &state) {
Value operandHandle = cast<OpTy>(this->getOperation()).getOperandHandle();
auto payload = state.getPayloadOps(operandHandle);
return success();
}
- DiagnosedSilenceableFailure apply(TransformResults &results,
+ DiagnosedSilenceableFailure apply(TransformRewriter &rewriter,
+ TransformResults &results,
TransformState &state) {
Value operandHandle = cast<OpTy>(this->getOperation()).getOperandHandle();
ValueRange payload = state.getPayloadValues(operandHandle);
constexpr const static ::llvm::StringLiteral
kWithNamedSequenceAttrName = "transform.with_named_sequence";
- /// Names of the attribute attachable to an operation so it can be
+ /// Name of the attribute attachable to an operation so it can be
/// identified as root by the default interpreter pass.
constexpr const static ::llvm::StringLiteral
kTargetTagAttrName = "transform.target_tag";
+ /// Name of the attribute attachable to an operation, indicating that
+ /// TrackingListener failures should be silenced.
+ constexpr const static ::llvm::StringLiteral
+ kSilenceTrackingFailuresAttrName = "transform.silence_tracking_failures";
+
/// Names of the attributes indicating whether an argument of an external
/// transform dialect symbol is consumed or only read.
constexpr const static ::llvm::StringLiteral
#include "mlir/Support/LogicalResult.h"
namespace mlir {
-
namespace transform {
class TransformOpInterface;
class TransformResults;
+class TransformRewriter;
class TransformState;
using Param = Attribute;
public TransformState::Extension {
public:
/// Create a new TrackingListener for usage in the specified transform op.
- explicit TrackingListener(TransformState &state, TransformOpInterface op)
- : TransformState::Extension(state), transformOp(op) {}
+ TrackingListener(TransformState &state, TransformOpInterface op);
protected:
/// Return a replacement payload op for the given op, which is going to be
/// The transform op in which this TrackingListener is used.
TransformOpInterface transformOp;
+
+ /// The handles that are consumed by the transform op.
+ DenseSet<Value> consumedHandles;
};
/// A specialized listener that keeps track of cases in which no replacement
int64_t errorCounter = 0;
};
+/// This is a special rewriter to be used in transform op implementations,
+/// providing additional helper functions to update the transform state, etc.
+// TODO: Helper functions will be added in a subsequent change.
+class TransformRewriter : public RewriterBase {
+protected:
+ friend class TransformState;
+
+ /// Create a new TransformRewriter.
+ explicit TransformRewriter(MLIRContext *ctx,
+ ErrorCheckingTrackingListener *listener);
+
+public:
+ /// Return "true" if the tracking listener had failures.
+ bool hasTrackingFailures() const;
+
+ /// Silence all tracking failures that have been encountered so far.
+ void silenceTrackingFailure();
+
+private:
+ ErrorCheckingTrackingListener *const listener;
+};
+
/// This trait is supposed to be attached to Transform dialect operations that
/// can be standalone top-level transforms. Such operations typically contain
/// other Transform dialect operations that can be executed following some
/// 5. If any `applyToOne` return silenceableFailure, the transformation is
/// considered silenceable.
/// 6. Otherwise the transformation is considered successful.
- DiagnosedSilenceableFailure apply(TransformResults &transformResults,
+ DiagnosedSilenceableFailure apply(transform::TransformRewriter &rewriter,
+ TransformResults &transformResults,
TransformState &state);
/// Checks that the op matches the expectations of this trait.
}
};
+/// `TrackingListener` failures are reported only for ops that have this trait.
+/// The purpose of this trait is to give users more time to update their custom
+/// transform ops to use the provided `TransformRewriter` for all IR
+/// modifications. This trait will eventually be removed, and failures will be
+/// reported for all transform ops.
+template <typename OpTy>
+class ReportTrackingListenerFailuresOpTrait
+ : public OpTrait::TraitBase<OpTy, ReportTrackingListenerFailuresOpTrait> {};
+
/// A single result of applying a transform op with `ApplyEachOpTrait` to a
/// single payload operation.
using ApplyToEachResult = MappedValue;
/// `targets` contains operations of the same class and a silenceable failure
/// is reported if it does not.
template <typename TransformOpTy, typename Range>
-DiagnosedSilenceableFailure
-applyTransformToEach(TransformOpTy transformOp, Range &&targets,
- SmallVectorImpl<ApplyToEachResultList> &results,
- TransformState &state) {
+DiagnosedSilenceableFailure applyTransformToEach(
+ TransformOpTy transformOp, TransformRewriter &rewriter, Range &&targets,
+ SmallVectorImpl<ApplyToEachResultList> &results, TransformState &state) {
using OpTy = typename llvm::function_traits<
- decltype(&TransformOpTy::applyToOne)>::template arg_t<0>;
+ decltype(&TransformOpTy::applyToOne)>::template arg_t<1>;
static_assert(std::is_convertible<OpTy, Operation *>::value,
"expected transform function to take an operation");
+ OpBuilder::InsertionGuard g(rewriter);
SmallVector<Diagnostic> silenceableStack;
unsigned expectedNumResults = transformOp->getNumResults();
ApplyToEachResultList partialResults;
partialResults.reserve(expectedNumResults);
Location specificOpLoc = specificOp->getLoc();
+ rewriter.setInsertionPoint(specificOp);
DiagnosedSilenceableFailure res =
- transformOp.applyToOne(specificOp, partialResults, state);
+ transformOp.applyToOne(rewriter, specificOp, partialResults, state);
if (res.isDefiniteFailure())
return DiagnosedSilenceableFailure::definiteFailure();
template <typename OpTy>
mlir::DiagnosedSilenceableFailure
mlir::transform::TransformEachOpTrait<OpTy>::apply(
- TransformResults &transformResults, TransformState &state) {
+ TransformRewriter &rewriter, TransformResults &transformResults,
+ TransformState &state) {
Value handle = this->getOperation()->getOperand(0);
auto targets = state.getPayloadOps(handle);
// corresponding results entry.
SmallVector<ApplyToEachResultList, 1> results;
DiagnosedSilenceableFailure result = detail::applyTransformToEach(
- cast<OpTy>(this->getOperation()), targets, results, state);
+ cast<OpTy>(this->getOperation()), rewriter, targets, results, state);
// Step 3. Propagate the definite failure if any and bail out.
if (result.isDefiniteFailure())
transformation represented by the current op is targeted. Returns a
special status object indicating whether the transformation succeeded
or failed, and, if it failed, whether the failure is recoverable or not.
+
+ IR must be created, modified and deleted with the provided rewriter.
+ implementations are responsible for setting the insertion point of the
+ rewriter to the desired location.
}],
/*returnType=*/"::mlir::DiagnosedSilenceableFailure",
/*name=*/"apply",
/*arguments=*/(ins
+ "::mlir::transform::TransformRewriter &":$rewriter,
"::mlir::transform::TransformResults &":$transformResults,
"::mlir::transform::TransformState &":$state
)>,
let cppNamespace = "::mlir::transform";
}
+def ReportTrackingListenerFailuresOpTrait : NativeOpTrait<"ReportTrackingListenerFailuresOpTrait"> {
+ let cppNamespace = "::mlir::transform";
+}
+
def FindPayloadReplacementOpInterface
: OpInterface<"FindPayloadReplacementOpInterface"> {
let description = [{
def ApplyPatternsOp : TransformDialectOp<"apply_patterns",
[TransformOpInterface, TransformEachOpTrait,
- DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+ ReportTrackingListenerFailuresOpTrait]
# GraphRegionNoTerminator.traits> {
let summary = "Greedily applies patterns to the body of the targeted op";
let description = [{
considered "payload op replacements". Furthermore, only if the replacement
values are defined by the same op and that op has the same type as the
original op, the mapping is updated. Otherwise, this transform fails
- silently unless `fail_on_payload_replacement_not_found` is set to "false".
- More details can be found at the documentation site of `TrackingListener`.
+ silently. More details can be found at the documentation site of
+ `TrackingListener`.
This transform also fails silently if the pattern application did not
converge within the default number of iterations/rewrites of the greedy
}];
let arguments = (ins
- TransformHandleTypeInterface:$target,
- DefaultValuedAttr<BoolAttr, "true">:$fail_on_payload_replacement_not_found);
+ TransformHandleTypeInterface:$target);
let results = (outs);
let regions = (region MaxSizedRegion<1>:$region);
OpBuilder<(ins
"Value":$target,
CArg<"function_ref<void(OpBuilder &, Location)>", "nullptr">:
- $bodyBuilder,
- CArg<"bool", "true">:$failOnPayloadReplacementNotFound)>,
+ $bodyBuilder)>,
];
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
} // namespace
DiagnosedSilenceableFailure
-SimplifyBoundedAffineOpsOp::apply(TransformResults &results,
+SimplifyBoundedAffineOpsOp::apply(transform::TransformRewriter &rewriter,
+ TransformResults &results,
TransformState &state) {
// Get constraints for bounded values.
SmallVector<int64_t> lbs;
SimplifyAffineMinMaxOp<AffineMaxOp>>(getContext(), cstr);
FrozenRewritePatternSet frozenPatterns(std::move(patterns));
GreedyRewriteConfig config;
+ config.listener =
+ static_cast<RewriterBase::Listener *>(rewriter.getListener());
config.strictMode = GreedyRewriteStrictness::ExistingAndNewOps;
// Apply the simplification pattern to a fixpoint.
if (failed(applyOpPatternsAndFold(targets, frozenPatterns, config))) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::OneShotBufferizeOp::apply(TransformResults &transformResults,
+transform::OneShotBufferizeOp::apply(transform::TransformRewriter &rewriter,
+ TransformResults &transformResults,
TransformState &state) {
OneShotBufferizationOptions options;
options.allowReturnAllocs = getAllowReturnAllocs();
modifiesPayload(effects);
}
-DiagnosedSilenceableFailure
-transform::EliminateEmptyTensorsOp::apply(TransformResults &transformResults,
- TransformState &state) {
- IRRewriter rewriter(getContext());
+DiagnosedSilenceableFailure transform::EliminateEmptyTensorsOp::apply(
+ transform::TransformRewriter &rewriter, TransformResults &transformResults,
+ TransformState &state) {
OneShotBufferizationOptions options;
options.allowReturnAllocs = true;
// EmptyTensorToAllocTensorOp
//===----------------------------------------------------------------------===//
-DiagnosedSilenceableFailure
-EmptyTensorToAllocTensorOp::applyToOne(tensor::EmptyOp target,
- ApplyToEachResultList &results,
- transform::TransformState &state) {
- IRRewriter rewriter(target->getContext());
+DiagnosedSilenceableFailure EmptyTensorToAllocTensorOp::applyToOne(
+ transform::TransformRewriter &rewriter, tensor::EmptyOp target,
+ ApplyToEachResultList &results, transform::TransformState &state) {
rewriter.setInsertionPoint(target);
auto alloc = rewriter.replaceOpWithNewOp<bufferization::AllocTensorOp>(
target, target.getType(), target.getDynamicSizes());
/// Alter kernel configuration of the given kernel.
static DiagnosedSilenceableFailure
-alterGpuLaunch(IRRewriter &rewriter, LaunchOp gpuLaunch,
+alterGpuLaunch(RewriterBase &rewriter, LaunchOp gpuLaunch,
TransformOpInterface transformOp,
std::optional<int64_t> gridDimX = std::nullopt,
std::optional<int64_t> gridDimY = std::nullopt,
return DiagnosedSilenceableFailure::success();
}
-DiagnosedSilenceableFailure
-transform::MapForallToBlocks::applyToOne(Operation *target,
- ApplyToEachResultList &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure transform::MapForallToBlocks::applyToOne(
+ transform::TransformRewriter &rewriter, Operation *target,
+ ApplyToEachResultList &results, transform::TransformState &state) {
LaunchOp gpuLaunch = dyn_cast<LaunchOp>(target);
- IRRewriter rewriter(getContext());
auto transformOp = cast<TransformOpInterface>(getOperation());
if (!getGenerateGpuLaunch() && !gpuLaunch) {
}
DiagnosedSilenceableFailure transform::MapNestedForallToThreads::applyToOne(
- Operation *target, ApplyToEachResultList &results, TransformState &state) {
+ transform::TransformRewriter &rewriter, Operation *target,
+ ApplyToEachResultList &results, TransformState &state) {
LaunchOp gpuLaunch = dyn_cast<LaunchOp>(target);
auto transformOp = cast<TransformOpInterface>(getOperation());
// Set the GPU launch configuration for the block dims early, this is not
// subject to IR inspection.
- IRRewriter rewriter(getContext());
diag = alterGpuLaunch(rewriter, gpuLaunch, transformOp, std::nullopt,
std::nullopt, std::nullopt, blockDims[0], blockDims[1],
blockDims[2]);
// BufferizeToAllocationOp
//===----------------------------------------------------------------------===//
-DiagnosedSilenceableFailure
-transform::BufferizeToAllocationOp::apply(transform::TransformResults &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure transform::BufferizeToAllocationOp::apply(
+ transform::TransformRewriter &rewriter,
+ transform::TransformResults &results, transform::TransformState &state) {
Attribute memorySpace =
getMemorySpace().has_value() ? getMemorySpace().value() : Attribute();
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
auto transformed = llvm::to_vector(
llvm::map_range(state.getPayloadValues(getTarget()), [&](Value v) {
return linalg::bufferizeToAllocation(rewriter, v, memorySpace);
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::DecomposeOp::applyToOne(LinalgOp target,
+transform::DecomposeOp::applyToOne(transform::TransformRewriter &rewriter,
+ LinalgOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
#define DOWNSCALE(trans) \
}
DiagnosedSilenceableFailure
-transform::FuseOp::apply(mlir::transform::TransformResults &transformResults,
+transform::FuseOp::apply(transform::TransformRewriter &rewriter,
+ mlir::transform::TransformResults &transformResults,
mlir::transform::TransformState &state) {
SmallVector<int64_t> tileSizes = extractFromI64ArrayAttr(getTileSizes());
SmallVector<int64_t> tileInterchange =
tilingOptions = tilingOptions.setTileSizes(tileSizes);
scf::SCFTileAndFuseOptions tileAndFuseOptions;
tileAndFuseOptions.tilingOptions = tilingOptions;
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
LogicalResult result = applyTilingToAll(
rewriter, getOperation(), state.getPayloadOps(getTarget()),
tileSizes.size() - llvm::count(tileSizes, 0), transformResults,
}
DiagnosedSilenceableFailure
-transform::FuseIntoContainingOp::apply(transform::TransformResults &results,
+transform::FuseIntoContainingOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<Operation *> fusedOps;
auto producerOps = state.getPayloadOps(getProducerOp());
return failure();
};
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
while (!remainingProducers.empty()) {
auto nextProducer = getNextProducer();
if (failed(nextProducer)) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::GeneralizeOp::applyToOne(LinalgOp target,
+transform::GeneralizeOp::applyToOne(transform::TransformRewriter &rewriter,
+ LinalgOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
// Exit early if no transformation is needed.
results.push_back(target);
return DiagnosedSilenceableFailure::success();
}
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<LinalgOp> generic = generalizeNamedOp(rewriter, target);
if (succeeded(generic)) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::InterchangeOp::applyToOne(GenericOp target,
+transform::InterchangeOp::applyToOne(transform::TransformRewriter &rewriter,
+ GenericOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
ArrayRef<int64_t> interchangeVector = getIteratorInterchange();
results.push_back(target);
return DiagnosedSilenceableFailure::success();
}
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
FailureOr<GenericOp> res =
interchangeGenericOp(rewriter, target,
SmallVector<unsigned>(interchangeVector.begin(),
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::LowerPackOp::applyToOne(
- tensor::PackOp target, transform::ApplyToEachResultList &transformResults,
+ transform::TransformRewriter &rewriter, tensor::PackOp target,
+ transform::ApplyToEachResultList &transformResults,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<LowerPackResult> res = lowerPack(rewriter, target);
if (failed(res)) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::LowerUnPackOp::applyToOne(
- tensor::UnPackOp target, transform::ApplyToEachResultList &transformResults,
+ transform::TransformRewriter &rewriter, tensor::UnPackOp target,
+ transform::ApplyToEachResultList &transformResults,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<LowerUnPackOpResult> res = lowerUnPack(rewriter, target);
if (failed(res)) {
}
DiagnosedSilenceableFailure
-transform::MatchOp::apply(transform::TransformResults &results,
+transform::MatchOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
llvm::StringSet<> strs;
if (getOps().has_value())
}
DiagnosedSilenceableFailure transform::MultiTileSizesOp::applyToOne(
- LinalgOp target, transform::ApplyToEachResultList &results,
- TransformState &state) {
+ transform::TransformRewriter &rewriter, LinalgOp target,
+ transform::ApplyToEachResultList &results, TransformState &state) {
if (isa<TransformParamTypeInterface>(getLowSize().getType())) {
if (target.hasDynamicShape()) {
auto diag = emitSilenceableError()
}
DiagnosedSilenceableFailure
-transform::PackOp::apply(transform::TransformResults &transformResults,
+transform::PackOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &transformResults,
transform::TransformState &state) {
auto targetOps = state.getPayloadOps(getTarget());
// If nothing to pack, propagate success.
DiagnosedSilenceableFailure status = unpackSingleIndexResultPayloadOperations(
state, *this, packedSizes, getMixedPackedSizes());
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(linalgOp);
FailureOr<PackResult> maybeResult = pack(rewriter, linalgOp, packedSizes);
if (failed(maybeResult))
}
DiagnosedSilenceableFailure
-PackGreedilyOp::apply(transform::TransformResults &transformResults,
+PackGreedilyOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &transformResults,
transform::TransformState &state) {
SmallVector<Operation *> results;
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
for (Operation *op : state.getPayloadOps(getTarget())) {
auto linalgOp = dyn_cast<LinalgOp>(op);
if (!linalgOp)
}
DiagnosedSilenceableFailure
-transform::PackTransposeOp::apply(transform::TransformResults &transformResults,
+transform::PackTransposeOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &transformResults,
transform::TransformState &state) {
auto packOrUnpackOps = state.getPayloadOps(getTargetPackOrUnPackOp());
auto linalgOps = state.getPayloadOps(getTargetLinalgOp());
assert(packOp && linalgOp && "unexpected null op");
// Step 3. Actually transpose the ops.
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
FailureOr<PackTransposeResult> res = packTranspose(
rewriter, packOp, linalgOp, unPackOp, getOuterPerm(), getInnerPerm());
// Preconditions have been checked, it is an error to fail here.
//===---------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::PadOp::applyToOne(LinalgOp target,
+transform::PadOp::applyToOne(transform::TransformRewriter &rewriter,
+ LinalgOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
// Convert the integer packing flags to booleans.
transposePaddings.push_back(
extractFromI64ArrayAttr(cast<ArrayAttr>(transposeVector)));
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
LinalgOp paddedOp;
SmallVector<int64_t> paddingDimensions =
extractFromI64ArrayAttr(getPaddingDimensions());
//===---------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::HoistPadBuildPackingLoopNestOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &transformResults,
transform::TransformState &state) {
auto targetOps = state.getPayloadOps(getTarget());
if (!padOp || !loopOp)
return emitDefiniteFailure() << "requires exactly 2 non-null handles";
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
FailureOr<linalg::detail::PackingResult> result =
linalg::detail::buildPackingLoopNest(rewriter, padOp, loopOp,
getTranspose());
}
DiagnosedSilenceableFailure
-transform::HoistPadOp::applyToOne(tensor::PadOp target,
+transform::HoistPadOp::applyToOne(transform::TransformRewriter &rewriter,
+ tensor::PadOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
tensor::PadOp hoistedPadOp;
SmallVector<GenericOp> transposeOps;
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
FailureOr<Value> result =
hoistPaddingOnTensors(rewriter, target, getNumLoops(), getTranspose(),
hoistedPadOp, transposeOps);
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::PromoteOp::applyToOne(LinalgOp target,
+transform::PromoteOp::applyToOne(transform::TransformRewriter &rewriter,
+ LinalgOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
LinalgPromotionOptions promotionOptions;
if (failed(promoteSubviewsPrecondition(target, promotionOptions)))
return emitDefaultDefiniteFailure(target);
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<LinalgOp> res = promoteSubViews(rewriter, target, promotionOptions);
if (failed(res))
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::ReplaceOp::apply(TransformResults &transformResults,
+transform::ReplaceOp::apply(transform::TransformRewriter &rewriter,
+ TransformResults &transformResults,
TransformState &state) {
auto payload = state.getPayloadOps(getTarget());
}
// Clone and replace.
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
Operation *pattern = &getBodyRegion().front().front();
SmallVector<Operation *> replacements;
for (Operation *target : payload) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::ScalarizeOp::applyToOne(LinalgOp target,
+transform::ScalarizeOp::applyToOne(transform::TransformRewriter &rewriter,
+ LinalgOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
scf::SCFTilingOptions tilingOptions;
AffineMap map = target.getShapesToLoopsMap();
if (!map)
return tileSizes;
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
SmallVector<OpFoldResult> shapeSizes =
affine::makeComposedFoldedMultiResultAffineApply(rewriter, loc, map,
allShapeSizes);
return tileSizes;
});
SmallVector<int64_t> emptyTileSizes;
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<scf::SCFTilingResult> maybeTilingResult = tileUsingSCFForOp(
rewriter, cast<TilingInterface>(target.getOperation()), tilingOptions);
DiagnosedSilenceableFailure
transform::RewriteInDestinationPassingStyleOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
SmallVector<Operation *> res;
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<Operation *> maybeResult =
TypeSwitch<Operation *, FailureOr<Operation *>>(target)
// SplitOp
//===----------------------------------------------------------------------===//
-DiagnosedSilenceableFailure SplitOp::apply(TransformResults &results,
- TransformState &state) {
+DiagnosedSilenceableFailure
+SplitOp::apply(transform::TransformRewriter &rewriter,
+ TransformResults &results, TransformState &state) {
// Collect the dynamic split points if provided.
SmallVector<Operation *> payload =
llvm::to_vector(state.getPayloadOps(getTarget()));
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
SmallVector<OpFoldResult> splitPoints;
splitPoints.reserve(payload.size());
if (getDynamicSplitPoint()) {
}
DiagnosedSilenceableFailure transform::SplitReductionOp::applyToOne(
- LinalgOp target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, LinalgOp target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
ControlSplitReductionFn splitFn = [&](LinalgOp) {
return linalg::SplitReductionOptions{int64_t(getSplitFactor()),
unsigned(getInsertSplitDimension()),
bool(getInnerParallel())};
};
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<SplitReductionResult> splitResult =
(getUseScalingAlgorithm())
}
DiagnosedSilenceableFailure transform::TileReductionUsingScfOp::applyToOne(
- LinalgOp target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, LinalgOp target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
FailureOr<scf::SCFReductionTilingResult> result = scf::tileReductionUsingScf(
rewriter, cast<PartialReductionOpInterface>(target.getOperation()),
}
DiagnosedSilenceableFailure transform::TileReductionUsingForallOp::applyToOne(
- LinalgOp target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, LinalgOp target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
SmallVector<OpFoldResult> numThreads =
getAsOpFoldResult(rewriter.getI64ArrayAttr(getNumThreads()));
}
DiagnosedSilenceableFailure
-transform::TileOp::apply(TransformResults &transformResults,
+transform::TileOp::apply(transform::TransformRewriter &rewriter,
+ TransformResults &transformResults,
TransformState &state) {
ArrayRef<int64_t> tileSizes = getStaticSizes();
}
tilingOptions.setInterchange(getInterchange());
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
FailureOr<scf::SCFTilingResult> maybeTilingResult =
tileUsingSCFForOp(rewriter, tilingInterface, tilingOptions);
if (failed(maybeTilingResult))
}
DiagnosedSilenceableFailure
-transform::TileToForallOp::apply(transform::TransformResults &transformResults,
+transform::TileToForallOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &transformResults,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
- auto transformOp = cast<TransformOpInterface>(getOperation());
-
- // Result payload ops.
- SmallVector<Operation *> tileOps;
- SmallVector<Operation *> tiledOps;
-
- // Unpack handles.
- SmallVector<OpFoldResult> mixedNumThreads;
- DiagnosedSilenceableFailure status =
- getPackedNumThreads()
- ? unpackSingleIndexResultPayloadOperations(
- state, transformOp, mixedNumThreads, getPackedNumThreads())
- : unpackSingleIndexResultPayloadOperations(
- state, transformOp, mixedNumThreads, getMixedNumThreads());
- if (!status.succeeded())
- return status;
- SmallVector<OpFoldResult> mixedTileSizes;
- status = getPackedTileSizes()
- ? unpackSingleIndexResultPayloadOperations(
- state, transformOp, mixedTileSizes, getPackedTileSizes())
- : unpackSingleIndexResultPayloadOperations(
- state, transformOp, mixedTileSizes, getMixedTileSizes());
- if (!status.succeeded())
- return status;
-
- for (Operation *target : state.getPayloadOps(getTarget())) {
- linalg::ForallTilingResult tilingResult;
- DiagnosedSilenceableFailure diag = tileToForallOpImpl(
- rewriter, state, transformOp, target, mixedNumThreads, mixedTileSizes,
- getMapping(), tilingResult);
- if (!diag.succeeded())
+ auto transformOp = cast<TransformOpInterface>(getOperation());
+
+ // Result payload ops.
+ SmallVector<Operation *> tileOps;
+ SmallVector<Operation *> tiledOps;
+
+ // Unpack handles.
+ SmallVector<OpFoldResult> mixedNumThreads;
+ DiagnosedSilenceableFailure status =
+ getPackedNumThreads()
+ ? unpackSingleIndexResultPayloadOperations(
+ state, transformOp, mixedNumThreads, getPackedNumThreads())
+ : unpackSingleIndexResultPayloadOperations(
+ state, transformOp, mixedNumThreads, getMixedNumThreads());
+ if (!status.succeeded())
+ return status;
+ SmallVector<OpFoldResult> mixedTileSizes;
+ status = getPackedTileSizes()
+ ? unpackSingleIndexResultPayloadOperations(
+ state, transformOp, mixedTileSizes, getPackedTileSizes())
+ : unpackSingleIndexResultPayloadOperations(
+ state, transformOp, mixedTileSizes, getMixedTileSizes());
+ if (!status.succeeded())
+ return status;
+
+ for (Operation *target : state.getPayloadOps(getTarget())) {
+ linalg::ForallTilingResult tilingResult;
+ DiagnosedSilenceableFailure diag = tileToForallOpImpl(
+ rewriter, state, transformOp, target, mixedNumThreads, mixedTileSizes,
+ getMapping(), tilingResult);
+ if (!diag.succeeded())
return diag;
tileOps.push_back(tilingResult.tileOp);
tiledOps.push_back(tilingResult.tiledOp);
- }
+ }
transformResults.set(cast<OpResult>(getForallOp()), tileOps);
transformResults.set(cast<OpResult>(getTiledOp()), tiledOps);
}
DiagnosedSilenceableFailure
-transform::TileToScfForOp::apply(TransformResults &transformResults,
+transform::TileToScfForOp::apply(transform::TransformRewriter &rewriter,
+ TransformResults &transformResults,
TransformState &state) {
ArrayRef<int64_t> tileSizes = getStaticSizes();
}
tilingOptions.setInterchange(getInterchange());
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
FailureOr<scf::SCFTilingResult> tilingResult =
tileUsingSCFForOp(rewriter, tilingInterfaceOp, tilingOptions);
if (failed(tilingResult))
} // namespace
DiagnosedSilenceableFailure
-transform::VectorizeOp::applyToOne(Operation *target,
+transform::VectorizeOp::applyToOne(transform::TransformRewriter &rewriter,
+ Operation *target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
if (!target->hasTrait<OpTrait::IsIsolatedFromAbove>()) {
// MaskedVectorizeOp
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::MaskedVectorizeOp::apply(
+ transform::TransformRewriter &rewriter,
mlir::transform::TransformResults &transformResults,
mlir::transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
auto targets = state.getPayloadOps(getTarget());
if (std::empty(targets))
return DiagnosedSilenceableFailure::success();
DiagnosedSilenceableFailure
transform::HoistRedundantVectorTransfersOp::applyToOne(
- func::FuncOp target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, func::FuncOp target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
// WARNING: This hoisting does not model parallelism and is generally
// incorrect when used on distributed loops with memref semantics!
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::ConvertConv2DToImg2ColOp::applyToOne(
- linalg::LinalgOp target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, linalg::LinalgOp target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
rewriter.setInsertionPoint(target);
auto maybeTransformed =
TypeSwitch<Operation *, FailureOr<std::pair<Operation *, Operation *>>>(
DiagnosedSilenceableFailure
transform::HoistRedundantTensorSubsetsOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
auto forOp = dyn_cast<scf::ForOp>(target);
if (forOp) {
linalg::hoistRedundantSubsetExtractInsert(rewriter, forOp);
}
DiagnosedSilenceableFailure transform::InsertSliceToCopyOp::applyToOne(
- Operation *targetOp, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *targetOp,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(targetOp->getContext(), &listener);
rewriter.setInsertionPoint(targetOp);
if (auto target = dyn_cast<tensor::InsertSliceOp>(targetOp))
return doit(rewriter, target, results, state);
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::MemRefMultiBufferOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &transformResults,
transform::TransformState &state) {
SmallVector<Operation *> results;
- IRRewriter rewriter(getContext());
for (Operation *op : state.getPayloadOps(getTarget())) {
bool canApplyMultiBuffer = true;
auto target = cast<memref::AllocOp>(op);
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::MemRefMakeLoopIndependentOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
// Gather IVs.
SmallVector<Value> ivs;
}
// Rewrite IR.
- IRRewriter rewriter(target->getContext());
FailureOr<Value> replacement = failure();
if (auto allocaOp = dyn_cast<memref::AllocaOp>(target)) {
replacement = memref::replaceWithIndependentOp(rewriter, allocaOp, ivs);
// GetParentForOp
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::GetParentForOp::apply(transform::TransformResults &results,
+transform::GetParentForOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SetVector<Operation *> parents;
for (Operation *target : state.getPayloadOps(getTarget())) {
}
DiagnosedSilenceableFailure
-transform::LoopOutlineOp::apply(transform::TransformResults &results,
+transform::LoopOutlineOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<Operation *> functions;
SmallVector<Operation *> calls;
for (Operation *target : state.getPayloadOps(getTarget())) {
Location location = target->getLoc();
Operation *symbolTableOp = SymbolTable::getNearestSymbolTable(target);
- IRRewriter rewriter(getContext());
scf::ExecuteRegionOp exec = wrapInExecuteRegion(rewriter, target);
if (!exec) {
DiagnosedSilenceableFailure diag = emitSilenceableError()
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::LoopPeelOp::applyToOne(scf::ForOp target,
+transform::LoopPeelOp::applyToOne(transform::TransformRewriter &rewriter,
+ scf::ForOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
scf::ForOp result;
- IRRewriter rewriter(target->getContext());
// This helper returns failure when peeling does not occur (i.e. when the IR
// is not modified). This is not a failure for the op as the postcondition:
// "the loop trip count is divisible by the step"
}
DiagnosedSilenceableFailure
-transform::LoopPipelineOp::applyToOne(scf::ForOp target,
+transform::LoopPipelineOp::applyToOne(transform::TransformRewriter &rewriter,
+ scf::ForOp target,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
scf::PipeliningOption options;
getReadLatency());
};
scf::ForLoopPipeliningPattern pattern(options, target->getContext());
- IRRewriter rewriter(getContext());
rewriter.setInsertionPoint(target);
FailureOr<scf::ForOp> patternResult =
scf::pipelineForLoop(rewriter, target, options);
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::LoopUnrollOp::applyToOne(Operation *op,
+transform::LoopUnrollOp::applyToOne(transform::TransformRewriter &rewriter,
+ Operation *op,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
LogicalResult result(failure());
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::LoopCoalesceOp::applyToOne(Operation *op,
+transform::LoopCoalesceOp::applyToOne(transform::TransformRewriter &rewriter,
+ Operation *op,
transform::ApplyToEachResultList &results,
transform::TransformState &state) {
LogicalResult result(failure());
}
DiagnosedSilenceableFailure transform::TakeAssumedBranchOp::applyToOne(
- scf::IfOp ifOp, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, scf::IfOp ifOp,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
- TrackingListener listener(state, *this);
- IRRewriter rewriter(ifOp->getContext(), &listener);
rewriter.setInsertionPoint(ifOp);
-
Region ®ion =
getTakeElseBranch() ? ifOp.getElseRegion() : ifOp.getThenRegion();
if (!llvm::hasSingleElement(region)) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::MakeLoopIndependentOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
// Gather IVs.
SmallVector<Value> ivs;
}
// Rewrite IR.
- IRRewriter rewriter(target->getContext());
FailureOr<Value> replacement = failure();
if (auto padOp = dyn_cast<tensor::PadOp>(target)) {
replacement = tensor::buildIndependentOp(rewriter, padOp, ivs);
}
return success();
}
+ if (attribute.getName().getValue() == kSilenceTrackingFailuresAttrName) {
+ if (!llvm::isa<UnitAttr>(attribute.getValue())) {
+ return op->emitError()
+ << attribute.getName() << " must be a unit attribute";
+ }
+ return success();
+ }
return emitError(op->getLoc())
<< "unknown attribute: " << attribute.getName();
}
#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
+#include "mlir/Dialect/Transform/IR/TransformDialect.h"
#include "mlir/Dialect/Transform/IR/TransformTypes.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Operation.h"
return diag;
}
+ // Prepare rewriter and listener.
+ transform::ErrorCheckingTrackingListener trackingListener(*this, transform);
+ transform::TransformRewriter rewriter(transform->getContext(),
+ &trackingListener);
+
// Compute the result but do not short-circuit the silenceable failure case as
// we still want the handles to propagate properly so the "suppress" mode can
// proceed on a best effort basis.
transform::TransformResults results(transform->getNumResults());
- DiagnosedSilenceableFailure result(transform.apply(results, *this));
+ DiagnosedSilenceableFailure result(transform.apply(rewriter, results, *this));
compactOpHandles();
+
+ // Error handling: fail if transform or listener failed.
+ DiagnosedSilenceableFailure trackingFailure =
+ trackingListener.checkAndResetError();
+ if (!transform->hasTrait<ReportTrackingListenerFailuresOpTrait>() ||
+ transform->hasAttr(
+ transform::TransformDialect::kSilenceTrackingFailuresAttrName)) {
+ // Only report failures for ReportTrackingListenerFailuresOpTrait ops. Also
+ // do not report failures if the above mentioned attribute is set.
+ if (trackingFailure.isSilenceableFailure())
+ (void)trackingFailure.silence();
+ trackingFailure = DiagnosedSilenceableFailure::success();
+ }
+ if (!trackingFailure.succeeded()) {
+ if (result.succeeded()) {
+ result = std::move(trackingFailure);
+ } else {
+ // Transform op errors have precedence, report those first.
+ if (result.isSilenceableFailure())
+ result.attachNote() << "tracking listener also failed: "
+ << trackingFailure.getMessage();
+ (void)trackingFailure.silence();
+ }
+ }
if (result.isDefiniteFailure())
return result;
// TrackingListener
//===----------------------------------------------------------------------===//
+transform::TrackingListener::TrackingListener(TransformState &state,
+ TransformOpInterface op)
+ : TransformState::Extension(state), transformOp(op) {
+ if (op) {
+ for (OpOperand *opOperand : transformOp.getConsumedHandleOpOperands()) {
+ consumedHandles.insert(opOperand->get());
+ }
+ }
+}
+
Operation *transform::TrackingListener::getCommonDefiningOp(ValueRange values) {
Operation *defOp = nullptr;
for (Value v : values) {
// Op is not tracked.
return;
}
+
+ // Helper function to check if the current transform op consumes any handle
+ // that is mapped to `op`.
+ //
+ // Note: If a handle was consumed, there shouldn't be any alive users, so it
+ // is not really necessary to check for consumed handles. However, in case
+ // there are indeed alive handles that were consumed (which is undefined
+ // behavior) and a replacement op could not be found, we want to fail with a
+ // nicer error message: "op uses a handle invalidated..." instead of "could
+ // not find replacement op". This nicer error is produced later.
+ auto handleWasConsumed = [&] {
+ return llvm::any_of(opHandles,
+ [&](Value h) { return consumedHandles.contains(h); });
+ };
+
+ // Helper function to check if the handle is alive.
auto hasAliveUser = [&]() {
- for (Value v : opHandles)
+ for (Value v : opHandles) {
for (Operation *user : v.getUsers())
- if (!happensBefore(user, transformOp))
+ if (user != transformOp && !happensBefore(user, transformOp))
return true;
+ }
return false;
};
- if (!hasAliveUser()) {
- // The op is tracked but the corresponding handles are dead.
+
+ if (!hasAliveUser() || handleWasConsumed()) {
+ // The op is tracked but the corresponding handles are dead or were
+ // consumed. Drop the op form the mapping.
(void)replacePayloadOp(op, nullptr);
return;
}
}
//===----------------------------------------------------------------------===//
+// TransformRewriter
+//===----------------------------------------------------------------------===//
+
+transform::TransformRewriter::TransformRewriter(
+ MLIRContext *ctx, ErrorCheckingTrackingListener *listener)
+ : RewriterBase(ctx), listener(listener) {
+ setListener(listener);
+}
+
+bool transform::TransformRewriter::hasTrackingFailures() const {
+ return listener->failed();
+}
+
+/// Silence all tracking failures that have been encountered so far.
+void transform::TransformRewriter::silenceTrackingFailure() {
+ if (hasTrackingFailures()) {
+ DiagnosedSilenceableFailure status = listener->checkAndResetError();
+ (void)status.silence();
+ }
+}
+
+//===----------------------------------------------------------------------===//
// Utilities for TransformEachOpTrait.
//===----------------------------------------------------------------------===//
-//===- TransformDialect.cpp - Transform dialect operations ----------------===//
+//===- TransformOps.cpp - Transform dialect operations --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Transform/IR/TransformOps.h"
+
#include "mlir/Dialect/Transform/IR/MatchInterfaces.h"
#include "mlir/Dialect/Transform/IR/TransformAttrs.h"
#include "mlir/Dialect/Transform/IR/TransformDialect.h"
}
DiagnosedSilenceableFailure
-transform::AlternativesOp::apply(transform::TransformResults &results,
+transform::AlternativesOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<Operation *> originals;
if (Value scopeHandle = getScope())
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::AnnotateOp::apply(transform::TransformResults &results,
+transform::AnnotateOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<Operation *> targets =
llvm::to_vector(state.getPayloadOps(getTarget()));
// ApplyPatternsOp
//===----------------------------------------------------------------------===//
-DiagnosedSilenceableFailure
-transform::ApplyPatternsOp::applyToOne(Operation *target,
- ApplyToEachResultList &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure transform::ApplyPatternsOp::applyToOne(
+ transform::TransformRewriter &rewriter, Operation *target,
+ ApplyToEachResultList &results, transform::TransformState &state) {
// Make sure that this transform is not applied to itself. Modifying the
// transform IR while it is being interpreted is generally dangerous. Even
// more so for the ApplyPatternsOp because the GreedyPatternRewriteDriver
}
// Configure the GreedyPatternRewriteDriver.
- ErrorCheckingTrackingListener listener(state, *this);
GreedyRewriteConfig config;
- config.listener = &listener;
+ config.listener =
+ static_cast<RewriterBase::Listener *>(rewriter.getListener());
LogicalResult result = failure();
if (target->hasTrait<OpTrait::IsIsolatedFromAbove>()) {
<< "greedy pattern application failed";
}
- // Check listener state for tracking errors.
- if (listener.failed()) {
- DiagnosedSilenceableFailure status = listener.checkAndResetError();
- if (getFailOnPayloadReplacementNotFound())
- return status;
- (void)status.silence();
- }
-
return DiagnosedSilenceableFailure::success();
}
void transform::ApplyPatternsOp::build(
OpBuilder &builder, OperationState &result, Value target,
- function_ref<void(OpBuilder &, Location)> bodyBuilder,
- bool failOnPayloadReplacementNotFound) {
+ function_ref<void(OpBuilder &, Location)> bodyBuilder) {
result.addOperands(target);
- result.getOrAddProperties<Properties>()
- .fail_on_payload_replacement_not_found =
- builder.getBoolAttr(failOnPayloadReplacementNotFound);
OpBuilder::InsertionGuard g(builder);
Region *region = result.addRegion();
// ApplyRegisteredPassOp
//===----------------------------------------------------------------------===//
-DiagnosedSilenceableFailure
-transform::ApplyRegisteredPassOp::applyToOne(Operation *target,
- ApplyToEachResultList &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure transform::ApplyRegisteredPassOp::applyToOne(
+ transform::TransformRewriter &rewriter, Operation *target,
+ ApplyToEachResultList &results, transform::TransformState &state) {
// Make sure that this transform is not applied to itself. Modifying the
// transform IR while it is being interpreted is generally dangerous. Even
// more so when applying passes because they may perform a wide range of IR
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::CastOp::applyToOne(Operation *target, ApplyToEachResultList &results,
+transform::CastOp::applyToOne(transform::TransformRewriter &rewriter,
+ Operation *target, ApplyToEachResultList &results,
transform::TransformState &state) {
results.push_back(target);
return DiagnosedSilenceableFailure::success();
}
DiagnosedSilenceableFailure
-transform::ForeachMatchOp::apply(transform::TransformResults &results,
+transform::ForeachMatchOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<std::pair<FunctionOpInterface, FunctionOpInterface>>
matchActionPairs;
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::ForeachOp::apply(transform::TransformResults &results,
+transform::ForeachOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<SmallVector<Operation *>> resultOps(getNumResults(), {});
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure transform::GetClosestIsolatedParentOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
SetVector<Operation *> parents;
for (Operation *target : state.getPayloadOps(getTarget())) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::GetConsumersOfResult::apply(transform::TransformResults &results,
+transform::GetConsumersOfResult::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
int64_t resultNumber = getResultNumber();
auto payloadOps = state.getPayloadOps(getTarget());
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::GetDefiningOp::apply(transform::TransformResults &results,
+transform::GetDefiningOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<Operation *> definingOps;
for (Value v : state.getPayloadValues(getTarget())) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::GetProducerOfOperand::apply(transform::TransformResults &results,
+transform::GetProducerOfOperand::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
int64_t operandNumber = getOperandNumber();
SmallVector<Operation *> producers;
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::GetResultOp::apply(transform::TransformResults &results,
+transform::GetResultOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
int64_t resultNumber = getResultNumber();
SmallVector<Value> opResults;
}
DiagnosedSilenceableFailure
-transform::IncludeOp::apply(transform::TransformResults &results,
+transform::IncludeOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
auto callee = SymbolTable::lookupNearestSymbolFrom<NamedSequenceOp>(
getOperation(), getTarget());
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::MatchParamCmpIOp::apply(transform::TransformResults &results,
+transform::MatchParamCmpIOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
auto signedAPIntAsString = [&](APInt value) {
std::string str;
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::ParamConstantOp::apply(transform::TransformResults &results,
+transform::ParamConstantOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
results.setParams(cast<OpResult>(getParam()), {getValue()});
return DiagnosedSilenceableFailure::success();
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::MergeHandlesOp::apply(transform::TransformResults &results,
+transform::MergeHandlesOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<Operation *> operations;
for (Value operand : getHandles())
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::NamedSequenceOp::apply(transform::TransformResults &results,
+transform::NamedSequenceOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
// Nothing to do here.
return DiagnosedSilenceableFailure::success();
}
DiagnosedSilenceableFailure
-transform::SplitHandleOp::apply(transform::TransformResults &results,
+transform::SplitHandleOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
int64_t numPayloadOps = llvm::range_size(state.getPayloadOps(getHandle()));
auto produceNumOpsError = [&]() {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::ReplicateOp::apply(transform::TransformResults &results,
+transform::ReplicateOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
unsigned numRepetitions = llvm::range_size(state.getPayloadOps(getPattern()));
for (const auto &en : llvm::enumerate(getHandles())) {
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::SequenceOp::apply(transform::TransformResults &results,
+transform::SequenceOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
// Map the entry block argument to the list of operations.
auto scope = state.make_region_scope(*getBodyBlock()->getParent());
}
DiagnosedSilenceableFailure
-transform::PrintOp::apply(transform::TransformResults &results,
+transform::PrintOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
llvm::outs() << "[[[ IR printer: ";
if (getName().has_value())
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::PDLMatchOp::apply(transform::TransformResults &results,
+transform::PDLMatchOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
auto *extension = state.getExtension<PatternApplicatorExtension>();
assert(extension &&
//===----------------------------------------------------------------------===//
DiagnosedSilenceableFailure
-transform::WithPDLPatternsOp::apply(transform::TransformResults &results,
+transform::WithPDLPatternsOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
TransformOpInterface transformOp = nullptr;
for (Operation &nested : getBody().front()) {
%1 = transform.structured.match ops{["test.foo"]} in %arg1 : (!transform.any_op) -> !transform.any_op
transform.apply_patterns to %0 {
transform.apply_patterns.transform.test_patterns
- } {fail_on_payload_replacement_not_found = false} : !transform.any_op
+ } {transform.silence_tracking_failures} : !transform.any_op
transform.annotate %1 "annotated" : !transform.any_op
}
return llvm::StringLiteral("transform.test_transform_op");
}
- DiagnosedSilenceableFailure apply(transform::TransformResults &results,
+ DiagnosedSilenceableFailure apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
InFlightDiagnostic remark = emitRemark() << "applying transformation";
if (Attribute message = getMessage())
"transform.test_transform_unrestricted_op_no_interface");
}
- DiagnosedSilenceableFailure apply(transform::TransformResults &results,
+ DiagnosedSilenceableFailure apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
return DiagnosedSilenceableFailure::success();
}
DiagnosedSilenceableFailure
mlir::test::TestProduceSelfHandleOrForwardOperandOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
if (getOperation()->getNumOperands() != 0) {
results.set(cast<OpResult>(getResult()),
DiagnosedSilenceableFailure
mlir::test::TestProduceValueHandleToSelfOperand::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
results.setValues(llvm::cast<OpResult>(getOut()), getIn());
return DiagnosedSilenceableFailure::success();
DiagnosedSilenceableFailure
mlir::test::TestProduceValueHandleToResult::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
if (target->getNumResults() <= getNumber())
return emitSilenceableError() << "payload has no result #" << getNumber();
DiagnosedSilenceableFailure
mlir::test::TestProduceValueHandleToArgumentOfParentBlock::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
if (!target->getBlock())
return emitSilenceableError() << "payload has no parent block";
}
DiagnosedSilenceableFailure
-mlir::test::TestConsumeOperand::apply(transform::TransformResults &results,
+mlir::test::TestConsumeOperand::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
return DiagnosedSilenceableFailure::success();
}
}
DiagnosedSilenceableFailure mlir::test::TestConsumeOperandOfOpKindOrFail::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
auto payload = state.getPayloadOps(getOperand());
assert(llvm::hasSingleElement(payload) && "expected a single target op");
}
DiagnosedSilenceableFailure mlir::test::TestPrintRemarkAtOperandOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
auto payload = state.getPayloadOps(getOperand());
for (Operation *op : payload)
}
DiagnosedSilenceableFailure mlir::test::TestPrintRemarkAtOperandValue::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
ArrayRef<Value> values = state.getPayloadValues(getIn());
for (Value value : values) {
transform::onlyReadsPayload(effects);
}
-DiagnosedSilenceableFailure
-mlir::test::TestAddTestExtensionOp::apply(transform::TransformResults &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure mlir::test::TestAddTestExtensionOp::apply(
+ transform::TransformRewriter &rewriter,
+ transform::TransformResults &results, transform::TransformState &state) {
state.addExtension<TestTransformStateExtension>(getMessageAttr());
return DiagnosedSilenceableFailure::success();
}
DiagnosedSilenceableFailure
mlir::test::TestCheckIfTestExtensionPresentOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
auto *extension = state.getExtension<TestTransformStateExtension>();
if (!extension) {
}
DiagnosedSilenceableFailure mlir::test::TestRemapOperandPayloadToSelfOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
auto *extension = state.getExtension<TestTransformStateExtension>();
if (!extension)
}
DiagnosedSilenceableFailure mlir::test::TestRemoveTestExtensionOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
state.removeExtension<TestTransformStateExtension>();
return DiagnosedSilenceableFailure::success();
}
-DiagnosedSilenceableFailure
-mlir::test::TestReversePayloadOpsOp::apply(transform::TransformResults &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure mlir::test::TestReversePayloadOpsOp::apply(
+ transform::TransformRewriter &rewriter,
+ transform::TransformResults &results, transform::TransformState &state) {
auto payloadOps = state.getPayloadOps(getTarget());
auto reversedOps = llvm::to_vector(llvm::reverse(payloadOps));
results.set(llvm::cast<OpResult>(getResult()), reversedOps);
}
DiagnosedSilenceableFailure mlir::test::TestTransformOpWithRegions::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
return DiagnosedSilenceableFailure::success();
}
DiagnosedSilenceableFailure
mlir::test::TestBranchingTransformOpTerminator::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
return DiagnosedSilenceableFailure::success();
}
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {}
DiagnosedSilenceableFailure mlir::test::TestEmitRemarkAndEraseOperandOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
emitRemark() << getRemark();
for (Operation *op : state.getPayloadOps(getTarget()))
}
DiagnosedSilenceableFailure mlir::test::TestWrongNumberOfResultsOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
OperationState opState(target->getLoc(), "foo");
results.push_back(OpBuilder(target).create(opState));
DiagnosedSilenceableFailure
mlir::test::TestWrongNumberOfMultiResultsOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
static int count = 0;
if (count++ == 0) {
DiagnosedSilenceableFailure
mlir::test::TestCorrectNumberOfMultiResultsOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
OperationState opState(target->getLoc(), "foo");
results.push_back(OpBuilder(target).create(opState));
DiagnosedSilenceableFailure
mlir::test::TestMixedNullAndNonNullResultsOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
OperationState opState(target->getLoc(), "foo");
results.push_back(nullptr);
DiagnosedSilenceableFailure
mlir::test::TestMixedSuccessAndSilenceableOp::applyToOne(
- Operation *target, transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ transform::ApplyToEachResultList &results,
transform::TransformState &state) {
if (target->hasAttr("target_me"))
return DiagnosedSilenceableFailure::success();
DiagnosedSilenceableFailure
mlir::test::TestPrintNumberOfAssociatedPayloadIROps::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
if (!getHandle())
emitRemark() << 0;
}
DiagnosedSilenceableFailure
-mlir::test::TestCopyPayloadOp::apply(transform::TransformResults &results,
+mlir::test::TestCopyPayloadOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
results.set(llvm::cast<OpResult>(getCopy()),
state.getPayloadOps(getHandle()));
DiagnosedSilenceableFailure
mlir::test::TestReportNumberOfTrackedHandlesNestedUnder::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
int64_t count = 0;
for (Operation *op : state.getPayloadOps(getTarget())) {
}
DiagnosedSilenceableFailure
-mlir::test::TestPrintParamOp::apply(transform::TransformResults &results,
+mlir::test::TestPrintParamOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
std::string str;
llvm::raw_string_ostream os(str);
}
DiagnosedSilenceableFailure
-mlir::test::TestAddToParamOp::apply(transform::TransformResults &results,
+mlir::test::TestAddToParamOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
SmallVector<uint32_t> values(/*Size=*/1, /*Value=*/0);
if (Value param = getParam()) {
DiagnosedSilenceableFailure
mlir::test::TestProduceParamWithNumberOfTestOps::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
Builder builder(getContext());
SmallVector<Attribute> result = llvm::to_vector(
DiagnosedSilenceableFailure
mlir::test::TestProduceIntegerParamWithTypeOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
Attribute zero = IntegerAttr::get(getType(), 0);
results.setParams(llvm::cast<OpResult>(getResult()), zero);
DiagnosedSilenceableFailure
mlir::test::TestProduceTransformParamOrForwardOperandOp::applyToOne(
- Operation *target, ::transform::ApplyToEachResultList &results,
+ transform::TransformRewriter &rewriter, Operation *target,
+ ::transform::ApplyToEachResultList &results,
::transform::TransformState &state) {
Builder builder(getContext());
if (getFirstResultIsParam()) {
}
DiagnosedSilenceableFailure mlir::test::TestProduceNullPayloadOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
SmallVector<Operation *, 1> null({nullptr});
results.set(llvm::cast<OpResult>(getOut()), null);
}
DiagnosedSilenceableFailure mlir::test::TestProduceEmptyPayloadOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
results.set(cast<OpResult>(getOut()), {});
return DiagnosedSilenceableFailure::success();
transform::producesHandle(getOut(), effects);
}
-DiagnosedSilenceableFailure
-mlir::test::TestProduceNullParamOp::apply(transform::TransformResults &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure mlir::test::TestProduceNullParamOp::apply(
+ transform::TransformRewriter &rewriter,
+ transform::TransformResults &results, transform::TransformState &state) {
results.setParams(llvm::cast<OpResult>(getOut()), Attribute());
return DiagnosedSilenceableFailure::success();
}
transform::producesHandle(getOut(), effects);
}
-DiagnosedSilenceableFailure
-mlir::test::TestProduceNullValueOp::apply(transform::TransformResults &results,
- transform::TransformState &state) {
+DiagnosedSilenceableFailure mlir::test::TestProduceNullValueOp::apply(
+ transform::TransformRewriter &rewriter,
+ transform::TransformResults &results, transform::TransformState &state) {
results.setValues(llvm::cast<OpResult>(getOut()), Value());
return DiagnosedSilenceableFailure::success();
}
}
DiagnosedSilenceableFailure mlir::test::TestRequiredMemoryEffectsOp::apply(
+ transform::TransformRewriter &rewriter,
transform::TransformResults &results, transform::TransformState &state) {
results.set(llvm::cast<OpResult>(getOut()), state.getPayloadOps(getIn()));
return DiagnosedSilenceableFailure::success();
}
DiagnosedSilenceableFailure
-mlir::test::TestTrackedRewriteOp::apply(transform::TransformResults &results,
+mlir::test::TestTrackedRewriteOp::apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
- transform::ErrorCheckingTrackingListener listener(state, *this);
- IRRewriter rewriter(getContext(), &listener);
int64_t numIterations = 0;
// `getPayloadOps` returns an iterator that skips ops that are erased in the
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state) {
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation * target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation * target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation * target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation * target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation * target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let extraClassDeclaration = [{
::mlir::DiagnosedSilenceableFailure applyToOne(
+ ::mlir::transform::TransformRewriter &rewriter,
::mlir::Operation *target,
::mlir::transform::ApplyToEachResultList &results,
::mlir::transform::TransformState &state);
let cppNamespace = "::mlir::test";
let extraClassDeclaration = [{
- DiagnosedSilenceableFailure apply(transform::TransformResults &results,
+ DiagnosedSilenceableFailure apply(transform::TransformRewriter &rewriter,
+ transform::TransformResults &results,
transform::TransformState &state) {
llvm_unreachable("op should not be used as a transform");
return DiagnosedSilenceableFailure::definiteFailure();