Commit Graph

1507 Commits

Author SHA1 Message Date
Matthias Springer
c0cba25cdd [mlir][Transforms] Dialect conversion: Hardening replaceOp (#109540)
This commit adds extra checks/assertions to the
`ConversionPatternRewriterImpl::notifyOpReplaced` to improve its
robustness.

1. Replacing an `unrealized_conversion_cast` op that was created by the
driver is now forbidden and caught early during `replaceOp`. It may work
in some cases, but it is generally dangerous because the conversion
driver keeps track of these ops and performs some extra legalization
steps during the "finalize" phase. (Erasing is them is fine.)
2. `null` replacement values are no longer registered in the
`ConversionValueMapping`. This was an oversight in #106760. There is no
benefit in having `null` values in the `ConversionValueMapping`. (It may
even cause problems.)

This change is in preparation of merging the 1:1 and 1:N dialect
conversion drivers.
2024-10-29 21:13:54 +09:00
Matthias Springer
a8ef0b33a6 [mlir] Fix build (#113750)
```
mlir/lib/Transforms/Utils/DialectConversion.cpp:2851:28: error: call of overloaded ‘TypeRange(llvm::SmallVector<mlir::Value>&)’ is ambiguous
     assert(TypeRange(result) == resultTypes &&
```
2024-10-25 19:11:38 -07:00
Matthias Springer
8c4bc1e75d [mlir][Transforms] Merge 1:1 and 1:N type converters (#113032)
The 1:N type converter derived from the 1:1 type converter and extends
it with 1:N target materializations. This commit merges the two type
converters and stores 1:N target materializations in the 1:1 type
converter. This is in preparation of merging the 1:1 and 1:N dialect
conversion infrastructures.

1:1 target materializations (producing a single `Value`) will remain
valid. An additional API is added to the type converter to register 1:N
target materializations (producing a `SmallVector<Value>`). Internally,
all target materializations are stored as 1:N materializations.

The 1:N type converter is removed.

Note for LLVM integration: If you are using the `OneToNTypeConverter`,
simply switch all occurrences to `TypeConverter`.

---------

Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
2024-10-25 11:44:20 -07:00
Matthias Springer
f18c3e4e73 [mlir][Transforms] Dialect Conversion: Simplify materialization fn result type (#113031)
This commit simplifies the result type of materialization functions.

Previously: `std::optional<Value>`
Now: `Value`

The previous implementation allowed 3 possible return values:
- Non-null value: The materialization function produced a valid
materialization.
- `std::nullopt`: The materialization function failed, but another
materialization can be attempted.
- `Value()`: The materialization failed and so should the dialect
conversion. (Previously: Dialect conversion can roll back.)

This commit removes the last variant. It is not particularly useful
because the dialect conversion will fail anyway if all other
materialization functions produced `std::nullopt`.

Furthermore, in contrast to type conversions, at least one
materialization callback is expected to succeed. In case of a failing
type conversion, the current dialect conversion can roll back and try a
different pattern. This also used to be the case for materializations,
but that functionality was removed with #107109: failed materializations
can no longer trigger a rollback. (They can just make the entire dialect
conversion fail without rollback.) With this in mind, it is even less
useful to have an additional error state for materialization functions.

This commit is in preparation of merging the 1:1 and 1:N type
converters. Target materializations will have to return multiple values
instead of a single one. With this commit, we can keep the API simple:
`SmallVector<Value>` instead of `std::optional<SmallVector<Value>>`.

Note for LLVM integration: All 1:1 materializations should return
`Value` instead of `std::optional<Value>`. Instead of `std::nullopt`
return `Value()`.
2024-10-23 07:29:17 -07:00
Frank Schlimbach
d5746d73ce eliminating g++ warnings (#105520)
Eliminating g++ warnings. Mostly declaring "[[maybe_unused]]", adding
return statements where missing and fixing casts.

@rengolin

---------

Co-authored-by: Benjamin Maxwell <macdue@dueutil.tech>
Co-authored-by: Renato Golin <rengolin@systemcall.eu>
2024-10-18 21:20:47 +01:00
Longsheng Mou
70865c448c [mlir][transforms] Add signalPassFailure in RemoveDeadValues (#112199)
This PR adds `signalPassFailure` in RemoveDeadValues to ensure that a
pipeline would stop here.
Fixes #111757.
2024-10-18 09:55:41 +08:00
Matthias Springer
0d906a4254 [mlir][Transforms] Dialect conversion: add originalType param to materializations (#112128)
This commit adds an optional `originalType` parameter to target
materialization functions. Without this parameter, target
materializations are underspecified.

Note: `originalType` is only needed for target materializations.
Source/argument materializations do not have it.

Consider the following example: Let's assume that a conversion pattern
"P1" replaced an SSA value "v1" (type "t1") with "v2" (type "t2"). Then
a different conversion pattern "P2" matches an op that has "v1" as an
operand. Let's furthermore assume that "P2" determines that the
legalized type of "t1" is "t3", which may be different from "t2". In
this example, the target materialization callback will be invoked with:
outputType = "t3", inputs = "v2", originalType = "t1". Note that the
original type "t1" cannot be recovered from just "t3" and "v2"; that's
why the `originalType` parameter is added.

This change is in preparation of merging the 1:1 and 1:N dialect
conversion drivers. As part of that change, argument materializations
will be removed (as they are no longer needed; they were just a
workaround because of missing 1:N support in the dialect conversion).
The new `originalType` parameter is needed when lowering MemRef to LLVM.
During that lowering, MemRef function block arguments are replaced with
the elements that make up a MemRef descriptor. The type converter is set
up in such a way that the legalized type of a MemRef type is an
`!llvm.struct` that represents the MemRef descriptor. When the bare
pointer calling convention is enabled, the function block arguments
consist of just an LLVM pointer. In such a case, a target
materialization will be invoked to construct a MemRef descriptor (output
type = `!llvm.struct<...>`) from just the bare pointer (inputs =
`!llvm.ptr`). The original MemRef type is required to construct the
MemRef descriptor, as static sizes/strides/offset cannot be inferred
from just the bare pointer.
2024-10-15 08:52:32 +02:00
Kazu Hirata
ef436f3f60 [mlir] Avoid repeated hash lookups (NFC) (#112158) 2024-10-14 06:55:30 -07:00
Kazu Hirata
1e5f32e81f [Transforms] Avoid repeated hash lookups (NFC) (#111470) 2024-10-08 07:29:43 -07:00
Kazu Hirata
5fdda41474 [Transforms] Avoid repeated hash lookups (NFC) (#111329) 2024-10-07 07:01:07 -07:00
BARRET
1666d13078 [CMake]: Remove unnecessary dependencies on LLVM/MLIR (#111255)
Previous https://github.com/llvm/llvm-project/pull/110362 (reverted)
caused breakage. Here is the PR with fix.

My build cmdline:

```
cmake ../llvm \
    -G Ninja \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=install \
    -DCMAKE_C_COMPILER=gcc-9 \
    -DCMAKE_CXX_COMPILER=g++-9 \
    -DCMAKE_CUDA_COMPILER=$(which nvcc) \
    -DLLVM_ENABLE_LLD=OFF \
    -DLLVM_ENABLE_ASSERTIONS=ON \
    -DLLVM_BUILD_EXAMPLES=ON \
    -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
    -DLLVM_CCACHE_BUILD=ON \
    -DMLIR_ENABLE_BINDINGS_PYTHON=ON \
    -DBUILD_SHARED_LIBS=ON \
    -DLLVM_ENABLE_PROJECTS='llvm;mlir'
```
2024-10-07 15:52:43 +02:00
Matthias Springer
206fad0e21 [mlir][NFC] Mark type converter in populate... functions as const (#111250)
This commit marks the type converter in `populate...` functions as
`const`. This is useful for debugging.

Patterns already take a `const` type converter. However, some
`populate...` functions do not only add new patterns, but also add
additional type conversion rules. That makes it difficult to find the
place where a type conversion was added in the code base. With this
change, all `populate...` functions that only populate pattern now have
a `const` type converter. Programmers can then conclude from the
function signature that these functions do not register any new type
conversion rules.

Also some minor cleanups around the 1:N dialect conversion
infrastructure, which did not always pass the type converter as a
`const` object internally.
2024-10-05 21:32:40 +02:00
Matthias Springer
5030deadef [mlir][Transforms] Dialect conversion: No rollback during analysis conversion (#106414)
This commit changes the implementation of analysis conversions, so that
no rollback is needed at the end of the analysis. Instead, the dialect conversion is run on a clone of the IR.

The purpose of this commit is to reduce the number of rollbacks in the
dialect conversion framework. (Long term goal: Remove rollback
functionality entirely.)
2024-10-04 09:34:08 +02:00
Perry Gibson
7ad566d575 [mlir] Fix remove-dead-values pass throws error when module has a name (#109990)
Fixes #107870.

We can allow the enclosing Module operation to have a symbol.
The check was likely originally not considering this case and intended
to catch symbols inside the region, not accounting that the walk would
visit the enclosing operation.
2024-10-03 10:51:55 +02:00
Matthias Springer
8897dd6fc5 [mlir][Transforms][NFC] Dialect Conversion: Simplify finalize signature (#110419)
This commit simplifies the signature of `OperationConverter::finalize`.
This function always returns "success", so the return value can be
removed.

Note: Previously, this function used to return "failure" if a
materialization failed to legalize. This is now optional and happening
at a later point of time (see `config.buildMaterializations`).
2024-10-01 09:06:47 +02:00
Mehdi Amini
8b47711e84 Revert "CMake: Remove unnecessary dependencies on LLVM/MLIR" (#110594)
Reverts llvm/llvm-project#110362

Multiple bots are broken.
2024-10-01 00:44:21 +02:00
BARRET
4980f2177e CMake: Remove unnecessary dependencies on LLVM/MLIR (#110362)
There are some spurious libraries which can be removed.

I'm trying to bundle MLIR/LLVM library dependencies for our own
libraries. We're utilizing cmake function to recursively collect
MLIR/LLVM related dependencies. However, we identified certain library
dependencies as redundant and safe for removal.
2024-09-30 23:57:13 +02:00
Matthias Springer
023f7c9382 [mlir][Transforms][NFC] Dialect Conversion: Update docs for remapValues (#110414)
Simplify the nesting structure of "if" checks in `remapValues` and
update the code comments.

This is what the comments stated in case there is no type converter:
```
      // TODO: What we should do here is just set `desiredType` to `origType`
      // and then handle the necessary type conversions after the conversion
      // process has finished. Unfortunately a lot of patterns currently rely on
      // receiving the new operands even if the types change, so we keep the
      // original behavior here for now until all of the patterns relying on
      // this get updated.
```

However, without a type converter it is not possible to perform any
materializations. Furthermore, the absence of a type converter indicates
that the pattern does not care about type legality. Therefore, the
current implementation is correct and this TODO can be removed.

Note: Patterns that actually require a remapped type to match the
original operand type can be equipped with a type converter that maps
each type to itself.

This TODO is outdated:
```
      // TODO: There currently isn't any mechanism to do 1->N type conversion
      // via the PatternRewriter replacement API, so for now we just ignore it.
```
1->N type conversions are already possible as part of block signature
conversions. It is incorrect to just ignore such cases. However, there
is currently no better way to handle 1->N conversions in this function
because of infrastructure limitations. This is now clarified in the
comments.
2024-09-30 21:19:32 +02:00
Matthias Springer
fcde4f6577 [mlir][Transforms][NFC] Dialect Conversion: Remove redundant lookupOrDefault (#110370)
Remove a redundant `lookupOrDefault` that has no effect.

When no type is passed to `lookupOrDefault`, that function returns the
furthest mapped value (by following the mapping iteratively). If there
is no mapped value with the desired type, then the function also returns
the furthest mapped value.

The value that was passed to the redundant `lookupOrDefault` was
produced by this code:
```
Value newOperand = mapping.lookupOrDefault(operand, desiredType);
```

There are 2 possible cases:
- Case 1: There is no mapping to `desiredType`. Then `newOperand` is the
furthest mapped value.
- Case 2: There is a mapping to `desiredType`. Then the type of
`newOperand` is `desiredType` and the "if" branch that encloses the
redundant `lookupOrDefault` is not executed at all.

Also improve the documentation of
`ConversionValueMapping::lookupOrDefault` and simplify the
implementation a bit.
2024-09-28 20:09:45 +02:00
Matthias Springer
8527861179 [mlir][Transforms] Dialect conversion: Unify materialization of value replacements (#108381)
PR #106760 aligned the handling of dropped block arguments and dropped
op results. The two helper functions that insert source materializations
for uses of replaced block arguments / op results that survived the
conversion are now almost identical (`legalizeConvertedArgumentTypes`
and `legalizeConvertedOpResultTypes`). This PR merges the two functions
and moves the implementation directly into `finalize`.

This PR simplifies the code base and improves the efficiency a bit:
previously, `finalize` iterated over
`ConversionPatternRewriterImpl::rewrites` twice. Now, only one iteration
is needed.

---------

Co-authored-by: Jakub Kuderski <jakub@nod-labs.com>
2024-09-21 10:02:17 +02:00
JOE1994
095b41c6ee [mlir] Reland 5a6e52d6ef with update (NFC)
Excluded updates to mlir/lib/AsmParser/Parser.cpp ,
which caused LIT failure "FAIL: MLIR::completion.test" on multiple buildbots.
2024-09-15 22:45:28 -04:00
JOE1994
61ff1cb452 Revert "[mlir] Nits on uses of llvm::raw_string_ostream (NFC)"
This reverts commit 5a6e52d6ef.

"FAIL: MLIR::completion.test" on multiple buildbots.
2024-09-15 22:09:11 -04:00
JOE1994
5a6e52d6ef [mlir] Nits on uses of llvm::raw_string_ostream (NFC)
* Strip calls to raw_string_ostream::flush(), which is essentially a no-op
* Strip unneeded calls to raw_string_ostream::str(), to avoid excess indirection.
2024-09-15 21:33:42 -04:00
Longsheng Mou
1208699618 [mlir][transforms] Skip RemoveDeadValues for function declaration (#108221)
This patch skips `RemoveDeadValues` if funcOp is declaration, which
fixes a crash.
Fixes #107546.
2024-09-14 21:24:51 +08:00
Matthias Springer
d588e49a32 [mlir][Transforms][NFC] Dialect conversion: Cache UnresolvedMaterializationRewrite (#108359)
The dialect conversion maintains a set of unresolved materializations
(`UnrealizedConversionCastOp`). Turn that set into a `DenseMap` that
maps from ops to `UnresolvedMaterializationRewrite *`. This improves
efficiency a bit, because an iteration over
`ConversionPatternRewriterImpl::rewrites` can be avoided.

Also delete some dead code.
2024-09-13 20:16:05 +02:00
Matthias Springer
6093c26ac9 [mlir][Transforms] Dialect conversion: Align handling of dropped values (#106760)
Handle dropped block arguments and dropped op results in the same way:
build a source materialization (that may fold away if unused). This
simplifies the code base a bit and makes it possible to merge
`legalizeConvertedArgumentTypes` and `legalizeConvertedOpResultTypes` in
a future commit. These two functions are almost doing the same thing
now.

As a side effect, this commit also changes the dialect conversion such
that temporary circular cast ops are no longer generated. (There was a
workaround in #107109 that can now be removed again.) Example:
```
%0 = "builtin.unrealized_conversion_cast"(%1) : (!a) -> !b
%1 = "builtin.unrealized_conversion_cast"(%0) : (!b) -> !a
// No further uses of %0, %1.
```

This happened when:
1. An op was erased. (No replacement values provided.)
2. A conversion pattern for another op builds a replacement value for
the erased op's results (first cast op) during `remapValues`, but that
SSA value is not used during the pattern application.
3. During the finalization phase, `legalizeConvertedOpResultTypes`
thinks that the erased op is alive because of the cast op that was built
in Step 2. It builds a cast from that replacement value to the original
type.
4. During the commit phase, all uses of the original op are replaced
with the casted value produced in Step 3. We have generated circular IR.

This problem can be avoided by making sure that source materializations
are generated for all dropped results. This ensures that we always have
some replacement SSA value in the mapping. Previously, we sometimes had
a value mapped and sometimes not. (No more special casing is needed
anymore to distinguish between "value dropped" or "value replaced with
SSA value".)
2024-09-12 15:30:29 +02:00
Kazu Hirata
42494e5175 [Transforms] Avoid repeated hash lookups (NFC) (#108322) 2024-09-12 00:52:38 -07:00
Kazu Hirata
4b1b450ae4 [Transforms] Avoid repeated hash lookups (NFC) (#108139) 2024-09-11 06:40:17 -07:00
Henrich Lauko
d1cad2290c Reland [MLIR] Make resolveCallable customizable in CallOpInterface (#107989)
Relands #100361 with fixed dependencies.
2024-09-10 15:33:13 +02:00
Sven van Haastregt
bda9474f57 Add missing newlines at EOF; NFC 2024-09-10 13:55:31 +01:00
Matthias Springer
3815f478bb [mlir][Transforms] Dialect conversion: Make materializations optional (#107109)
This commit makes source/target/argument materializations (via the
`TypeConverter` API) optional.

By default (`ConversionConfig::buildMaterializations = true`), the
dialect conversion infrastructure tries to legalize all unresolved
materializations right after the main transformation process has
succeeded. If at least one unresolved materialization fails to resolve,
the dialect conversion fails. (With an error message such as `failed to
legalize unresolved materialization ...`.) Automatic materializations
through the `TypeConverter` API can now be deactivated. In that case,
every unresolved materialization will show up as a
`builtin.unrealized_conversion_cast` op in the output IR.

There used to be a complex and error-prone analysis in the dialect
conversion that predicted the future uses of unresolved
materializations. Based on that logic, some casts (that were deemed to
unnecessary) were folded. This analysis was needed because folding
happened at a point of time when some IR changes (e.g., op replacements)
had not materialized yet.

This commit removes that analysis. Any folding of cast ops now happens
after all other IR changes have been materialized and the uses can
directly be queried from the IR. This simplifies the analysis
significantly. And certain helper data structures such as
`inverseMapping` are no longer needed for the analysis. The folding
itself is done by `reconcileUnrealizedCasts` (which also exists as a
standalone pass).

After casts have been folded, the remaining casts are materialized
through the `TypeConverter`, as usual. This last step can be deactivated
in the `ConversionConfig`.

`ConversionConfig::buildMaterializations = false` can be used to debug
error messages such as `failed to legalize unresolved materialization
...`. (It is also useful in case automatic materializations are not
needed.) The materializations that failed to resolve can then be seen as
`builtin.unrealized_conversion_cast` ops in the resulting IR. (This is
better than running with `-debug`, because `-debug` shows IR where some
IR changes have not been materialized yet.)

Note: This is a reupload of #104668, but with correct handling of cyclic
unrealized_conversion_casts that may be generated by the dialect
conversion.
2024-09-05 19:40:58 +02:00
Ben Howe
c50fecaaaa [mlir] Fix region simplification bug when later blocks use prior block argument values (#97960)
This fixes #94520 by ensuring that any if any block arguments are being
used outside of the original block that the block is not considered a
candidate for merging.

More details: the root cause of the issue described in #94520 was that
`^bb2` and `^bb5` were being merged despite `%4` (an argument to `^bb2`)
was being used later in `^bb7`. When the block merge occurred, that
unintentionally changed the value of `%4` for all downstream code. This
change prevents that from happening.
2024-09-04 21:37:14 +02:00
Kazu Hirata
59a3b41568 [ADT] Deprecate DenseMap::getOrInsertDefault (#107040)
This patch deprecates DenseMap::getOrInsertDefault in favor of
DenseMap::operator[], which does the same thing, has been around
longer, and is also a household name as part of std::map and
std::unordered_map.

Note that DenseMap provides several equivalent ways to insert or
default-construct a key-value pair:

- operator[Key]
- try_emplace(Key).first->second
- getOrInsertDefault(Key)
- FindAndConstruct(Key).second
2024-09-03 08:19:45 -07:00
Matthias Springer
5eda498811 Revert "[mlir][Transforms] Dialect conversion: Make materializations optional" (#106778)
Reverts llvm/llvm-project#104668

This commit triggers an edge case that can cause circular
`unrealized_conversion_cast` ops.
https://github.com/llvm/llvm-project/pull/106760 may fix it, but it is
has other issues. Reverting this PR for now, until I find a solution for
that problem.
2024-08-30 12:34:41 -07:00
Matthias Springer
e8863748ba [mlir][Transforms][NFC] Dialect conversion: Remove redundant ReplaceBlockArgRewrite (#105963)
There was a redundant `appendRewrite<ReplaceBlockArgRewrite>(block,
origArg);` in `ConversionPatternRewriterImpl::applySignatureConversion`
that had no effect.
2024-08-27 07:48:37 -07:00
Christian Ulmann
6f092e501b [MLIR][Transforms] Update block arg locations during inlining (#106064)
This commit changes the inlining to also update the locations of block
arguments. Not updating these locations leads to LLVM IR verification
issues when exporting converted block arguments to phi nodes. This lack
of location update was not visible due to ignoring the argument
locations until recently.
Relevant change: https://github.com/llvm/llvm-project/pull/105534
2024-08-26 15:23:39 +02:00
Matthias Springer
d7073c5274 [mlir][Transforms] Dialect conversion: Make materializations optional (#104668)
This commit makes source/target/argument materializations (via the
`TypeConverter` API) optional.

By default (`ConversionConfig::buildMaterializations = true`), the
dialect conversion infrastructure tries to legalize all unresolved
materializations right after the main transformation process has
succeeded. If at least one unresolved materialization fails to resolve,
the dialect conversion fails. (With an error message such as `failed to
legalize unresolved materialization ...`.) Automatic materializations
through the `TypeConverter` API can now be deactivated. In that case,
every unresolved materialization will show up as a
`builtin.unrealized_conversion_cast` op in the output IR.

There used to be a complex and error-prone analysis in the dialect
conversion that predicted the future uses of unresolved
materializations. Based on that logic, some casts (that were deemed to
unnecessary) were folded. This analysis was needed because folding
happened at a point of time when some IR changes (e.g., op replacements)
had not materialized yet.

This commit removes that analysis. Any folding of cast ops now happens
after all other IR changes have been materialized and the uses can
directly be queried from the IR. This simplifies the analysis
significantly. And certain helper data structures such as
`inverseMapping` are no longer needed for the analysis. The folding
itself is done by `reconcileUnrealizedCasts` (which also exists as a
standalone pass).

After casts have been folded, the remaining casts are materialized
through the `TypeConverter`, as usual. This last step can be deactivated
in the `ConversionConfig`.

`ConversionConfig::buildMaterializations = false` can be used to debug
error messages such as `failed to legalize unresolved materialization
...`. (It is also useful in case automatic materializations are not
needed.) The materializations that failed to resolve can then be seen as
`builtin.unrealized_conversion_cast` ops in the resulting IR. (This is
better than running with `-debug`, because `-debug` shows IR where some
IR changes have not been materialized yet.)
2024-08-23 14:03:10 -07:00
Matthias Springer
a9f62244f2 [mlir][Transforms][NFC] Move ReconcileUnrealizedCasts implementation (#104671)
Move the implementation of `ReconcileUnrealizedCasts` to
`DialectConversion.cpp`, so that it can be called from there in a future
commit.

This commit is in preparation of decoupling argument/source/target
materializations from the dialect conversion framework. The existing
logic around unresolved materializations that predicts IR changes to
decide if a cast op can be folded/erased will become obsolete, as
`ReconcileUnrealizedCasts` will perform these kind of foldings on fully
materialized IR.

---------

Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
2024-08-23 08:46:31 -07:00
Théo Degioanni
b084111c8e [mlir][mem2reg] Fix Mem2Reg attempting to promote in graph regions (#104910)
Mem2Reg assumes SSA dependencies but did not check for graph regions.
This fixes it.

---------

Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
2024-08-23 15:15:10 +02:00
Billy Zhu
baa6627a0a [MLIR][Transforms] Fix dialect conversion inverse mapping (#104648)
Inverse mapping needs to be updated for the result that was remapped (it
was previously only updated halfway).
2024-08-19 18:04:16 -07:00
Matthias Springer
cb7614e839 [mlir][Transforms] Dialect conversion: Fix bug in computeNecessaryMaterializations (#104630)
There was a typo in the code path that removes unnecessary
materializations.

Before: Update `opResult` (result of an op different from `user`) in
mapping and remove `user`.
```
replaceMaterialization(rewriterImpl, opResult, inputOperands,
                       inverseMapping);
necessaryMaterializations.remove(materializationOps.lookup(user));
```

After: Update `user->getResults()` in mapping and remove `user`.
```
replaceMaterialization(rewriterImpl, user->getResults(), inputOperands,
                       inverseMapping);
necessaryMaterializations.remove(materializationOps.lookup(user));
```
2024-08-17 09:43:30 +02:00
Matthias Springer
2d50029f98 [mlir][Transforms] Dialect conversion: Build unresolved materialization for replaced ops (#101514)
When inserting an argument/source/target materialization, the dialect
conversion framework first inserts a "dummy"
`unrealized_conversion_cast` op (during the rewrite process) and then
(in the "finialize" phase) replaces these cast ops with the IR generated
by the type converter callback.

This is the case for all materializations, except when ops are being
replaced with values that have a different type. In that case, the
dialect conversion currently directly emits a source materialization.
This commit changes the implementation, such that a temporary
`unrealized_conversion_cast` is also inserted in that case.

This commit simplifies the code base: all materializations now happen in
`legalizeUnresolvedMaterialization`. This commit makes it possible to
decouple source/target/argument materializations from the dialect
conversion (to reduce the complexity of the code base). Such
materializations can then also be optional. This will be implemented in
a follow-up commit.

Depends on #101476.

---------

Co-authored-by: Jakub Kuderski <jakub@nod-labs.com>
2024-08-15 11:33:37 +02:00
Giuseppe Rossini
a0241e710f Fix late comment review for #102038 (#102869) 2024-08-12 11:10:01 +01:00
Matthias Springer
f09a28e66c [mlir][Transforms][NFC] Dialect conversion: Eagerly build reverse mapping (#101476)
The "inverse mapping" is an inverse IRMapping that points from replaced
values to their original values. This inverse mapping is needed when
legalizing unresolved materializations, to figure out if a value has any
uses. (It is not sufficient to examine the IR, because some IR changes
have not been materialized yet.)

There was a check in `OperationConverter::finalize` that computed the
inverse mapping only when needed. This check is not needed.
`legalizeUnresolvedMaterializations` always computes the inverse
mapping, so we can just do that in `OperationConverter::finalize` before
calling `legalizeUnresolvedMaterializations`.

Depends on #98805
2024-08-09 07:51:30 +02:00
Giuseppe Rossini
441b672bbd [mlir] Fix block merging (#102038)
With this PR I am trying to address:
https://github.com/llvm/llvm-project/issues/63230.

What changed:
- While merging identical blocks, don't add a block argument if it is
"identical" to another block argument. I.e., if the two block arguments
refer to the same `Value`. The operations operands in the block will
point to the argument we already inserted. This needs to happen to all
the arguments we pass to the different successors of the parent block
- After merged the blocks, get rid of "unnecessary" arguments. I.e., if
all the predecessors pass the same block argument, there is no need to
pass it as an argument.
- This last simplification clashed with
`BufferDeallocationSimplification`. The reason, I think, is that the two
simplifications are clashing. I.e., `BufferDeallocationSimplification`
contains an analysis based on the block structure. If we simplify the
block structure (by merging and/or dropping block arguments) the
analysis is invalid . The solution I found is to do a more prudent
simplification when running that pass.

**Note-1**: I ran all the integration tests
(`-DMLIR_INCLUDE_INTEGRATION_TESTS=ON`) and they passed.
**Note-2**: I fixed a bug found by @Dinistro in #97697 . The issue was
that, when looking for redundant arguments, I was not considering that
the block might have already some arguments. So the index (in the block
args list) of the i-th `newArgument` is `i+numOfOldArguments`.
2024-08-07 09:10:01 +01:00
Kazu Hirata
5262865aac [mlir] Construct SmallVector with ArrayRef (NFC) (#101896) 2024-08-04 11:43:05 -07:00
Matthias Springer
2fc71e4e4b [mlir][Transforms][NFC] Dialect Conversion: Move argument materialization logic (#98805)
This commit moves the argument materialization logic from
`legalizeConvertedArgumentTypes` to
`legalizeUnresolvedMaterializations`.

Before this change:
- Argument materializations were created in
`legalizeConvertedArgumentTypes` (which used to call
`materializeLiveConversions`).

After this change:
- `legalizeConvertedArgumentTypes` creates a "placeholder"
`unrealized_conversion_cast`.
- The placeholder `unrealized_conversion_cast` is replaced with an
argument materialization (using the type converter) in
`legalizeUnresolvedMaterializations`.
- All argument and target materializations now take place in the same
location (`legalizeUnresolvedMaterializations`).

This commit brings us closer towards creating all source/target/argument
materializations in one central step, which can then be made optional
(and delegated to the user) in the future. (There is one more source
materialization step that has not been moved yet.)

This commit also consolidates all `build*UnresolvedMaterialization`
functions into a single `buildUnresolvedMaterialization` function.

This is a re-upload of #96329.
2024-08-03 08:57:48 +02:00
Adrian Kuegel
17ba4f4053 Revert "[mlir][Transforms] Dialect conversion: Skip materializations when running without converter (#101318)"
This reverts commit 2aa96fcf75.

This was merged without a test. Also it seems it was only fixing an
issue for users which used a particular workaround that is not actually
needed anymore (skipping UnrealizedConversionCast operands).
2024-08-01 08:43:59 +00:00
Hideto Ueno
42c413b489 [mlir][Transforms] Preserve all analysis in print passes (#101315)
PrintIRPass, PrintOpStatsPass and PrintOpGraphPass don't mutate IR so
preserve all analysis to save computation resource a bit.
2024-08-01 11:51:28 +09:00
Matthias Springer
2aa96fcf75 [mlir][Transforms] Dialect conversion: Skip materializations when running without converter (#101318)
TODO: test case
2024-07-31 14:36:50 -07:00