227 Commits

Author SHA1 Message Date
Maksim Levental
2736fbd832
[mlir][NFC] update mlir/lib create APIs (26/n) (#149933)
See https://github.com/llvm/llvm-project/pull/147168 for more info.

---------

Co-authored-by: Tobias Gysi <tobias.gysi@nextsilicon.com>
2025-07-22 08:40:42 -04:00
Matthias Springer
8ee32c7b36
[mlir][Transforms][NFC] Dialect Conversion: Store materialization metadata separately (#148415)
Store metadata about unresolved materializations in a separate data
structure. This is in preparation of the One-Shot Dialect Conversion
refactoring, which no longer maintains a stack of `IRRewrite` objects.
Therefore, metadata about unresolved materializations can no longer be
retrieved from `UnresolvedMaterializationRewrite` objects.

This commit also removes a pointer indirection and may slightly improve
the performance of the existing driver.
2025-07-15 10:14:37 +02:00
Matthias Springer
1db33f1034
[mlir][Transforms] Report all allowPatternRollback violations as fatal errors (#148416)
Report all `allowPatternRollback` API violations as fatal errors. If
violated, the IR is potentially in an invalid/inconsistent state from
which the driver cannot recover.
2025-07-13 17:41:21 +02:00
Matthias Springer
58c0bd196e
[mlir][Transforms] Dialect Conversion: allowPatternRollback to check foldings (#148394)
When an operation is folded to an attribute, the attribute must be
materialized as a constant operation. That operation must then be
legalized. If such a legalization fails, the entire folding is rolled
back. This is not supported in a One-Shot Dialect Conversion. (Support
for rolling back foldings could be added at a later point of time.)

This commit improves the `allowPatternRollback` flag handling, such that
a fatal error is reported when a folder is attempted to be rolled back.
2025-07-13 10:06:07 +02:00
Matthias Springer
67db34863c
[mlir][Transforms][NFC] Dialect Conversion: Earlier isIgnored check (#148360)
When legalizing an operation, the conversion driver skips "ignored" ops.
Ops are ignored if they are inside of a recursively legal operation or
if they were erased.

This commit moves the "is ignored" check a bit earlier: it is now
checked before checking if the op is recursively legal. This is in
preparation of the One-Shot Dialect Conversion refactoring: erased ops
should not be accessed, not even for checking recursive legality.

This commit is NFC: When an op is erased, it is added to the set of
ignored ops and we don't want to process it, regardless of legality.
Nested ops are also added to the set of ignored ops when erasing an
enclosing op.
2025-07-12 16:46:42 +02:00
Matthias Springer
ad20dc0a87
[mlir][Transforms] Add ApplyConversionAction for profiling purposes (#146208)
Add a new `ApplyConversionAction` so that users can profile the time
that is spent in the conversion driver.
2025-07-04 14:58:49 +02:00
Kazu Hirata
b5cd49eff0
[mlir] Remove unused includes (NFC) (#146278)
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-29 12:13:12 -07:00
Matthias Springer
9ccf613b34
[mlir][Transforms][NFC] Store per-pattern IR modifications in separate state (#145319)
This commit adds extra state to `ConversionPatternRewriterImpl` to store
all modified / newly-created operations and moved / newly-created blocks
in separate lists on a per-pattern basis.

This is in preparation of the One-Shot Dialect Conversion refactoring:
the new driver will no longer maintain a list of all IR rewrites, so
information about newly-created operations (which is needed to trigger
recursive legalization) must be retained in a different data structure.

This commit is also expected to improve the performance of the existing
driver. The previous implementation iterated over all new IR
modifications and then filtered them by type. It also required an
additional pointer indirection (through `std::unique_ptr<IRRewrite>`) to
retrieve the operation/block pointer.
2025-06-26 08:54:39 +02:00
Matthias Springer
c5972da34a
[mlir][Transforms] Dialect Conversion: Simplify block-inline handling (#145308)
When a block is getting inlined, the destination block does not have to
be legalized. That's because the signature of the destination block does
not change by inlining.

This commit makes the implementation consistent with this comment:
```
  // If the pattern moved or created any blocks, make sure the types of block
  // arguments get legalized.
```
2025-06-24 08:52:13 +02:00
Matthias Springer
b1b8f67eab
[mlir][Transforms] Add 1:N support to replaceUsesOfBlockArgument (#145171)
This commit adds 1:N support to
`ConversionPatternRewriter::replaceUsesOfBlockArgument`. This was one of
the few remaining dialect conversion APIs that does not support 1:N
conversions yet.

This commit also reuses `replaceUsesOfBlockArgument` in the
implementation of `applySignatureConversion`. This is in preparation of
the One-Shot Dialect Conversion refactoring. The goal is to bring the
`applySignatureConversion` implementation into a state where it works
both with and without rollbacks. To that end, `applySignatureConversion`
should not directly access the `mapping`.
2025-06-23 12:07:00 +02:00
Matthias Springer
b9c979d369
[mlir][Transforms] Dialect conversion: Simplify replaceOp implementation (#145155)
Since #145030, `ConversionPatternRewriter::eraseBlock` no longer calls
`ConversionPatternRewriter::eraseOp`. This now happens in the rewriter
impl (during the cleanup phase). Therefore, a safety check in
`replaceOp` can now be simplified.
2025-06-23 11:06:14 +02:00
Matthias Springer
0921bfd81d
[mlir][Transforms] Dialect conversion: Add missing erasure notifications (#145030)
Add missing listener notifications when erasing nested
blocks/operations.

This commit also moves some of the functionality from
`ConversionPatternRewriter` to `ConversionPatternRewriterImpl`. This is
in preparation of the One-Shot Dialect Conversion refactoring: The
implementations in `ConversionPatternRewriter` should be as simple as
possible, so that a switch between "rollback allowed" and "rollback not
allowed" can be inserted at that level. (In the latter case,
`ConversionPatternRewriterImpl` can be bypassed to some degree, and
`PatternRewriter::eraseBlock` etc. can be used.)

Depends on #145018.
2025-06-21 10:44:54 +02:00
Matthias Springer
32dbaf12be
[mlir][Transforms][NFC] Dialect conversion: Rename internal functions (#145018)
Rename a few internal functions: drop the `notify` prefix, which
incorrectly suggests that the function is a listener callback function.
2025-06-21 09:43:34 +02:00
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
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
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
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
d1e85a0ea0
[mlir] Use range constructors of *Set (NFC) (#137563) 2025-04-27 17:52:41 -07: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
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
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
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
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
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
Matthias Springer
e63d543e66
[mlir][Transforms] Dialect conversion: Fix -debug crash (#125660)
Fix a crash in `ConversionPatternRewriter::replaceUsesOfBlockArgument`
when running with `-debug`. The block that owns the block argument can
be a detached block. In that case, do not attempt to print the name of
the owner op.
2025-02-04 11:31:45 +01:00
Matthias Springer
5f7568a32c
[mlir][Transforms] Fix mapping in findOrBuildReplacementValue (#121644)
Fixes two minor issues in `findOrBuildReplacementValue`:
* Remove a redundant `mapping.map`.
* Map `repl` instead of `value`. We used to overwrite an existing
mapping, which could introduce extra materializations.

Note: We generally do not want to overwrite mappings, but create a chain
of mappings. There are still a few more places, where a mapping is
overwritten. Once those are fixed, I will put an assertion into
`ConversionValueMapping::map`.
2025-01-06 08:55:18 +01:00
Matthias Springer
486f83faa3
[mlir][Transforms][NFC] Simplify buildUnresolvedMaterialization implementation (#121651)
The `buildUnresolvedMaterialization` implementation used to check if a
materialization is necessary. A materialization is not necessary if the
desired types already match the input. However, this situation can never
happen: we look for mapped values with the desired type at the call
sites before requesting a new unresolved materialization.

The previous implementation seemed incorrect because
`buildUnresolvedMaterialization` created a mapping that is never rolled
back. (When in reality that code was never executed, so it is
technically not incorrect.)

Also fix a comment that in `findOrBuildReplacementValue` that was
incorrect.
2025-01-05 17:32:07 +01:00
Matthias Springer
afef716e83
[mlir][Transforms] Fix build after #116524 (part 2) (#121662)
Since #116524, an integration test started to become flaky (failure rate
~15%).

```
bin/mlir-opt mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir --sparsifier="enable-arm-sve=true enable-runtime-library=false vl=2 reassociate-fp-reductions=true enable-index-optimizations=true" | mlir-cpu-runner --march=aarch64 --mattr="+sve" -e main -entry-point-result=void -shared-libs=./lib/libmlir_runner_utils.so,./lib/libmlir_c_runner_utils.so | bin/FileCheck mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir
# executed command: bin/mlir-opt mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir '--sparsifier=enable-arm-sve=true enable-runtime-library=false vl=2 reassociate-fp-reductions=true enable-index-optimizations=true'
# .---command stderr------------
# | mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir:71:10: error: null operand found
# |     %0 = linalg.generic #trait_mul
# |          ^
# | mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_block_matmul.mlir:71:10: note: see current operation: %70 = "arith.mulf"(<<NULL VALUE>>, %69) <{fastmath = #arith.fastmath<none>}> : (<<NULL TYPE>>, vector<[2]xf64>) -> vector<[2]xf64>
# `-----------------------------
# error: command failed with exit status: 1
```

I traced the issue back to the `DenseMap<ValueVector, ValueVector,
ValueVectorMapInfo> mapping;` data structure: previously, some
`mapping.erase(foo)` calls were unsuccessful (returning `false`), even
though the `mapping` contains `foo` as a key.
2025-01-04 21:28:59 +01:00
Matthias Springer
c9d61cde2b
[mlir][Transforms][NFC] Delete unused nTo1TempMaterializations (#121647)
`nTo1TempMaterializations` is no longer used since the conversion value
mapping supports 1:N mappings.
2025-01-04 15:16:35 +01:00
Matthias Springer
95c5c5d4ba
[mlir][Transforms][NFC] Use DominanceInfo to compute materialization insertion point (#120746)
In the dialect conversion driver, use `DominanceInfo` to compute a
suitable insertion point for N:1 source materializations.
2025-01-04 09:23:15 +01:00
Matthias Springer
faa30be101
[mlir][Transforms] Fix build after #116524 (#121578)
Fix build errors after #116524.

```
error: call of overloaded ‘TypeRange(ValueVector&)’ is ambiguous
```
2025-01-03 16:35:02 +01:00
Matthias Springer
3ace685105
[mlir][Transforms] Support 1:N mappings in ConversionValueMapping (#116524)
This commit updates the internal `ConversionValueMapping` data structure
in the dialect conversion driver to support 1:N replacements. This is
the last major commit for adding 1:N support to the dialect conversion
driver.

Since #116470, the infrastructure already supports 1:N replacements. But
the `ConversionValueMapping` still stored 1:1 value mappings. To that
end, the driver inserted temporary argument materializations (converting
N SSA values into 1 value). This is no longer the case. Argument
materializations are now entirely gone. (They will be deleted from the
type converter after some time, when we delete the old 1:N dialect
conversion driver.)

Note for LLVM integration: Replace all occurrences of
`addArgumentMaterialization` (except for 1:N dialect conversion passes)
with `addSourceMaterialization`.

---------

Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
2025-01-03 16:11:56 +01:00
Adrian Kuegel
cba9c6ac15 [mlir] Fix typo in parameter name annotation comment.
Found by ClangTidyBugProne check.
2025-01-03 12:50:05 +00:00
Pranav Kant
d8e7929312
[mlir] Fix -Werror,-Wundefined-bool-conversion after #117513 (#120985) 2024-12-23 10:47:59 -08:00
Matthias Springer
3cc311ab86
[mlir][Transforms] Dialect Conversion: No target mat. for 1:N replacement (#117513)
During a 1:N replacement (`applySignatureConversion` or
`replaceOpWithMultiple`), the dialect conversion driver used to insert
two materializations:

* Argument materialization: convert N replacement values to 1 SSA value
of the original type `S`.
* Target materialization: convert original type to legalized type `T`.

The target materialization is unnecessary. Subsequent patterns receive
the replacement values via their adaptors. These patterns have their own
type converter. When they see a replacement value of type `S`, they will
automatically insert a target materialization to type `T`. There is no
reason to do this already during the 1:N replacement. (The functionality
used to be duplicated in `remapValues` and `insertNTo1Materialization`.)

Special case: If a subsequent pattern does not have a type converter, it
does *not* insert any target materializations. That's because the
absence of a type converter indicates that the pattern does not care
about type legality. Therefore, it is correct to pass an SSA value of
type `S` (or any other type) to the pattern.

Note: Most patterns in `TestPatterns.cpp` run without a type converter.
To make sure that the tests still behave the same, some of these
patterns now have a type converter.

This commit is in preparation of adding 1:N support to the conversion
value mapping. Before making any further changes to the mapping
infrastructure, I'd like to make sure that the code base around it (that
uses the mapping) is robust.
2024-12-23 13:27:39 +01:00
Matthias Springer
79f4143446
[mlir][Transforms] Dialect conversion: Move hasRewrite to expensive checks (#119848)
The dialect conversion has various checks that detect incorrect API
usage in patterns. One of these checks turned out to be quite expensive
(N*M complexity where N is the number of block rewrites and M is the
total number of rewrites) in NVIDIA-internal workloads: Checking that a
block is not converted multiple times.

This check iterates over the stack of all rewrites, which can be large.
We saw `hasRewrite` being called around 45000 times with an average
rewrite stack size of 500000.

This PR moves the check to `MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS`.
For consistency reasons, the other `hasRewrite`-based check is also
moved there.
2024-12-13 11:26:12 +01:00
Matthias Springer
58389b220a
[mlir] Fix build after #116470 (#118147)
This should have been part of #116470.
2024-11-30 10:35:09 +09:00
Matthias Springer
9df63b2651
[mlir][Transforms] Add 1:N matchAndRewrite overload (#116470)
This commit adds a new `matchAndRewrite` overload to `ConversionPattern`
to support 1:N replacements. This is the first of two main PRs that
merge the 1:1 and 1:N dialect conversion drivers.

The existing `matchAndRewrite` function supports only 1:1 replacements,
as can be seen from the `ArrayRef<Value>` parameter.
```c++
LogicalResult ConversionPattern::matchAndRewrite(
    Operation *op, ArrayRef<Value> operands /*adaptor values*/,
    ConversionPatternRewriter &rewriter) const;
```

This commit adds a `matchAndRewrite` overload that is called by the
dialect conversion driver. By default, this new overload dispatches to
the original 1:1 `matchAndRewrite` implementation. Existing
`ConversionPattern`s do not need to be changed as long as there are no
1:N type conversions or value replacements.
```c++
LogicalResult ConversionPattern::matchAndRewrite(
    Operation *op, ArrayRef<ValueRange> operands /*adaptor values*/,
    ConversionPatternRewriter &rewriter) const {
  // Note: getOneToOneAdaptorOperands produces a fatal error if at least one
  // ValueRange has 0 or more than 1 value.
  return matchAndRewrite(op, getOneToOneAdaptorOperands(operands), rewriter);
}
```

The `ConversionValueMapping`, which keeps track of value replacements
and materializations, still does not support 1:N replacements. We still
rely on argument materializations to convert N replacement values back
into a single value. The `ConversionValueMapping` will be generalized to
1:N mappings in the second main PR.

Before handing the adaptor values to a `ConversionPattern`, all argument
materializations are "unpacked". The `ConversionPattern` receives N
replacement values and does not see any argument materializations. This
implementation strategy allows us to use the 1:N infrastructure/API in
`ConversionPattern`s even though some functionality is still missing in
the driver. This strategy was chosen to keep the sizes of the PRs
smaller and to make it easier for downstream users to adapt to API
changes.

This commit also updates the the "decompose call graphs" transformation
and the "sparse tensor codegen" transformation to use the new 1:N
`ConversionPattern` API.

Note for LLVM conversion: If you are using a type converter with 1:N
type conversion rules or if your patterns are performing 1:N
replacements (via `replaceOpWithMultiple` or
`applySignatureConversion`), conversion pattern applications will start
failing (fatal LLVM error) with this error message: `pattern 'name' does
not support 1:N conversion`. The name of the failing pattern is shown in
the error message. These patterns must be updated to the new 1:N
`matchAndRewrite` API.
2024-11-30 09:27:47 +09:00
Matthias Springer
f2d500c617
[mlir][Transforms] Dialect conversion: Fix bug in UnresolvedMaterializationRewrite rollback (#105949)
When an unresolved materialization (`unrealized_conversion_cast` op) is
rolled back, the mapping should be rolled back as well, regardless of
whether it is a source, target or argument materialization. Otherwise,
we accumulate pointers to erased IR in the `mapping`. This is harmless
in most cases, but can cause issues when a new operation is allocated at
the same memory location and the pointer is "reused".

It is not possible to write a test case for this because I cannot
trigger the pointer reuse programmatically.
2024-11-29 11:12:27 +09:00
Matthias Springer
345ca6a692
[mlir][Transforms] Dialect conversion: extra signature conversion check (#117471)
This commit adds an extra assertion to `applySignatureConversion` to
prevent incorrect API usage: The same block cannot be converted multiple
times. That would mess with the underlying conversion value mapping.
(Mappings would be overwritten.) This is similar to op replacements: The
same op cannot be replaced multiple times.

To simplify the check, `BlockTypeConversionRewrite::block` now stores
the original block. The new block is stored in an extra field. (It used
to be the other way around.)

This commit is in preparation of adding 1:N support to the conversion
value mapping. Before making any further changes to the mapping
infrastructure, I'd like to make sure that the code base around it (that
uses the mapping) is robust.
2024-11-25 11:33:38 +09:00
Matthias Springer
3761b67519
[mlir][Transforms][NFC] Dialect conversion: Remove "finalize" phase (#117097)
This is a re-upload of #116934, which was reverted.

The dialect conversion driver has three phases:
- **Create** `IRRewrite` objects as the IR is traversed.
- **Finalize** `IRRewrite` objects. During this phase, source
materializations for mismatching value types are created. (E.g., when
`Value` is replaced with a `Value` of different type, but there is a
user of the original value that was not modified because it is already
legal.)
- **Commit** `IRRewrite` objects. During this phase, all remaining IR
modifications are materialized. In particular, SSA values are actually
being replaced during this phase.

This commit removes the "finalize" phase. This simplifies the code base
a bit and avoids one traversal over the `IRRewrite` stack. Source
materializations are now built during the "commit" phase, right before
an SSA value is being replaced.

This commit also removes the "inverse mapping" of the conversion value
mapping, which was used to predict if an SSA value will be dead at the
end of the conversion. This check is replaced with an approximate check
that does not require an inverse mapping. (A false positive for `v` can
occur if another value `v2` is mapped to `v` and `v2` turns out to be
dead at the end of the conversion. This case is not expected to happen
very often.) This reduces the complexity of the driver a bit and removes
one potential source of bugs. (There have been bugs in the usage of the
inverse mapping in the past.)

`BlockTypeConversionRewrite` no longer stores a pointer to the type
converter. This pointer is now stored in `ReplaceBlockArgRewrite`.

This commit is in preparation of merging the 1:1 and 1:N dialect
conversion driver. It simplifies the upcoming changes around the
conversion value mapping. (API surface of the conversion value mapping
is reduced.)
2024-11-22 16:11:03 +09:00
Matthias Springer
4056d93be5
Revert "[mlir][Transforms][NFC] Dialect conversion: Remove "finalize" phase" (#117094)
Reverts llvm/llvm-project#116934

This commit broke the build.
2024-11-21 10:41:21 +09:00
Matthias Springer
aa65473c9d
[mlir][Transforms][NFC] Dialect conversion: Remove "finalize" phase (#116934)
The dialect conversion driver has three phases:
- **Create** `IRRewrite` objects as the IR is traversed.
- **Finalize** `IRRewrite` objects. During this phase, source
materializations for mismatching value types are created. (E.g., when
`Value` is replaced with a `Value` of different type, but there is a
user of the original value that was not modified because it is already
legal.)
- **Commit** `IRRewrite` objects. During this phase, all remaining IR
modifications are materialized. In particular, SSA values are actually
being replaced during this phase.

This commit removes the "finalize" phase. This simplifies the code base
a bit and avoids one traversal over the `IRRewrite` stack. Source
materializations are now built during the "commit" phase, right before
an SSA value is being replaced.

This commit also removes the "inverse mapping" of the conversion value
mapping, which was used to predict if an SSA value will be dead at the
end of the conversion. This check is replaced with an approximate check
that does not require an inverse mapping. (A false positive for `v` can
occur if another value `v2` is mapped to `v` and `v2` turns out to be
dead at the end of the conversion. This case is not expected to happen
very often.) This reduces the complexity of the driver a bit and removes
one potential source of bugs. (There have been bugs in the usage of the
inverse mapping in the past.)

`BlockTypeConversionRewrite` no longer stores a pointer to the type
converter. This pointer is now stored in `ReplaceBlockArgRewrite`.

This commit is in preparation of merging the 1:1 and 1:N dialect
conversion driver. It simplifies the upcoming changes around the
conversion value mapping. (API surface of the conversion value mapping
is reduced.)
2024-11-21 10:26:05 +09:00