summaryrefslogtreecommitdiff
path: root/mlir/lib/Dialect/Transform/IR/TransformDialect.cpp
AgeCommit message (Collapse)Author
2025-10-06[mlir] transform dialect: don't crash in verifiers (#161098)Oleksandr "Alex" Zinenko
Fix crashes in the verifier of `transform.with_named_sequence` attribute attached to a symbol table operation caused by it constructing a call graph inside the symbol table. The call graph construction assumes calls and callables, such as functions or named sequences, have been verified, but it is not yet the case when the attribute verifier on the (parent) symbol table operation runs. Trigger such verification manually before constructing the call graph. This adds redundancy in verification, but there is currently no mechanism to change the order of verificaiton. In performance-critical scenarios, verification can be disabled altogether. Remove unnecessary verfificaton from `transform::IncludeOp::getEffects`. It was introduced along with the op definition as the op used to inspect the body of callee, which assumed the body existed, to identify handle consumption behavior. This was later evolved to having explicit argument attributes on the callee, which handles the absence of such attributes gracefully without the need for verification, but the verification was never removed. It would have been causing infinite recursion if kept in place. Fixes #159646. Fixes #159734. Fixes #159736.
2025-07-11[mlir] Remove unused includes (NFC) (#148119)Kazu Hirata
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-06-11[MLIR][Transform] apply_registered_pass op's options as a dict (#143159)Rolf Morel
Improve ApplyRegisteredPassOp's support for taking options by taking them as a dict (vs a list of string-valued key-value pairs). Values of options are provided as either static attributes or as params (which pass in attributes at interpreter runtime). In either case, the keys and value attributes are converted to strings and a single options-string, in the format used on the commandline, is constructed to pass to the `addToPipeline`-pass API.
2024-09-22[mlir] Don't call llvm::raw_string_ostream::flush() (NFC)Youngsuk Kim
Don't call raw_string_ostream::flush(), which is essentially a no-op. As specified in the docs, raw_string_ostream is always unbuffered. ( 65b13610a5226b84889b923bae884ba395ad084d for further reference )
2024-03-20[mlir] split transform interfaces into a separate library (#85221)Oleksandr "Alex" Zinenko
Transform interfaces are implemented, direction or via extensions, in libraries belonging to multiple other dialects. Those dialects don't need to depend on the non-interface part of the transform dialect, which includes the growing number of ops and transitive dependency footprint. Split out the interfaces into a separate library. This in turn requires flipping the dependency from the interface on the dialect that has crept in because both co-existed in one library. The interface shouldn't depend on the transform dialect either. As a consequence of splitting, the capability of the interpreter to automatically walk the payload IR to identify payload ops of a certain kind based on the type used for the entry point symbol argument is disabled. This is a good move by itself as it simplifies the interpreter logic. This functionality can be trivially replaced by a `transform.structured.match` operation.
2023-10-25[mlir][transform] Handle multiple library preloading passes. (#69705)Ingo Müller
This is a new attempt at #69320. The transform dialect stores a "library module" that the preload pass can populate. Until now, each pass registered an additional module by simply pushing it to a vector; however, the interpreter only used the first of them. This commit turns the registration into "loading", i.e., each newly added module gets merged into the existing one. This allows the loading to be split into several passes, and using the library in the interpreter now takes all of them into account. While this design avoids repeated merging every time the library is accessed, it requires that the implementation of merging modules lives in the TransformDialect target (since it at the dialect depend on each other). This resolves https://github.com/llvm/llvm-project/issues/69111.
2023-08-07[mlir][transform] Add apply_conversion_patterns opMatthias Springer
This transform op applies a dialect conversion to the targeted ops. Its design is similar to `apply_patterns`. Patterns are specified in the first region of `apply_conversion_patterns`. They must implement the `ConversionPatternDescriptorOpInterface`. Regular rewrite patterns and dialect conversion patterns should not be mixed, so the interface is separate from the `PatternDescriptorOpInterface`. The type converter is specified as the single op of the second region. It is optional; if no type converter is specified, it is expected that pattern descriptors provide their own type converters. If both the pattern descriptors and the `apply_conversion_patterns` op specify a type converter, the type converter of the pattern descriptor is used. Differential Revision: https://reviews.llvm.org/D157109
2023-06-20[mlir][transform] Add TransformRewriterMatthias Springer
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
2023-06-06[mlir][transform] Add region to ApplyPatternsOpMatthias Springer
Patterns should be selected by adding ops that implement `PatternDescriptorOpInterface` to the region of `apply_pattern` ops. Such ops can have operands, allowing for pattern parameterization. The existing way of selecting patterns from the PatternRegistry is deprecated. Differential Revision: https://reviews.llvm.org/D152167
2023-06-05[mlir][transform] ApplyPatternsOp: Register canonicalization patternsMatthias Springer
Also support replacing payload ops with ConstantLike ops in the TrackingListener, even if the replacement op does not have the same name. (Not supported for ops with multiple results, as this would require splitting the handle.) Differential Revision: https://reviews.llvm.org/D152127
2023-05-24[mlir] move PDL-related transform ops into an extensionAlex Zinenko
The initial bring-up of the Transform dialect relied on PDL to provide the default handle type (`!pdl.operation`) and the matching capability. Both are now provided natively by the Transform dialect removing the reason to have a hard dependency on the PDL dialect and its interpreter. Move PDL-related transform operations into a separate extension. This requires us to introduce a dialect state extension mechanism into the Transform dialect so it no longer needs to know about PDL constraint functions that may be injected by extensions similarly to operations and types. This mechanism will be reused to connect pattern application drivers and the Transform dialect. This completes the restructuring of the Transform dialect to remove overrilance on PDL. Note to downstreams: flow that are using `!pdl.operation` with Transform dialect operations will now require `transform::PDLExtension` to be applied to the transform dialect in order to provide the transform handle type interface for `!pdl.operation`. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D151104
2023-05-12[mlir] Update method cast calls to function callsTres Popp
The MLIR classes Type/Attribute/Operation/Op/Value support cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast functionality in addition to defining methods with the same name. This change begins the migration of uses of the method to the corresponding function call as has been decided as more consistent. Note that there still exist classes that only define methods directly, such as AffineExpr, and this does not include work currently to support a functional cast/isa call. Context: * https://mlir.llvm.org/deprecation/ at "Use the free function variants for dyn_cast/cast/isa/…" * Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443 Implementation: This follows a previous patch that updated calls `op.cast<T>()-> cast<T>(op)`. However some cases could not handle an unprefixed `cast` call due to occurrences of variables named cast, or occurring inside of class definitions which would resolve to the method. All C++ files that did not work automatically with `cast<T>()` are updated here to `llvm::cast` and similar with the intention that they can be easily updated after the methods are removed through a find-replace. See https://github.com/llvm/llvm-project/compare/main...tpopp:llvm-project:tidy-cast-check for the clang-tidy check that is used and then update printed occurrences of the function to include `llvm::` before. One can then run the following: ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -export-fixes /tmp/cast/casts.yaml mlir/*\ -header-filter=mlir/ -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc ``` Differential Revision: https://reviews.llvm.org/D150348
2023-04-13[mlir] add structured (Linalg) transform op matchersAlex Zinenko
Add a set of transform operations into the "structured" extension of the Transform dialect that allow one to select transformation targets more specifically than the currently available matching. In particular, add the mechanism for identifying the producers of operands (input and init in destination-passing style) and users of results, as well as mechanisms for reasoning about the shape of the iteration space. Additionally, add several transform operations to manipulate parameters that could be useful to implement more advanced selectors. Specifically, new operations let one produce and compare parameter values to implement shape-driven transformations. New operations are placed in separate files to decrease compilation time. Some relayering of the extension is necessary to avoid repeated generation of enums. Depends on D148013 Depends on D148014 Depends on D148015 Reviewed By: chelini Differential Revision: https://reviews.llvm.org/D148017
2023-04-04[mlir] add readonly/consume annotations to transform named sequencesAlex Zinenko
Use the argument attribute mechanism for function-like operations to annotate the arguments of named transform sequences as consuming or only reading the handles passed as arguments. This makes it possible to correctly specify handle invalidation for external named sequences by requiring their declarations to always provide such annotations. Additionally, these annotations remove the need to analyze the body of a named sequence to understand its effects on the arguments. Make them required for named sequences that are called from the same file, in addition to external sequences. Provide a convenience pass that infers annotations by analyzing bodies of named sequences provided they are not called from the same file. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D147223
2023-03-21[mlir] Transform dialect: add named sequencesAlex Zinenko
Named sequences introduce an additional abstraction and reuse capability to the transform dialect. They can be though of as macros parameterized with handles that can be invoked in places where a transform dialect operation is expected. Such reuse was previously not possible in the dialect and required dynamic construction of the transform IR from the client language. Named sequences are intentionally restricted to disallow recursion, as it could make the dialect accidentally Turing-complete, which isn't desired at this point. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D146433
2023-02-09[mlir] add support for transform dialect value handlesAlex Zinenko
Introduce support for the third kind of values in the transform dialect: value handles. Similarly to operation handles, value handles are pointing to a set of values in the payload IR. This enables transformation to be targeted at specific values, such as individual results of a multi-result payload operation without indirecting through the producing op or block arguments that previously could not be easily addressed. This is expected to support a broad class of memory-oriented transformations such as selective bufferization, buffer assignment, and memory transfer management. Value handles are functionally similar to operation handles and require similar implementation logic. The most important change concerns the handle invalidation mechanism where operation and value handles can affect each other. This patch includes two cleanups that make it easier to introduce value handles: - `RaggedArray` structure that encapsulates the SmallVector of ArrayRef backed by flat SmallVector logic, frequently used in the transform interfaces implementation; - rewrite the tests that associated payload handles with an integer value `reinterpret_cast`ed as a pointer, which were a frequent source of confusion and crashes when adding more debugging facilities that can inspect the payload. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D143385
2023-01-22[NFC] Fix "form/from" typosPiotr Fusik
Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D142007
2023-01-06[mlir] NFC: rename TransformTypeInterface to TransformHandleTypeInterfaceAlex Zinenko
This makes it more consistent with the recently added TransformParamTypeInterface. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D140977
2023-01-06[mlir] introduce parameters into the transofrm dialectAlex Zinenko
Introduce a new kind of values into the transform dialect -- parameter values. These values have a type implementing the new `TransformParamTypeInterface` and are associated with lists of attributes rather than lists of payload operations. This mechanism allows one to wrap numeric calculations, typically heuristics, into transform operations separate from those at actually applying the transformation. For example, tile size computation can be now separated from tiling itself, and not hardcoded in the transform dialect. This further improves the separation of concerns between transform choice and implementation. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D140976
2022-10-11[mlir] add OperationType to the Transform dialectAlex Zinenko
Add a new OperationType handle type to the Transform dialect. This transform type is parameterized by the name of the payload operation it can point to. It is intended as a constraint on transformations that are only applicable to a specific kind of payload operations. If a transformation is applicable to a small set of operation classes, it can be wrapped into a transform op by using a disjunctive constraint, such as `Type<Or<[Transform_ConcreteOperation<"foo">.predicate, Transform_ConcreteOperation<"bar">.predicate]>>` for its operand without modifying this type. Broader sets of accepted operations should be modeled as specific types. Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D135586
2022-10-11[mlir] switch transform dialect ops to use TransformTypeInterfaceAlex Zinenko
Use the recently introduced TransformTypeInterface instead of hardcoding the PDLOperationType. This will allow the operations to use more specific transform types to express pre/post-conditions in the future. It requires the syntax and Python op construction API to be updated. Dialect extensions will be switched separately. Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D135584
2022-10-11[mlir] clean up transform dialect definitions, NFCAlex Zinenko
Refactor the definition of the Transform dialect to move non-trivial method implementations out of the .td file, and detemplatize functions when possible while moving their implementations to a .cpp. Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D135165
2022-10-11[mlir] add types to the transform dialectAlex Zinenko
Introduce a type system for the transform dialect. A transform IR type captures the expectations of the transform IR on the payload IR operations that are being transformed, such as being of a certain kind or implementing an interface that enables the transformation. This provides stricter checking and better readability of the transform IR than using the catch-all "handle" type. This change implements the basic support for a type system amendable to dialect extensions and adds a drop-in replacement for the unrestricted "handle" type. The actual switch of transform dialect ops to that type will happen in a separate commit. See https://discourse.llvm.org/t/rfc-type-system-for-the-transform-dialect/65702 Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D135164
2022-08-12[mlir][transform] failure propagation mode in sequenceAlex Zinenko
Introduce two different failure propagation mode in the Transform dialect's Sequence operation. These modes specify whether silenceable errors produced by nested ops are immediately propagated, thus stopping the sequence, or suppressed. The latter is useful in end-to-end transform application scenarios where the user cannot correct the transformation, but it is robust enough to silenceable failures. It can be combined with the "alternatives" operation. There is intentionally no default value to avoid favoring one mode over the other. Downstreams can update their tests using: S='s/sequence \(%.*\) {/sequence \1 failures(propagate) {/' T='s/sequence {/sequence failures(propagate) {/' git grep -l transform.sequence | xargs sed -i -e "$S" git grep -l transform.sequence | xargs sed -i -e "$T" Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D131774
2022-04-23[mlir][NFC] Shift a bunch of dialect includes from the .h to the .cppRiver Riddle
Now that dialect constructors are generated in the .cpp file, we can drop all of the dependent dialect includes from the .h file. Differential Revision: https://reviews.llvm.org/D124298
2022-04-22[mlir] use side effects in the Transform dialectAlex Zinenko
Currently, the sequence of Transform dialect operations only supports a single use of each operand (verified by the `transform.sequence` operation). This was originally motivated by the need to guard against accessing a payload IR operation associated with a transform IR value after this operation has likely been rewritten by a transformation. However, not all Transform dialect operations rewrite payload IR, in particular the "navigation" operation such as `transform.pdl_match` do not. Introduce memory effects to the Transform dialect operations to describe their effect on the payload IR and the mapping between payload IR opreations and transform IR values. Use these effects to replace the single-use rule, allowing repeated reads and disallowing use-after-free, where operations with the "free" effect are considered to "consume" the transform IR value and rewrite the corresponding payload IR operations). As an additional improvement, this enables code motion transformation on the transform IR itself. Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D124181
2022-04-21[mlir] Connect Transform dialect to PDLAlex Zinenko
This introduces a pair of ops to the Transform dialect that connect it to PDL patterns. Transform dialect relies on PDL for matching the Payload IR ops that are about to be transformed. For this purpose, it provides a container op for patterns, a "pdl_match" op and transform interface implementations that call into the pattern matching infrastructure. To enable the caching of compiled patterns, this also provides the extension mechanism for TransformState. Extensions allow one to store additional information in the TransformState and thus communicate it between different Transform dialect operations when they are applied. They can be added and removed when applying transform ops. An extension containing a symbol table in which the pattern names are resolved and a pattern compilation cache is introduced as the first client. Depends On D123664 Reviewed By: Mogball Differential Revision: https://reviews.llvm.org/D124007
2022-04-19[mlir][transform] Introduce transform.sequence opAlex Zinenko
Sequence is an important transform combination primitive that just indicates transform ops being applied in a row. The simplest version requires fails immediately if any transformation in the sequence fails. Introducing this operation allows one to start placing transform IR within other IR. Depends On D123135 Reviewed By: Mogball, rriddle Differential Revision: https://reviews.llvm.org/D123664
2022-04-14[mlir] Introduce Transform dialectAlex Zinenko
This dialect provides operations that can be used to control transformation of the IR using a different portion of the IR. It refers to the IR being transformed as payload IR, and to the IR guiding the transformation as transform IR. The main use case for this dialect is orchestrating fine-grain transformations on individual operations or sets thereof. For example, it may involve finding loop-like operations with specific properties (e.g., large size) in the payload IR, applying loop tiling to those and only those operations, and then applying loop unrolling to the inner loops produced by the previous transformations. As such, it is not intended as a replacement for the pass infrastructure, nor for the pattern rewriting infrastructure. In the most common case, the transform IR will be processed and applied to payload IR by a pass. Transformations expressed by the transform dialect may be implemented using the pattern infrastructure or any other relevant MLIR component. This dialect is designed to be extensible, that is, clients of this dialect are allowed to inject additional operations into this dialect using the newly introduced in this patch `TransformDialectExtension` mechanism. This allows the dialect to avoid a dependency on the implementation of the transformation as well as to avoid introducing dialect-specific transform dialects. See https://discourse.llvm.org/t/rfc-interfaces-and-dialects-for-precise-ir-transformation-control/60927. Reviewed By: nicolasvasilache, Mogball, rriddle Differential Revision: https://reviews.llvm.org/D123135