summaryrefslogtreecommitdiff
path: root/mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp
AgeCommit message (Collapse)Author
2025-07-24[mlir][NFC] update `mlir/Dialect` create APIs (18/n) (#149925)Maksim Levental
See https://github.com/llvm/llvm-project/pull/147168 for more info.
2025-07-12[llvm] Remove unused includes (NFC) (#148342)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.
2024-08-06[mlir] Support DialectRegistry extension comparison (#101119)Nikhil Kalra
`PassManager::run` loads the dependent dialects for each pass into the current context prior to invoking the individual passes. If the dependent dialect is already loaded into the context, this should be a no-op. However, if there are extensions registered in the `DialectRegistry`, the dependent dialects are unconditionally registered into the context. This poses a problem for dynamic pass pipelines, however, because they will likely be executing while the context is in an immutable state (because of the parent pass pipeline being run). To solve this, we'll update the extension registration API on `DialectRegistry` to require a type ID for each extension that is registered. Then, instead of unconditionally registered dialects into a context if extensions are present, we'll check against the extension type IDs already present in the context's internal `DialectRegistry`. The context will only be marked as dirty if there are net-new extension types present in the `DialectRegistry` populated by `PassManager::getDependentDialects`. Note: this PR removes the `addExtension` overload that utilizes `std::function` as the parameter. This is because `std::function` is copyable and potentially allocates memory for the contained function so we can't use the function pointer as the unique type ID for the extension. Downstream changes required: - Existing `DialectExtension` subclasses will need a type ID to be registered for each subclass. More details on how to register a type ID can be found here: https://github.com/llvm/llvm-project/blob/8b68e06731e0033ed3f8d6fe6292ae671611cfa1/mlir/include/mlir/Support/TypeID.h#L30 - Existing uses of the `std::function` overload of `addExtension` will need to be refactored into dedicated `DialectExtension` classes with associated type IDs. The attached `std::function` can either be inlined into or called directly from `DialectExtension::apply`. --------- Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2024-06-19[mlir][side effect] refactor(*): Include more precise side effects (#94213)donald chen
This patch adds more precise side effects to the current ops with memory effects, allowing us to determine which OpOperand/OpResult/BlockArgument the operation reads or writes, rather than just recording the reading and writing of values. This allows for convenient use of precise side effects to achieve analysis and optimization. Related discussions: https://discourse.llvm.org/t/rfc-add-operandindex-to-sideeffect-instance/79243
2024-04-19Switch member calls to `isa/dyn_cast/cast/...` to free function calls. (#89356)Christian Sigg
This change cleans up call sites. Next step is to mark the member functions deprecated. See https://mlir.llvm.org/deprecation and https://discourse.llvm.org/t/preferred-casting-style-going-forward.
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-11-03[MLIR][MemRefToLLVM] Remove last typed pointer remnants (#71113)Christian Ulmann
This commit removes the last typed pointer remnants from the MemRef to LLVM conversions, including the transform dialect operation. Typed pointers have been deprecated for a while now and it's planned to soon remove them from the LLVM dialect. Related PSA: https://discourse.llvm.org/t/psa-removal-of-typed-pointers-from-the-llvm-dialect/74502
2023-09-21[mlir][memref][transform] Add new alloca_to_global op. (#66511)Ingo Müller
This PR adds a new transform op that replaces `memref.alloca`s with `memref.get_global`s to newly inserted `memref.global`s. This is useful, for example, for allocations that should reside in the shared memory of a GPU, which have to be declared as globals.
2023-09-05[mlir] alloc-to-alloca conversion for memref (#65335)Oleksandr "Alex" Zinenko
Introduce a simple conversion of a memref.alloc/dealloc pair into an alloca in the same scope. Expose it as a transform op and a pattern. Allocas typically lower to stack allocations as opposed to alloc/dealloc that lower to significantly more expensive malloc/free calls. In addition, this can be combined with allocation hoisting from loops to further improve performance.
2023-09-01[mlir][memref] Add support for erasing dead allocations.Hanhan Wang
Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D159135
2023-08-10[mlir][Transform] Add support to drive conversions of func to LLVM with TDNicolas Vasilache
This revision adds a `transform.apply_conversion_patterns.func.func_to_llvm` transformation. It is unclear at this point whether this should be spelled out as a standalone transformation or whether it should resemble `transform.apply_conversion_patterns.dialect_to_llvm "fun"`. This is dependent on how we want to handle the type converter creation. In particular the current implementation exhibits the fact that `transform.apply_conversion_patterns.memref.memref_to_llvm_type_converter` was not rich enough and did not match the LowerToLLVMOptions. Keeping those options in sync across all the passes that lower to LLVM is very error prone. Instead, we should have a single `to_llvm_type_converter`. Differential Revision: https://reviews.llvm.org/D157553
2023-08-09[mlir][memref][transform] Add vector_to_llvm conversion patternsMatthias Springer
These patterns are exposed via a new "apply_conversion_patterns" op. Also provide a new type converter that converts from memref to LLVM types. Conversion patterns that lower to LLVM are special: they require an `LLVMTypeConverter`; a normal `TypeConverter` is not enough. This revision also adds a new interface method to pattern descriptor ops to verify that the default type converter of the enclosing "apply_conversion_patterns" op is compatible with the set of patterns. At the moment, a simple `StringRef` is used. This can evolve to a richer type in the future if needed. Differential Revision: https://reviews.llvm.org/D157369
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] Use separate ops instead of PatternRegistryMatthias Springer
* Remove `transform::PatternRegistry`. * Add a new op for each currently registered pattern set. * Change names of vector dialect pattern selector ops, so that they are consistent with the remaining code base. * Remove redundant `transform.vector.extract_address_computations` op. Differential Revision: https://reviews.llvm.org/D152249
2023-06-05[mlir][memref][transform] Register memref dialect patternsMatthias Springer
Differential Revision: https://reviews.llvm.org/D151998
2023-05-17[mlir] don't hardcode PDL_Operation in Transform dialect extensionsAlex Zinenko
Update operations in Transform dialect extensions defined in the Affine, GPU, MemRef and Tensor dialects to use the more generic `TransformHandleTypeInterface` type constraint instead of hardcoding `PDL_Operation`. See https://discourse.llvm.org/t/rfc-type-system-for-the-transform-dialect/65702 for motivation. Remove the dependency on PDLDialect from these extensions. Update tests to use `!transform.any_op` instead of `!pdl.operation`. Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D150781
2023-05-15[mlir][transform] Use TrackingListener-aware iterator for getPayloadOpsMatthias Springer
Instead of returning an `ArrayRef<Operation *>`, return at iterator that skips ops that were erased/replaced while iterating over the payload ops. This fixes an issue in conjuction with TrackingListener, where a tracked op was erased during the iteration. Elements may not be removed from an array while iterating over it; this invalidates the iterator. When ops are erased/removed via `replacePayloadOp`, they are not immediately removed from the mappings data structure. Instead, they are set to `nullptr`. `nullptr`s are not enumerated by `getPayloadOps`. At the end of each transformation, `nullptr`s are removed from the mapping data structure. Differential Revision: https://reviews.llvm.org/D149847
2023-05-12[mlir] Move casting calls from methods 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. Caveats include: - This clang-tidy script probably has more problems. - This only touches C++ code, so nothing that is being generated. 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 first patch was created with the following steps. The intention is to only do automated changes at first, so I waste less time if it's reverted, and so the first mass change is more clear as an example to other teams that will need to follow similar steps. Steps are described per line, as comments are removed by git: 0. Retrieve the change from the following to build clang-tidy with an additional check: https://github.com/llvm/llvm-project/compare/main...tpopp:llvm-project:tidy-cast-check 1. Build clang-tidy 2. Run clang-tidy over your entire codebase while disabling all checks and enabling the one relevant one. Run on all header files also. 3. Delete .inc files that were also modified, so the next build rebuilds them to a pure state. 4. Some changes have been deleted for the following reasons: - Some files had a variable also named cast - Some files had not included a header file that defines the cast functions - Some files are definitions of the classes that have the casting methods, so the code still refers to the method instead of the function without adding a prefix or removing the method declaration at the same time. ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -header-filter=mlir/ mlir/* -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc git restore mlir/lib/IR mlir/lib/Dialect/DLTI/DLTI.cpp\ mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp\ mlir/lib/**/IR/\ mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp\ mlir/lib/Dialect/Vector/Transforms/LowerVectorMultiReduction.cpp\ mlir/test/lib/Dialect/Test/TestTypes.cpp\ mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp\ mlir/test/lib/Dialect/Test/TestAttributes.cpp\ mlir/unittests/TableGen/EnumsGenTest.cpp\ mlir/test/python/lib/PythonTestCAPI.cpp\ mlir/include/mlir/IR/ ``` Differential Revision: https://reviews.llvm.org/D150123
2023-05-04[mlir][memref] Add helper to make alloca ops independentMatthias Springer
Add a helper function that makes dynamic sizes of `memref.alloca` ops independent of a given set of values. This functionality can be used to make dynamic allocations hoistable from loops. Differential Revision: https://reviews.llvm.org/D149316
2023-04-20[mlir][Affine][NFC] Wrap dialect in "affine" namespaceMatthias Springer
This cleanup aligns the affine dialect with all the other dialects. Differential Revision: https://reviews.llvm.org/D148687
2023-03-28[mlir][MemRef] Add patterns to extract address computationsQuentin Colombet
This patch adds patterns to rewrite memory accesses such that the resulting accesses are only using a base pointer. E.g., ```mlir memref.load %base[%off0, ...] ``` Will be rewritten in: ```mlir %new_base = memref.subview %base[%off0,...][1,...][1,...] memref.load %new_base[%c0,...] ``` The idea behind these patterns is to offer a way to more gradually lower address computations. These patterns are the exact opposite of FoldMemRefAliasOps. I've implemented the support of only five operations in this patch: - memref.load - memref.store - nvgpu.ldmatrix - vector.transfer_read - vector.transfer_write Going forward we may want to provide an interface for these rewritings (and the ones in FoldMemRefAliasOps.) One step at a time! Differential Revision: https://reviews.llvm.org/D146724
2023-03-01[mlir][MemRef] Rewrite multi-buffering with proper composable abstractionsNicolas Vasilache
Rewrite and document multi-buffering properly: 1. Use IndexingUtils / StaticValueUtils instead of duplicating functionality 2. Properly plumb RewriterBase through. 3. Add support 4. Better debug messages. This revision is otherwise almost NFC, if it weren't for the extra DeallocOp support that would previoulsy make multi-buffering fail. Depends on: D145036 Differential Revision: https://reviews.llvm.org/D145055
2023-02-17[mlir] add option to multi-bufferingThomas Raoux
Allow user to apply multi-buffering transformation for cases where proving that there is no loop carried dependency is not trivial. In this case user needs to ensure that the data are written and read in the same iteration otherwise the result is incorrect. Differential Revision: https://reviews.llvm.org/D144227
2023-02-13[mlir][MemRef][Transform] Don't apply multibuffer on "useless" allocsQuentin Colombet
`alloc`s that have users outside of loops are guaranteed to fail in `multibuffer`. Instead of exposing ourselves to that failure in the transform dialect, filter out the `alloc`s that fall in this category. To be able to do this filtering we have to change the `multibuffer` transform op from `TransformEachOpTrait` to a plain `TransformOp`. This is because `TransformEachOpTrait` expects that every successful `applyToOne` returns a non-empty result. Couple of notes: - I changed the assembly syntax to make sure we only get `alloc` ops as input. (And added a test case to make sure we reject invalid inputs.) - `multibuffer` can still fail pretty easily when you know its limitations. See the updated `op failed to multibuffer` test case for instance. Longer term, instead of leaking/coupling the actual implementation (in this case the checks normally done in `memref::multiBuffer`) with the transform dialect (the added check in `::apply`), we may want to refactor how we structure the underlying implementation. E.g., we could imagine a `canApply` method for all the implementations that we want to hook up in the transform dialect. This has some implications on how not to duplicate work between `canApply` and the actual implementation but I thought I throw that here to have us think about it :). Differential Revision: https://reviews.llvm.org/D143747
2023-02-13[mlir][MemRef][TransformOps] Fix error reporting for multibufferQuentin Colombet
Multibuffer will fail to apply on allocs that are used outside of loops. This was properly caught in the current implementation but the way we report it was broken. Notes cannot be emitted on their own, they need to be attached to another main diagnostic. Long story short, change the severity of the report from Note to Error. Differential Revision: https://reviews.llvm.org/D143729
2023-01-06[mlir] adapt TransformEachOpTrait to parameter valuesAlex Zinenko
Adapt the implementation of TransformEachOpTrait to the existence of parameter values recently introduced into the transform dialect. In particular, allow `applyToOne` hooks to return a list containing a mix of `Operation *` that will be associated with handles and `Attribute` that will be associated with parameter values by the trait implementation of the transform interface's `apply` method. Disentangle the "transposition" of the list of per-payload op partial results to decrease its overall complexity and detemplatize the code that doesn't really need templates. This removes the poorly documented special handling for single-result ops with TransformEachOpTrait that could have assigned null pointer values to handles. Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D140979
2022-12-17[mlir] llvm::Optional::value => operator*/operator->Fangrui Song
std::optional::value() has undesired exception checking semantics and is unavailable in older Xcode (see _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS). The call sites block std::optional migration.
2022-12-12[mlir] make DiagnosedSilenceableError(LogicalResult) ctor privateAlex Zinenko
Now we have more convenient functions to construct silenceable errors while emitting diagnostics, and the constructor is ambiguous as it doesn't tell whether the logical error is silencebale or definite. Reviewed By: nicolasvasilache Differential Revision: https://reviews.llvm.org/D137257
2022-09-29[mlir][arith] Change dialect name from Arithmetic to ArithJakub Kuderski
Suggested by @lattner in https://discourse.llvm.org/t/rfc-define-precise-arith-semantics/65507/22. Tested with: `ninja check-mlir check-mlir-integration check-mlir-mlir-spirv-cpu-runner check-mlir-mlir-vulkan-runner check-mlir-examples` and `bazel build --config=generic_clang @llvm-project//mlir:all`. Reviewed By: lattner, Mogball, rriddle, jpienaar, mehdi_amini Differential Revision: https://reviews.llvm.org/D134762
2022-09-28[mlir][transform] Add multi-buffering to the transform dialectKirsten Lee
Add the plumbing necessary to call the memref dialect's multiBuffer function. This will allow separation between choosing which buffers to multi-buffer and the actual transform. Alter the multibuffer function to return the newly created allocation if multi-buffering succeeds. This is necessary to communicate with the transform dialect hooks what allocation multi-buffering created. Reviewed By: ftynse, nicolasvasilache Differential Revision: https://reviews.llvm.org/D133985