Commit Graph

1594 Commits

Author SHA1 Message Date
Matthias Springer
a4e4527c4b [mlir][Transforms] Fix replaceUsesOfBlockArgument API (#144706)
Before this PR, users had to pass the "old" block argument when
replacing the uses of a block argument in a newly converted block. Users
can now pass the actual block argument that should be replaced.

Note for LLVM integration: Make sure to pass the current block argument
instead of the old one.
2025-06-19 15:39:06 +02:00
Matthias Springer
66580f77b8 [mlir][Transforms][NFC] Dialect Conversion: Keep unresolvedMaterializations up to date (#144254)
`unresolvedMaterializations` is a mapping from
`UnrealizedConversionCastOp` to `UnresolvedMaterializationRewrite`. This
mapping is needed to find the correct type converter for an unresolved
materialization.

With this commit, `unresolvedMaterializations` is updated immediately
when an op is being erased. This also cleans up the code base a bit:
`SingleEraseRewriter` is now used only during the "cleanup" phase and no
longer needed as a field of `ConversionRewriterImpl`.

This commit is in preparation of the One-Shot Dialect Conversion
refactoring: `allowPatternRollback = false` will in the future trigger
immediate materialization of all IR changes.
2025-06-18 14:42:09 +02:00
Kazu Hirata
43c35e858c [mlir] Simplify calls to *Map::{insert,try_emplace} (NFC) (#143729)
This patch simplifies code by removing the values from
insert/try_emplace.  Note that default values inserted by try_emplace
are immediately overrideen in all these cases.
2025-06-11 12:50:35 -07:00
Kazu Hirata
b3b8a097fe [mlir] Use *Map::try_emplace (NFC) (#143341)
- try_emplace(Key) is shorter than insert({Key, nullptr}).
- try_emplace performs value initialization without value parameters.
- We overwrite values on successful insertion anyway.
2025-06-09 07:18:26 -07:00
Alex Denisov
da4958ae2b [MLIR] Add a missing newline to debug output. NFC (#141531)
Before:

```
** Erase   : 'scf.yield'(0x6000037b1630)
** Insert Block into detached Region (nullptr parent op)'        ** Insert Block into detached Region (nullptr parent op)'        ** Insert  : 'scf.if'(0x6000025b8140)
** Erase   : 'scf.if'(0x600003ab0780)
```

After:

```
** Erase   : 'scf.yield'(0x600003128b90)
** Insert Block into detached Region (nullptr parent op)'
** Insert Block into detached Region (nullptr parent op)'
** Insert  : 'scf.if'(0x6000023206e0)
```
2025-05-26 15:42:54 -07:00
Kazu Hirata
6464238dc0 [mlir] Use llvm::stable_sort (NFC) (#141186) 2025-05-22 22:36:32 -07:00
Kazu Hirata
4bcea4e9ed [mlir] Fix unused-variable warnings
This patch fixes warnings of the form:

  mlir/lib/Conversion/VectorToGPU/VectorToGPU.cpp:320:19: error:
  unused variable 'result' [-Werror,-Wunused-variable]
2025-05-22 12:37:28 -07:00
William Moses
6a8dde04a0 [MLIR] Change getBackwardSlice to return a logicalresult rather than crash (#140961)
The current implementation of getBackwardSlice will crash if an
operation in the dependency chain is defined by an operation with
multiple regions or blocks. Crashing is bad (and forbids many analyses
from using getBackwardSlice, as well as causing existing users of
getBackwardSlice to fail for IR with this property).

This PR instead causes the analysis to return a failure, rather than
crash in the cases it cannot compute the full slice

---------

Co-authored-by: Oleksandr "Alex" Zinenko <git@ozinenko.com>
2025-05-22 14:13:32 -05:00
Kazu Hirata
c2835e70fd [mlir] Remove unused local variables (NFC) (#140423) 2025-05-17 19:43:15 -07:00
Matthias Springer
751e6c08b2 [mlir][Transforms] Check for correct type converter rule implementation (#140347)
If a type conversion rule fails to apply, it should not append any types
to the result. This commit just adds an assertion to detect such cases
of incorrect API usage.
2025-05-18 09:05:02 +09:00
Kazu Hirata
395f8695da [mlir] Use llvm::replace (NFC) (#140344) 2025-05-17 09:09:26 -07:00
Vadim Curcă
cdabce0c1b [MLIR] Remove extra 'any' from CompositePass inner pipeline string (#139877)
When a `CompositePass` is created programmatically, it incorrectly
prepends an extra `any` to the inner pipeline string. For example:
```c++
passManager.nestAny().addPass(createCompositeFixedPointPass(
  "Pass1AndPass2",
  [](OpPassManager &nestedPassManger) {
    nestedPassManger.addPass(createPass1());
    nestedPassManger.addPass(createPass2());
  },
```
This would result in the following pipeline string:
```
any(composite-fixed-point-pass{max-iterations=3 name=Pass1AndPass2
pipeline=any(pass1,pass2)})
```

This commit fixes this issue, resulting in the pipeline string:
```
any(composite-fixed-point-pass{max-iterations=3 name=Pass1AndPass2
pipeline=pass1,pass2})
```
2025-05-14 15:00:29 +02:00
Rahul Joshi
b17f3c63de [NFC][MLIR] Add {} for else when if body has {} (#139422) 2025-05-12 10:29:03 -07:00
Matthias Springer
fc8484f0e3 [mlir][Transforms][NFC] Rename MaterializationCallbackFn (#138814)
There are two kind of materialization callbacks: one for target
materializations and one for source materializations. The callback type
for target materializations is `TargetMaterializationCallbackFn`. This
commit renames the one for source materializations from
`MaterializationCallbackFn` to `SourceMaterializationCallbackFn`, for
consistency.

There used to be a single callback type for both kind of
materializations, but the materialization function signatures have
changed over time.

Also clean up a few places in the documentation that still referred to
argument materializations.
2025-05-08 08:22:38 +02:00
Kazu Hirata
921d162460 [mlir] Remove unused local variables (NFC) (#138642) 2025-05-06 07:55:50 -07:00
Oleksandr "Alex" Zinenko
7318074168 [mlir] allow function type cloning to fail (#137130)
`FunctionOpInterface` assumed the fact that the function type (attribute
of the operation) can be cloned with arbirary lists of function
arguments and results to support argument and result list mutation. This
is not always correct, in particular, LLVM dialect functions require
exactly one result making it impossible to erase the result.

Allow function type cloning to fail and propagate this failure through
various APIs that use it. The common assumption is that existing IR has
not been modified.

Fixes #131142.

Reland a8c7ecdcbc3e89b493b495c6831cc93671c3b844 / #136300.
2025-04-30 09:26:42 +02:00
Kazu Hirata
d1e85a0ea0 [mlir] Use range constructors of *Set (NFC) (#137563) 2025-04-27 17:52:41 -07:00
bubblepipe
3ce2d1e6a1 [mlir] Fix typo in CSE transform (#137341)
"Replace all uses, but do not _remote_ the operation yet" should be
"Replace all uses, but do not _remove_ the operation yet".
2025-04-25 08:53:29 -07:00
Oleksandr "Alex" Zinenko
0c61b24337 [mlir] add a fluent API to GreedyRewriterConfig (#137122)
This is similar to other configuration objects used across MLIR.

Rename some fields to better reflect that they are no longer booleans.

Reland 04d261101b4f229189463136a794e3e362a793af / #132253.
2025-04-24 09:51:42 +02:00
Kazu Hirata
f5564895ea [mlir] Fix a warning
This patch fixes:

  mlir/lib/Transforms/Utils/DialectConversion.cpp:2104:9: error:
  unused variable 'rewriterImpl' [-Werror,-Wunused-variable]
2025-04-22 12:47:51 -07:00
Matthias Springer
8bc0d4d1cc [mlir][Transforms] Dialect conversion: Add flag to disable rollback (#136490)
This commit adds a new flag to `ConversionConfig` to disallow the
rollback of IR modification. This commit is in preparation of the
One-Shot Dialect Conversion refactoring, which will remove the ability
to roll back IR modifications from the conversion driver.

RFC:
https://discourse.llvm.org/t/rfc-a-new-one-shot-dialect-conversion-driver/79083/46

By default, this flag is set to "true". I.e., the rollback of IR
modifications is allowed. When set to "false", the conversion driver
will report a fatal LLVM error when an IR rollback is requested. The
name of the rolled back pattern is included in the error message.
Moreover, the original IR is no longer restored after a failed
conversion.

Example:
```
within split at llvm-project/mlir/test/Conversion/ArithToSPIRV/fast-math.mlir:1 offset :11:8: error: pattern '(anonymous namespace)::CmpFOpNanKernelPattern' produced IR that could not be legalized
  %0 = arith.cmpf ord, %arg0, %arg1 fastmath<fast> : f32
       ^
within split at llvm-project/mlir/test/Conversion/ArithToSPIRV/fast-math.mlir:1 offset :11:8: note: see current operation: %1 = "arith.cmpf"(%arg0, %arg1) <{fastmath = #arith.fastmath<fast>, predicate = 7 : i64}> : (f32, f32) -> i1
pattern '(anonymous namespace)::CmpFOpNanKernelPattern' rollback of IR modifications requested
UNREACHABLE executed at llvm-project/mlir/lib/Transforms/Utils/DialectConversion.cpp:1231!
```

The majority of patterns in MLIR have already been updated such that
they do not trigger any rollbacks, but a few SPIRV patterns remain. More
information in the RFC.
2025-04-22 09:45:11 +02:00
Matthias Springer
2d3bbb6aaf [mlir][Transforms] Dialect conversion: Erase materialized constants instead of rollback (#136489)
When illegal (and not legalizable) constant operations are materialized
during a dialect conversion as part of op folding, these operations must
be deleted again. This used to be implemented via the rollback
mechanism. This commit switches the implementation to regular rewriter
API usage: simply delete the materialized constants with `eraseOp`.

This commit is in preparation of the One-Shot Dialect Conversion
refactoring, which will disallow IR rollbacks.

This commit also adds a new optional parameter to `OpBuilder::tryFold`
to get hold of the materialized constant ops.
2025-04-22 09:12:00 +02:00
Kazu Hirata
5e834b9ec7 [mlir] Call hash_combine_range with ranges (NFC) (#136512) 2025-04-20 16:36:35 -07:00
Kazu Hirata
7da385d797 Revert "[mlir] allow function type cloning to fail (#136300)"
This reverts commit 20a104a7d6.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/157/builds/25688

I've reproduced the build failure.
2025-04-18 09:52:28 -07:00
Kazu Hirata
4cb9a3700c Revert "[mlir] add a fluent API to GreedyRewriterConfig (#132253)"
This reverts commit 63b8f1c948.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/172/builds/12083/steps/5/logs/stdio

I've reproduced the error with a release build (-DCMAKE_BUILD_TYPE=Release).
2025-04-18 09:40:28 -07:00
Oleksandr "Alex" Zinenko
20a104a7d6 [mlir] allow function type cloning to fail (#136300)
`FunctionOpInterface` assumed the fact that the function type (attribute
of the operation) can be cloned with arbirary lists of function
arguments and results to support argument and result list mutation. This
is not always correct, in particular, LLVM dialect functions require
exactly one result making it impossible to erase the result.

Allow function type cloning to fail and propagate this failure through
various APIs that use it. The common assumption is that existing IR has
not been modified.

Fixes #131142.
2025-04-18 16:05:54 +02:00
Oleksandr "Alex" Zinenko
63b8f1c948 [mlir] add a fluent API to GreedyRewriterConfig (#132253)
This is similar to other configuration objects used across MLIR.
2025-04-18 15:19:57 +02:00
Matthias Springer
23e3cbb2e8 [mlir][Transforms] Delete 1:N dialect conversion driver (#121389)
The 1:N dialect conversion driver has been deprecated. Use the regular
dialect conversion driver instead. This commit deletes the 1:N dialect
conversion driver.

Note for LLVM integration: If you are already using the regular dialect conversion, but still have argument materializations in your code base, simply delete all `addArgumentMaterialization` calls.

For details, see
https://discourse.llvm.org/t/rfc-merging-1-1-and-1-n-dialect-conversions/82513.
2025-04-17 14:37:20 +02:00
Jakub Kuderski
0078cf79ad [mlir] Remove deprecated cast member functions (#135556)
These have been deprecated for over two years now in favor of free
functions.

See the relevant discourse thread:

https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443
and the deprecation notice: https://mlir.llvm.org/deprecation/.
2025-04-14 09:08:34 -04:00
Benjamin Kramer
3e08dcd767 [mlir][inliner] Move callback types from InlinerConfig -> InlinerInterface. NFC.
The proper layering here is that Inliner depends on InlinerUtils, and
not the other way round. Maybe it's time to give InliningUtils a less
terrible file name.
2025-04-06 13:02:42 +02:00
junfengd-nv
aeec94500a [mlir][inliner] Add doClone and canHandleMultipleBlocks callbacks to Inliner Config (#131226)
Current inliner disables inlining when the caller is in a region with
single block trait, while the callee function contains multiple blocks.
the SingleBlock trait is used in operations such as do/while loop, for
example fir.do_loop, fir.iterate_while and fir.if. Typically, calls within
loops are good candidates for inlining. However, functions with multiple
blocks are also common. for example, any function with "if () then
return" will result in multiple blocks in MLIR.

This change gives the flexibility of a customized inliner to handle such
cases.
doClone: clones instructions and other information from the callee
function into the caller function. .
canHandleMultipleBlocks: checks if functions with multiple blocks can be
inlined into a region with the SingleBlock trait.

The default behavior of the inliner remains unchanged.

---------

Co-authored-by: jeanPerier <jean.perier.polytechnique@gmail.com>
Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-04-05 22:56:55 +02:00
Matthias Springer
68ce637872 [mlir][Transforms][NFC] Dialect Conversion: Replace after legalizing constants (#134384)
When folding an op during a conversion, first try to legalize all
generated constants, then replace the original operation. This is
slightly more efficient because fewer rewrites must be rolled back in
case a generated constant could not be legalized.

Note: This is in preparation of the One-Shot Dialect Conversion
refactoring.
2025-04-05 06:20:25 -07:00
Adrian Kuegel
c154d66339 [mlir] Apply ClangTidyBugProne finding (NFC).
argument name 'outputType' in comment does not match parameter name 'outputTypes'
2025-04-04 09:01:56 +00:00
Longsheng Mou
222297b020 [mlir] Use Region::hasOneBlock (NFC) (#133879) 2025-04-02 09:40:22 +08:00
Longsheng Mou
1d9ad99305 [mlir] Use llvm::hasSingleElement (NFC) (#133881) 2025-04-01 18:58:50 +08:00
Han-Chung Wang
66b0b0466b [MLIR][NFC] Fix incomplete boundary comments. (#133516)
I observed that we have the boundary comments in the codebase like:

```
//===----------------------------------------------------------------------===//
// ...
//===----------------------------------------------------------------------===//
```

I also observed that there are incomplete boundary comments. The
revision is generated by a script that completes the boundary comments.

```
//===----------------------------------------------------------------------===//
// ...

...
```

Signed-off-by: hanhanW <hanhan0912@gmail.com>
2025-03-31 09:29:54 -07:00
Matthias Springer
4abff4d7b2 [mlir][Transforms] Improve replaceOpWithMultiple API (#132608)
This commit adds an additional overload to `replaceOpWithMultiple` that
accepts additional container types. This has been brought up by users of
the new `replaceOpWithMultiple` API.

In particular, one missing container type was
`SmallVector<SmallVector<Value>>`. The "default" `ArrayRef<ValueRange>`
container type can lead to use-after-scope errors in cases such as:
```c++
// Compute the replacement value ranges. Some replacements are single
// values, some are value ranges.
SmallVector<ValueRange> repl;
repl.push_back(someValueRange);  // OK
for (...) {
  // push_back(Value) triggers an implicit conversion to ValueRange,
  // which does not own the range.
  repl.push_back(someValue);  // triggers use-after-scope later
}
rewriter.replaceOpWithMultiple(op, repl);
```

In this example, users should use `SmallVector<SmallVector<Value>>
repl;`.
2025-03-28 14:18:54 +01:00
AdityaK
f2849fe05f Fix RemoveDeadValues: Bail out early when there are no terminators (#133316)
Fixes: #131765
2025-03-27 15:04:31 -07:00
Kazu Hirata
1cc07a0865 [mlir] Use *Set::insert_range (NFC) (#133043)
We can use *Set::insert_range to collapse:

  for (auto Elem : Range)
    Set.insert(E);

down to:

  Set.insert_range(Range);

In some cases, we can further fold that into the set declaration.
2025-03-26 07:47:02 -07:00
Vadim Curcă
6b59b33358 [MLIR] Handle call site locations when inlining (#132247)
When inlining a `callee` with a call site debug location, the inlining
infrastructure was trivially combining the `callee` and the `caller`
locations, forming a "tree" of call stacks. Because of this, the remarks
were printing an incomplete inlining stack.

This commit handles this case and appends the `caller` location at the
end of the `callee`'s stack, extending the chain.
2025-03-21 14:06:53 +01:00
Kazu Hirata
3041fa6c7a [mlir] Use *Set::insert_range (NFC) (#132326)
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently
gained C++23-style insert_range.  This patch replaces:

  Dest.insert(Src.begin(), Src.end());

with:

  Dest.insert_range(Src);

This patch does not touch custom begin like succ_begin for now.
2025-03-20 22:24:17 -07:00
Longsheng Mou
efc31ecd27 [mlir][LICM] Restrict LICM to pure tensor semantics (#129673)
This PR fixes a bug where LICM incorrectly allowed buffer semantics,
which could lead to a crash. Fixes #129416.
2025-03-19 14:17:49 +08:00
Matthias Springer
e614e840bc [mlir][memref] Add runtime verification for memref.dim (#130410)
Add runtime verification for `memref.dim`: check that the index is in
bounds.

Also simplify the pass pipeline for all memref runtime verification
checks.
2025-03-18 09:10:49 +01:00
Matthias Springer
6c2f8476e7 [mlir][Transforms] Dialect Conversion: Add 1:N support to remapInput (#131454)
This commit adds 1:N support to `SignatureConversion::remapInputs`. This
API allows users to replace a block argument with multiple replacement
values. (And the block argument is dropped.) The API already supported
"bbarg --> multiple bbargs" mappings, but "bbarg --> multiple SSA
values" was missing.

---------

Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
2025-03-15 18:33:06 +01:00
MaheshRavishankar
665299eb3e [mlir][Transforms] Add a utility method to move value definitions. (#130874)
205c5325b3
added a transform utility that moved all SSA dependences of an operation
before an insertion point. Similar to that, this PR adds a transform
utility function, `moveValueDefinitions` to move the slice of operations
that define all values in a `ValueRange` before the insertion point.
While very similar to `moveOperationDependencies`, this method differs
in a few ways

1. When computing the backward slice since the start of the slice is
value, the slice computed needs to be inclusive.
2. The combined backward slice needs to be sorted topologically before
moving them to avoid SSA use-def violations while moving individual ops.

The PR also adds a new transform op to test this new utility function.

---------

Signed-off-by: MaheshRavishankar <mahesh.ravishankar@gmail.com>
2025-03-12 08:30:43 -07:00
MaheshRavishankar
205c5325b3 [mlir] Add a utility method to move operation dependencies. (#129975)
The added utility method moves all SSA values that an operation depends
upon before an insertion point. This is useful during transformations
where such movements might make transformations (like fusion) more
powerful.

To test the operation add a transform dialect op that calls the move
operation. To be able to capture the `notifyMatchFailure` messages from
the transformation and to report/check these in the test modify the
`ErrorCheckingTrackingListener` to capture the last match failure
notification.

---------

Signed-off-by: MaheshRavishankar <mahesh.ravishankar@gmail.com>
2025-03-10 20:23:08 -07:00
Andrzej Warzyński
02fb976941 [mlir] Improve GreedyPatternRewriteDriver logging (#127314)
Currently, when `GreedyPatternRewriteDriver` fails, the log output
contains nested failure messages:

```bash
   } -> failure : pattern failed to match
} -> failure : pattern failed to match
```

This may seem redundant, but these messages refer to different aspects
of the pattern application logic. This patch clarifies the distinction
by separately logging:

* Success/failure for a specific pattern (e.g., "_this pattern_ failed
  to match on the Op currently being processed").
* Success/failure for an operation as a whole (e.g., "_all patterns_
  failed to match the Op currently being processed").

Before (example with success):
```bash
Processing operation : (...) {

  * Pattern (...) -> ()' {
Trying to match "..."
    ** Match Failure : (...)
  } -> failure : pattern failed to match

  * Pattern (...) -> ()' {
Trying to match "..."
  } -> success : pattern applied successfully
} -> success : pattern matched
```

After (example with success):
```bash
Processing operation : (...) {

  * Pattern (...) -> ()' {
Trying to match "..."
    ** Match Failure : (...)
  } -> failure : pattern failed to match

  * Pattern (...) -> ()' {
Trying to match "..."
  } -> success : pattern applied successfully
} -> success : at least one pattern matched
```

This improves log clarity, making it easier to distinguish pattern-level
failures from operation-level outcomes.
2025-02-15 20:06:32 +00:00
Hongtao Yu
4a63ff4330 Revert "[mlir] Enable LICM for ops with only read side effects in scf.for" (#126840)
Reverts llvm/llvm-project#120302
2025-02-11 20:07:21 -08:00
Arda Unal
36d8e7056e [mlir] Enable LICM for ops with only read side effects in scf.for (#120302)
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_.
2025-02-11 15:48:57 -08:00
Longsheng Mou
be354cf381 [mlir][transforms] Process RegionBranchOp with empty region (#123895)
This PR adds process for RegionBranchOp with empty region, such as
'else' region of `scf.if`. Fixes #123246.
2025-02-11 14:43:15 +08:00