summaryrefslogtreecommitdiff
path: root/mlir/lib/Dialect/MemRef/Transforms/ExpandStridedMetadata.cpp
AgeCommit message (Collapse)Author
2025-11-12[mlir][memref] Remove invalid `extract_aligned_pointer_as_index` folding in ↵Ivan Butygin
`ExpandStridedMetadata` (#167615) `RewriteExtractAlignedPointerAsIndexOfViewLikeOp` tries to propagate `extract_aligned_pointer_as_index` through the view ops. `ViewLikeOpInterface` by itself doesn't guarantee to preserve the base pointer and `memref.view` is one such example, so limit pattern to a few specific ops.
2025-10-23[mlir][memref] Fold extract_strided_metadata(cast(x)) into ↵Ming Yan
extract_strided_metadata(x) (#164585)
2025-08-21[mlir] add getViewDest method to viewLikeOpInterface (#154524)donald chen
The viewLikeOpInterface abstracts the behavior of an operation view one buffer as another. However, the current interface only includes a "getViewSource" method and lacks a "getViewDest" method. Previously, it was generally assumed that viewLikeOpInterface operations would have only one return value, which was the view dest. This assumption was broken by memref.extract_strided_metadata, and more operations may break these silent conventions in the future. Calling "viewLikeInterface->getResult(0)" may lead to a core dump at runtime. Therefore, we need 'getViewDest' method to standardize our behavior. This patch adds the getViewDest function to viewLikeOpInterface and modifies the usage points of viewLikeOpInterface to standardize its use.
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-07[mlir] Add `isStatic`* size check for `ShapedType`s. NFCI. (#147085)Jakub Kuderski
The motivation is to avoid having to negate `isDynamic*` checks, avoid double negations, and allow for `ShapedType::isStaticDim` to be used in ADT functions without having to wrap it in a lambda performing the negation. Also add the new functions to C and Python bindings.
2025-05-18[mlir][MemRef] Changed AssumeAlignment into a Pure ViewLikeOp (#139521)Shay Kleiman
Made AssumeAlignment a ViewLikeOp that returns a new SSA memref equal to its memref argument and made it have Pure trait. This gives it a defined memory effect that matches what it does in practice and makes it behave nicely with optimizations which won't get rid of it unless its result isn't being used.
2025-05-05[mlir] Remove unused local variables (NFC) (#138481)Kazu Hirata
2025-04-23[MLIR][NFC] Retire let constructor for MemRef (#134788)lorenzo chelini
let constructor is legacy (do not use in tree!) since the tableGen backend emits most of the glue logic to build a pass. Note: The following constructor has been retired: ```cpp std::unique_ptr<Pass> createExpandReallocPass(bool emitDeallocs = true); ``` To update your codebase, replace it with the new options-based API: ```cpp memref::ExpandReallocPassOptions expandAllocPassOptions{ /*emitDeallocs=*/false}; pm.addPass(memref::createExpandReallocPass(expandAllocPassOptions)); ```
2025-01-21[mlir][IR][NFC] Move free-standing functions to `MemRefType` (#123465)Matthias Springer
Turn free-standing `MemRefType`-related helper functions in `BuiltinTypes.h` into member functions.
2024-12-20[mlir] Enable decoupling two kinds of greedy behavior. (#104649)Jacques Pienaar
The greedy rewriter is used in many different flows and it has a lot of convenience (work list management, debugging actions, tracing, etc). But it combines two kinds of greedy behavior 1) how ops are matched, 2) folding wherever it can. These are independent forms of greedy and leads to inefficiency. E.g., cases where one need to create different phases in lowering and is required to applying patterns in specific order split across different passes. Using the driver one ends up needlessly retrying folding/having multiple rounds of folding attempts, where one final run would have sufficed. Of course folks can locally avoid this behavior by just building their own, but this is also a common requested feature that folks keep on working around locally in suboptimal ways. For downstream users, there should be no behavioral change. Updating from the deprecated should just be a find and replace (e.g., `find ./ -type f -exec sed -i 's|applyPatternsAndFoldGreedily|applyPatternsGreedily|g' {} \;` variety) as the API arguments hasn't changed between the two.
2024-12-17[MemRef] Migrate away from PointerUnion::{is,get} (NFC) (#120202)Kazu Hirata
Note that PointerUnion::{is,get} have been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> I'm not touching PointerUnion::dyn_cast for now because it's a bit complicated; we could blindly migrate it to dyn_cast_if_present, but we should probably use dyn_cast when the operand is known to be non-null.
2024-10-26[mlir] [memref] add more checks to the memref.reinterpret_cast (#112669)donald chen
Operation memref.reinterpret_cast was accept input like: %out = memref.reinterpret_cast %in to offset: [%offset], sizes: [10], strides: [1] : memref<?xf32> to memref<10xf32> A problem arises: while lowering, the true offset of %out is %offset, but its data type indicates an offset of 0. Permitting this inconsistency can result in incorrect outcomes, as certain pass might erroneously extract the offset from the data type of %out. This patch fixes this by enforcing that the return value's data type aligns with the input parameter.
2024-08-14[mlir][MemRef] Add more ops to narrow type support, strided metadata ↵Krzysztof Drewniak
expansion (#102228) - Add support fef memory_space_cast to strided metadata expansion and narrow type emulation - Add support for expand_shape to narrow type emulation (like collapse_shape, it's a noop after linearization) and to expand-strided-metadata (mirroring the collapse_shape pattern) - Add support for memref.dealloc to narrow type emulation (it is a trivial rewrite) and for memref.copy (which is unsupported when it is used for a layout change but a trivial rewrite otherwise)
2024-04-26[mlir][MemRef] Add ExtractStridedMetadataOpCollapseShapeFolder (#89954)Diego Caballero
This PR adds a new pattern to the set of patterns used to resolve the offset, sizes and stride of a memref. Similar to `ExtractStridedMetadataOpSubviewFolder`, the new pattern resolves strided_metadata(collapse_shape) directly, without introduce a reshape_cast op.
2024-02-02[mlir][memref] `memref.subview`: Verify result strides with rank reductions ↵Matthias Springer
(#80158) This is a follow-up on #79865. Result strides are now also verified if the `memref.subview` op has rank reductions.
2024-01-31[mlir][memref] `memref.subview`: Verify result stridesMatthias Springer
The `memref.subview` verifier currently checks result shape, element type, memory space and offset of the result type. However, the strides of the result type are currently not verified. This commit adds verification of result strides for non-rank reducing ops and fixes invalid IR in test cases. Verification of result strides for ops with rank reductions is more complex (and there could be multiple possible result types). That is left for a separate commit. Also refactor the implementation a bit: * If `computeMemRefRankReductionMask` could not compute the dropped dimensions, there must be something wrong with the op. Return `FailureOr` instead of `std::optional`. * `isRankReducedMemRefType` did much more than just checking whether the op has rank reductions or not. Inline the implementation into the verifier and add better comments. * `produceSubViewErrorMsg` does not have to be templatized. * Fix comment and add additional assert to `ExpandStridedMetadata.cpp`, to make sure that the memref.subview verifier is in sync with the memref.subview -> memref.reinterpret_cast lowering. Note: This change is identical to #79865, but with a fixed comment and an additional assert in `ExpandStridedMetadata.cpp`. (I reverted #79865 in #80116, but the implementation was actually correct, just the comment in `ExpandStridedMetadata.cpp` was confusing.)
2024-01-17[mlir][IR] Rename "update root" to "modify op" in rewriter API (#78260)Matthias Springer
This commit renames 4 pattern rewriter API functions: * `updateRootInPlace` -> `modifyOpInPlace` * `startRootUpdate` -> `startOpModification` * `finalizeRootUpdate` -> `finalizeOpModification` * `cancelRootUpdate` -> `cancelOpModification` The term "root" is a misnomer. The root is the op that a rewrite pattern matches against (https://mlir.llvm.org/docs/PatternRewriter/#root-operation-name-optional). A rewriter must be notified of all in-place op modifications, not just in-place modifications of the root (https://mlir.llvm.org/docs/PatternRewriter/#pattern-rewriter). The old function names were confusing and have contributed to various broken rewrite patterns. Note: The new function names use the term "modify" instead of "update" for consistency with the `RewriterBase::Listener` terminology (`notifyOperationModified`).
2023-10-05[mlir][MemRef] Add a pattern to simplify `extract_strided_metadata(ca… ↵qcolombet
(#68291) …st)` `expand-strided-metadata` was missing a pattern to get rid of `memref.cast`. The pattern is straight foward: Produce a new `extract_strided_metadata` with the source of the cast and fold the static information (sizes, strides, offset) along the way.
2023-08-17[mlir] Revamp implementation of sub-byte load/store emulation.Mahesh Ravishankar
When handling sub-byte emulation, the sizes of the converted `memref`s also need to be updated (this was not done in the current implementation). This adds the additional complexity of having to linearize the `memref`s as well. Consider a `memref<3x3xi4>` where the `i4` elements are packed. This has a overall size of 5 bytes (rounded up to number of bytes). This can only be represented by a `memref<5xi8>`. A `memref<3x2xi8>` would imply an implicit padding of 4 bits at the end of each row. So incorporate linearization into the sub-byte load-store emulation. This patch also updates some of the utility functions to make better use of statically available information using `OpFoldResult` and `makeComposedFoldedAffineApplyOps`. Reviewed By: hanchung, yzhang93 Differential Revision: https://reviews.llvm.org/D158125
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-01Introduce MLIR Op PropertiesMehdi Amini
This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-05-01Revert "Introduce MLIR Op Properties"Mehdi Amini
This reverts commit d572cd1b067f1177a981a4711bf2e501eaa8117b. Some bots are broken and investigation is needed before relanding.
2023-05-01Introduce MLIR Op PropertiesMehdi Amini
This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Differential Revision: https://reviews.llvm.org/D141742
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-04-03[mlir][MemRef] Add pattern to resolve strided metadata of ↵Mahesh Ravishankar
`memref.get_global` operation. This changes adds patterns to resolve the base pointer, offset, sizes and strides of the result of a `memref.get_global` operation. Since the operation can only result in static shaped memrefs, current resolution kicks in only for non-zero offsets, and identity strides. Also - Add a separate `populateResolveExtractStridedMetadata` method that adds just the pattern to resolve `<memref op>` -> `memref.extract_strided_metadata` operations. - Refactor the `SubviewFolder` pattern to allow resolving `memref.subview` -> `memref.extract_strided_metadata`. This allows using these patterns for cases where there are already existing `memref.extract_strided_metadata` operations. Reviewed By: qcolombet Differential Revision: https://reviews.llvm.org/D147393
2023-03-28[mlir][MemRef] Move transform related functions in Transforms.hQuentin Colombet
NFC
2023-03-14[mlir][DialectUtils] Cleanup IndexingUtils and provide more affine variants ↵Nicolas Vasilache
while reusing implementations Differential Revision: https://reviews.llvm.org/D145784
2023-01-27[mlir] GreedyPatternRewriteDriver: Entry point takes single regionMatthias Springer
The rewrite driver is typically applied to a single region or all regions of the same op. There is no longer an overload to apply the rewrite driver to a list of regions. This simplifies the rewrite driver implementation because the scope is now a single region as opposed to a list of regions. Note: This change is not NFC because `config.maxIterations` and `config.maxNumRewrites` is now counted for each region separately. Furthermore, worklist filtering (`scope`) is now applied to each region separately. Differential Revision: https://reviews.llvm.org/D142611
2023-01-14[mlir] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to remove #include "llvm/ADT/Optional.h". This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-13[mlir] Add #include <optional> (NFC)Kazu Hirata
This patch adds #include <optional> to those files containing llvm::Optional<...> or Optional<...>. I'll post a separate patch to actually replace llvm::Optional with std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-08[mlir][ExpandStridedMetadata] Handle collapse_shape of dim of size 1 gracefullyQuentin Colombet
Collapsing dimensions of size 1 with random strides (a.k.a. non-contiguous w.r.t. collapsed dimensions) is a grey area that we'd like to clean-up. (See https://reviews.llvm.org/D136483#3909856) That said, the implementation in `memref-to-llvm` currently skips dimensions of size 1 when computing the stride of a group. While longer term we may want to clean that up, for now matches this behavior, at least in the static case. For the dynamic case, for this patch we stick to `min(group strides)`. However, if we want to handle the dynamic cases correctly while allowing non-truly-contiguous dynamic size of 1, we would need to `if-then-else` every dynamic size. In other words `min(stride_i, for all i in group and dim_i != 1)`. I didn't implement that in this patch at the moment since `memref-to-llvm` is technically broken in the general case for this. (It currently would only produce something sensible for row major tensors.) Differential Revision: https://reviews.llvm.org/D139329
2022-12-07[mlir][NFC] Add a new getStridesAndOffset functionQuentin Colombet
The new function is a wrapper around the regular `getStridesAndOffset` that offers a more compact way (as in writing less code) of getting the relevant information. This method is intended to be used only when it is known that the LogicalResult of the regular `getStridesAndOffset` must be "succeeded". This warpper will assert on that. Differential Revision: https://reviews.llvm.org/D139529
2022-11-21[mlir][MemRef] NFC rename simplify-extract-strided-metadataQuentin Colombet
This pass has outgrown its original goal and is now going to be used to expand certain memref operations before lowering. Reflect that in the name. The pass is now called expand-strided-metadata. NFC Differential Revision: https://reviews.llvm.org/D138448