summaryrefslogtreecommitdiff
path: root/mlir/lib/Transforms/Utils/LoopInvariantCodeMotionUtils.cpp
AgeCommit message (Collapse)Author
2025-10-15[mlir] Use isPure and skipRegions to print region op (NFC) (#163422)lonely eagle
2025-08-27[MLIR] Apply clang-tidy fixes for llvm-qualified-auto in ↵Mehdi Amini
LoopInvariantCodeMotionUtils.cpp (NFC)
2025-08-20[MLIR] Migrate LICM utils to the LDBG() macro style logging (NFC) (#154615)Mehdi Amini
2025-03-19[mlir][LICM] Restrict LICM to pure tensor semantics (#129673)Longsheng Mou
This PR fixes a bug where LICM incorrectly allowed buffer semantics, which could lead to a crash. Fixes #129416.
2025-02-11Revert "[mlir] Enable LICM for ops with only read side effects in scf.for" ↵Hongtao Yu
(#126840) Reverts llvm/llvm-project#120302
2025-02-11[mlir] Enable LICM for ops with only read side effects in scf.for (#120302)Arda Unal
Enable ops with only read side effects in scf.for to be hoisted with a scf.if guard that checks against the trip count This patch takes a step towards a less conservative LICM in MLIR as discussed in the following discourse thread: [Speculative LICM?](https://discourse.llvm.org/t/speculative-licm/80977) This patch in particular does the following: 1. Relaxes the original constraint for hoisting that only hoists ops without any side effects. This patch also allows the ops with only read side effects to be hoisted into an scf.if guard only if every op in the loop or its nested regions is side-effect free or has only read side effects. This scf.if guard wraps the original scf.for and checks for **trip_count > 0**. 2. To support this, two new interface methods are added to **LoopLikeInterface**: _wrapInTripCountCheck_ and _unwrapTripCountCheck_. Implementation starts with wrapping the scf.for loop into scf.if guard using _wrapInTripCountCheck_ and if there is no op hoisted into the this guard after we are done processing the worklist, it unwraps the guard by calling _unwrapTripCountCheck_.
2024-01-25[mlir][TilingInterface] Use `LoopLikeOpInterface` in tiling using SCF to ↵MaheshRavishankar
unify tiling with `scf.for` and `scf.forall`. (#77874) Using `LoopLikeOpInterface` as the basis for the implementation unifies all the tiling logic for both `scf.for` and `scf.forall`. The only difference is the actual loop generation. This is a follow up to https://github.com/llvm/llvm-project/pull/72178 Instead of many entry points for each loop type, the loop type is now passed as part of the options passed to the tiling method. This is a breaking change with the following changes 1) The `scf::tileUsingSCFForOp` is renamed to `scf::tileUsingSCF` 2) The `scf::tileUsingSCFForallOp` is deprecated. The same functionality is obtained by using `scf::tileUsingSCF` and setting the loop type in `scf::SCFTilingOptions` passed into this method to `scf::SCFTilingOptions::LoopType::ForallOp` (using the `setLoopType` method). 3) The `scf::tileConsumerAndFusedProducerGreedilyUsingSCFForOp` is renamed to `scf::tileConsumerAndFuseProducerUsingSCF`. The use of the `controlFn` in `scf::SCFTileAndFuseOptions` allows implementing any strategy with the default callback implemeting the greedy fusion. 4) The `scf::SCFTilingResult` and `scf::SCFTileAndFuseResult` now use `SmallVector<LoopLikeOpInterface>`. 5) To make `scf::ForallOp` implement the parts of `LoopLikeOpInterface` needed, the `getOutputBlockArguments()` method is replaced with `getRegionIterArgs()` These changes now bring the tiling and fusion capabilities using `scf.forall` on par with what was already supported by `scf.for`
2024-01-25[mlir][IR] Add rewriter API for moving operations (#78988)Matthias Springer
The pattern rewriter documentation states that "*all* IR mutations [...] are required to be performed via the `PatternRewriter`." This commit adds two functions that were missing from the rewriter API: `moveOpBefore` and `moveOpAfter`. After an operation was moved, the `notifyOperationInserted` callback is triggered. This allows listeners such as the greedy pattern rewrite driver to react to IR changes. This commit narrows the discrepancy between the kind of IR modification that can be performed and the kind of IR modifications that can be listened to.
2023-11-05[mlir][transform] LISH: Add transform op (#70630)Matthias Springer
Add a transform op for loop-invariant subset hoisting. Delete the old transform op from the Linalg dialect.
2023-11-01[mlir][Transforms] LISH: Improve bypass analysis for loop-like ops (#70623)Matthias Springer
Improve the bypass analysis for loop-like ops. Until now, loop-like ops were treated like any other non-subset ops: they prevent hoisting of any sort because the analysis does not know which parts of a tensor init operand are accessed by the loop-like op. With this change, the analysis can look into loop-like ops and analyze which subset they are operating on.
2023-11-01[mlir][Transforms] Add loop-invariant subset hoisting (LISH) transformation ↵Matthias Springer
(#70619) Add a loop-invariant subset hoisting pass to `mlir/Interfaces`. This pass hoist loop-invariant tensor subsets (subset extraction and subset insertion ops) from loop-like ops. Extraction ops are moved before the loop. Insertion ops are moved after the loop. The loop body operates on newly added region iter_args (one per extraction-insertion pair). This new pass will be improved in subsequent commits (to support more cases/ops) and will eventually replace `Linalg/Transforms/SubsetHoisting.cpp`. In contrast to the existing Linalg subset hoisting, the new pass is op interface-based (`SubsetOpInterface` and `LoopLikeOpInterface`).
2023-09-19[mlir][Interfaces] `LoopLikeOpInterface`: Support ops with multiple regions ↵Matthias Springer
(#66754) This commit implements `LoopLikeOpInterface` on `scf.while`. This enables LICM (and potentially other transforms) on `scf.while`. `LoopLikeOpInterface::getLoopBody()` is renamed to `getLoopRegions` and can now return multiple regions. Also fix a bug in the default implementation of `LoopLikeOpInterface::isDefinedOutsideOfLoop()`, which returned "false" for some values that are defined outside of the loop (in a nested op, in such a way that the value does not dominate the loop). This interface is currently only used for LICM and there is no way to trigger this bug, so no test is added.
2022-11-15[mlir] Remove `Transforms/SideEffectUtils.h` and move the methods into ↵Mahesh Ravishankar
`Interface/SideEffectInterfaces.h`. The methods in `SideEffectUtils.h` (and their implementations in `SideEffectUtils.cpp`) seem to have similar intent to methods already existing in `SideEffectInterfaces.h`. Move the decleration (and implementation) from `SideEffectUtils.h` (and `SideEffectUtils.cpp`) into `SideEffectInterfaces.h` (and `SideEffectInterface.cpp`). Also drop the `SideEffectInterface::hasNoEffect` method in favor of `mlir::isMemoryEffectFree` which actually recurses into the operation instead of just relying on the `hasRecursiveMemoryEffectTrait` exclusively. Differential Revision: https://reviews.llvm.org/D137857
2022-10-12Introduce a ConditionallySpeculatable op interfaceSanjoy Das
This patch takes the first step towards a more principled modeling of undefined behavior in MLIR as discussed in the following discourse threads: 1. https://discourse.llvm.org/t/semantics-modeling-undefined-behavior-and-side-effects/4812 2. https://discourse.llvm.org/t/rfc-mark-tensor-dim-and-memref-dim-as-side-effecting/65729 This patch in particular does the following: 1. Introduces a ConditionallySpeculatable OpInterface that dynamically determines whether an Operation can be speculated. 2. Re-defines `NoSideEffect` to allow undefined behavior, making it necessary but not sufficient for speculation. Also renames it to `NoMemoryEffect`. 3. Makes LICM respect the above semantics. 4. Changes all ops tagged with `NoSideEffect` today to additionally implement ConditionallySpeculatable and mark themselves as always speculatable. This combined trait is named `Pure`. This makes this change NFC. For out of tree dialects: 1. Replace `NoSideEffect` with `Pure` if the operation does not have any memory effects, undefined behavior or infinite loops. 2. Replace `NoSideEffect` with `NoSideEffect` otherwise. The next steps in this process are (I'm proposing to do these in upcoming patches): 1. Update operations like `tensor.dim`, `memref.dim`, `scf.for`, `affine.for` to implement a correct hook for `ConditionallySpeculatable`. I'm also happy to update ops in other dialects if the respective dialect owners would like to and can give me some pointers. 2. Update other passes that speculate operations to consult `ConditionallySpeculatable` in addition to `NoMemoryEffect`. I could not find any other than LICM on a quick skim, but I could have missed some. 3. Add some documentation / FAQs detailing the differences between side effects, undefined behavior, speculatabilty. Reviewed By: rriddle, mehdi_amini Differential Revision: https://reviews.llvm.org/D135505
2022-05-17[mlir][licm] Fix debug output with newlinesCullen Rhodes
2022-04-16[mlir] Refactor LICM into a utilityMogball
LICM is refactored into a utility that is application on any region. The implementation is moved to Transform/Utils.
2022-04-15Revert "[mlir] Refactor LICM into a utility"Stella Stamenova
This reverts commit 3131f808243abe3746280e016ab9459c14d9e53b. This commit broke the Windows mlir bot: https://lab.llvm.org/buildbot/#/builders/13/builds/19745
2022-04-15[mlir] Refactor LICM into a utilityMogball
LICM is refactored into a utility that is application on any region. The implementation is moved to Transform/Utils.