216 Commits

Author SHA1 Message Date
Adam Siemieniuk
9a767dce95
[mlir][bufferization] Drop equivalent buffer results - modify public functions option (#177589)
Adds an option to allow modification of public functions to the drop
equivalent buffer results API and the respective pass.
A new standalone test for the pass is also added.

https://github.com/llvm/llvm-project/pull/163001 modified the default
behavior by disallowing rewriting public function. This PR preserves the
new behavior and only adds an opt-in flag to reenable changing public
function.

The extra flag aligns dropping equivalent function results with another
bufferization API `promoteBufferResultsToOutParams` which also allows
opt-in public function rewriting.
2026-02-02 15:12:32 +01:00
Stefan Weigl-Bosker
86b17aeaf2
[MLIR][Bufferization]: Handle invalid memref element types (#173692)
Fixes #128329, Fixes #128330, Fixes #173565, Fixes #114730

There is an assertion failure in `-one-shot-bufferize` when tensors that
have an element type that can't be a memref element type are
encountered.
f8d3f47e1f/mlir/include/mlir/IR/BuiltinTypes.h (L440)

We can't emit a to_tensor for ops that do implement
`BufferizableOpInterface`, and i don't think quantizing is the right
move either, so erroring seemed like the best fit.

After some trial and error, `defaultGetBufferType` seems like the most
functional and least invasive place to put this check.
2025-12-31 01:55:33 +08:00
Quinn Dawkins
bb17dfa7d1
[mlir][bufferization] Enable moving dependent values in eliminate-empty-tensors (#169718)
Currently empty tensor elimination by constructing a SubsetExtractionOp
to match a SubsetInsertionOp at the end of a DPS chain will fail if any
operands required by the insertion op don't dominate the insertion point
for the extraction op.

This change improves the transformation by attempting to move all pure
producers of required operands to the insertion point of the extraction
op. In the process this improves a number of tests for empty tensor
elimination.
2025-12-05 14:40:08 -05:00
ddubov100
50b907751f
Added RecursiveMemoryEffects to ExecuteRegionOp (#164390)
Added RecursiveMemoryEffects to ExecuteRegionOp to be aligned to other
ops with region and get appropriate support in all appropriate passes,
which need RecursiveMemoryEffects.
The added test in dealloc-memoryeffect-interface.mlir fails with error
'ops with unknown memory side effects are not supported' without
RecursiveMemoryEffects.
The updated test in one-shot-module-bufferize.mlir gets cleaned by DCE
once the interface is added. Added func.call @foo():()->() which has
effect to keep execute_region from being removed.

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2025-10-28 13:44:33 +02:00
Andrei Golubev
3141bdefff
[mlir][bufferization] Test tensor encoding -> memref layout conversion (#161166)
Support custom types (4/N): test that it is possible to customize memref
layout specification for custom operations and function boundaries.

This is purely a test setup (no API modifications) to ensure users are
able to pass information from tensors to memrefs within bufferization
process. To achieve this, a test pass is required (since bufferization
options have to be set manually). As there is already a
--test-one-shot-module-bufferize pass present, it is extended for the
purpose.
2025-10-15 12:44:17 +02:00
lonely eagle
3f99d2fc9a
[mlir][bufferize] Make drop-equivalent-buffer-results only support functions that are neither public nor extern (#163001)
The callers of public or extern functions are unknown, so their function
signatures cannot be changed.
2025-10-14 18:27:30 +08:00
lonely eagle
71586a6a73
[mlir][bufferize] Make buffer-results-to-out-params support only functions that are neither public nor extern (#162441)
The callers of public or extern functions are unknown, so their function
signatures cannot be changed.
2025-10-08 16:54:02 +08:00
Alexandre Eichenberger
d45b427ed4
[MLIR] Define memory effects for memref.prefetch operation (#151261)
Currently `memref.prefetch` has no memory side effects, which are
necessary for some optimizations.

This PR adds the needed side effect, as recommended in
https://discourse.llvm.org/t/modeling-volatility-with-memory-effects/67946

This PR was created after a discussion on this specific topic here
https://discourse.llvm.org/t/memref-prefetch-op-has-no-memory-side-effects-decoration-in-the-def-td-file/87482

---------

Signed-off-by: Alexandre Eichenberger <alexe@us.ibm.com>
2025-10-08 08:36:57 +01:00
Dor Arad
373a2f1f22
[mlir][scf] ExecuteRegionOp bufferization to consider no_inline attr (#160697)
Fix a bug where ExecuteRegionOp bufferization dropped the "no_inline"
attribute.

Co-authored-by: Dor Arad <dor.arad@mobileye.com>
2025-09-25 15:53:00 +02:00
Andrei Golubev
ff4c4997ee
[mlir][bufferization] Support custom types at function boundaries (#159766)
Support custom types (3/N): allow custom tensor and buffer types in
function signatures and at call-sites. This is one of the major building
blocks to move in the direction of module-level one-shot-bufferization
support.

To achieve this, `BufferizationOptions::FunctionArgTypeConverterFn`
callback is converted to work with tensor-like and buffer-like types,
instead of the builtin counterparts. The default behavior for builtins
remains unchanged, while custom types by default go through
`TensorLikeType::getBufferType()` which is a general conversion
interface.
2025-09-24 13:09:27 +02:00
Evan Liu
e654d4e8fd
[mlir] Generalize OneShotModuleBufferize to operate on any Operation (#148327)
As part of 2646c36a864aa6a62bc1280e9a8cd2bcd2695349,
`OneShotModuleBufferize` no longer descends into nested symbol tables,
recommending users who wish to do this should do so in a pass
pipeline/custom pass. This did not support the use case of ops that
weren't ModuleOps. The patch updates `OneShotModuleBufferize` to work on
any general op.
2025-07-28 19:29:18 -07:00
Andrei Golubev
a63f572628
[mlir][bufferization] Return BufferLikeType in BufferizableOpInterface (#144867)
Support custom types (2/N): allow value-owning operations (e.g.
allocation ops) to bufferize custom tensors into custom buffers. This
requires BufferizableOpInterface::getBufferType() to return
BufferLikeType instead of BaseMemRefType.

Affected implementors of the interface are updated accordingly.

Relates to ee070d08163ac09842d9bf0c1315f311df39faf1.
2025-07-02 11:27:35 -07:00
Andrei Golubev
ee070d0816
[mlir][bufferization] Support custom types (1/N) (#142986)
Following the addition of TensorLike and BufferLike type interfaces (see
00eaff3e9c897c263a879416d0f151d7ca7eeaff), introduce minimal changes
required to bufferize a custom tensor operation into a custom buffer
operation.

To achieve this, new interface methods are added to TensorLike type
interface that abstract away the differences between existing (tensor ->
memref) and custom conversions.

The scope of the changes is intentionally limited (for example,
BufferizableOpInterface is untouched) in order to first understand the
basics and reach consensus design-wise.

---
Notable changes:
* mlir::bufferization::getBufferType() returns BufferLikeType (instead
of BaseMemRefType)
* ToTensorOp / ToBufferOp operate on TensorLikeType / BufferLikeType.
Operation argument "memref" renamed to "buffer"
* ToTensorOp's tensor type inferring builder is dropped (users now need
to provide the tensor type explicitly)
2025-06-18 16:18:12 +02:00
Shay Kleiman
ffb9bbfd07
[mlir][MemRef] Changed AssumeAlignment into a Pure ViewLikeOp (#139521)
Made AssumeAlignment a ViewLikeOp that returns a new SSA memref equal
to its memref argument and made it have Pure trait. This
gives it a defined memory effect that matches what it does in practice
and makes it behave nicely with optimizations which won't get rid of it
unless its result isn't being used.
2025-05-18 13:50:29 +03:00
Andrei Golubev
8f91b108df
[mlir][bufferization][NFC] Rename to_memref to to_buffer (#137180)
As part of the work on transitioning bufferization dialect, ops, and
associated logic to operate on newly added type interfaces (see
00eaff3e9c897c263a879416d0f151d7ca7eeaff), rename the
bufferization.to_memref to highlight the generic nature of the op.

Bufferization process produces buffers while memref is a builtin type
rather than a generic term.

Preserve the current API (to_buffer still produces a memref), however,
as the new type interfaces are not used yet.
2025-05-14 11:17:09 +02:00
Andrei Golubev
00eaff3e9c
[mlir][bufferization] Add tensor-like and buffer-like interfaces (#134220)
Current one-shot bufferization infrastructure operates on top of
TensorType and BaseMemRefType. These are non-extensible base classes of
the respective builtins: tensor and memref. Thus, the infrastructure is
bound to work only with builtin tensor/memref types. At the same time,
there are customization points that allow one to provide custom logic to
control the bufferization behavior.

This patch introduces new type interfaces: tensor-like and buffer-like
that aim to supersede TensorType/BaseMemRefType within the bufferization
dialect and allow custom tensors / memrefs to be used. Additionally,
these new type interfaces are attached to the respective builtin types
so that the switch is seamless.

Note that this patch does very minimal initial work, it does NOT
refactor bufferization infrastructure.

See https://discourse.llvm.org/t/rfc-changing-base-types-for-tensors-and-memrefs-from-c-base-classes-to-type-interfaces/85509
2025-04-15 11:38:49 +02:00
Mike
f20cb3f8d2
[mlir][bufferization] Drop the assumption for alloc result index (#134503)
Relax the assumption that alloc op always has allocation at
`getResult(0)`, allow to use `optimize-allocation-liveness` pass for
custom ops with >1 results. Ops with multiple allocations are not
handled here yet.
2025-04-07 11:54:44 +03:00
Javed Absar
41f9a00818
[NFC][mlir][bufferization] (#132637) 2025-03-24 07:50:27 +00:00
Christopher Bate
2646c36a86
[mlir][bufferization] Change OneShotModuleBufferize to not analyze or bufferize nested symbol tables (#127726)
The existing OneShotModuleBufferize will analyze and bufferize
operations which are in nested symbol tables (e.g. nested
`builtin.module`, `gpu.module`, or similar operations). This
behavior is untested and likely unintentional given other
limitations of OneShotModuleBufferize (`func.call` can't call
into nested symbol tables). This change reverses the existing
behavior so that the operations considered by the analysis and
bufferization exclude any operations in nested symbol table
scopes. Users who desire to bufferize nested modules can still do
so by applying the transformation in a pass pipeline or in a
custom pass. This further enables controlling the order in which
modules are bufferized as well as allowing use of different
options for different kinds of modules.
2025-02-25 14:23:11 -07:00
Matthias Springer
d4cb75ef8b
[mlir][bufferization] Module bufferization: Delete obsolete code (#127455)
Delete `equivalenceAnalysis`, which has been incorporated into the
`getAliasingValues` API. Also add an additional test case to ensure that
equivalence is properly propagated across function boundaries.
2025-02-19 10:00:06 +01:00
Matthias Springer
213917be82
[mlir][bufferization] Remove buffer-deallocation pass (#126366)
The `-buffer-deallocation` pass is not compatible with One-Shot
Bufferize and has been replaced with the Ownership-based Buffer
Deallocation pass about 1.5 years ago. To clean up the code base, this
commit removes the deprecated `buffer-deallocation` pass. All uses of
this deprecated pass within MLIR have already been migrated.

Note for LLVM integration: If you depend on this pass, migrate to the
Ownership-based Buffer Deallocation pass or copy the pass to your
codebase. For details, see
https://discourse.llvm.org/t/psa-bufferization-new-buffer-deallocation-pipeline/73375.
2025-02-13 09:49:16 +01:00
Jay Foad
e87f94a6a8
[llvm-project] Fix typos mutli and mutliple. NFC. (#122880) 2025-01-14 11:59:41 +00:00
Amir Bishara
d9111f19d2
[mlir][bufferization]-Refactor findValueInReverseUseDefChain to accept opOperand (#121304)
Edit the `findValueInReverseUseDefChain` method to accept `OpOperand`
instead of the `Value` type, This change will make sure that the
populated `visitedOpOperands` argument is fully accurate and contains
the opOperand we have started the reverse chain from.
2024-12-30 21:18:38 +02:00
Amir Bishara
08aa956387
[mlir][bufferization]-Replace only one use in TensorEmptyElimination (#118958)
In many cases the emptyTensorElimination can not transform or eliminate
the empty tensor which is being inserted into the
`SubsetInsertionOpInterface`.

Two major reasons for that:

1- Failing when trying to find a legal/suitable insertion point for the
`subsetExtract` which is about to replace the empty tensor. However, we
may try to handle this issue by moving the needed values which
responsible on building the `subsetExtract` nearby the empty tensor
(which is about to be eliminated). Thus increasing the probability to
find a legal insertion point.

2-The EmptyTensorElimination transform replaces the tensor.empty's uses
all at once in one apply, rather than replacing only the specific use
which was visited in the use-def chain (when traversing from the
tensor.insert_slice). This scenario of replacing all the uses of the
tensor.empty may lead into additional read effects after bufferization
of the specific subset extract/subview which should not be the case.

Both cases may result in many copies in the coming bufferization which
can not be canonicalized.

The first case can be noticed when having a `tensor.empty` followed by
`SubsetInsertionOpInterface` (or in simple words `tensor.insert_slice`),
which have been lowered from `tensor/tosa.concat`.

The second case can be noticed when having a `tensor.empty`, with many
uses and leading to applying the transformation only once, since the
whole uses have been replaced at once.

The first commit in the PR only adds the lit tests for the cases shown
above (NFC), to emphasize how the transform works, in the coming MRs
will upload a slight changes to handle these case.

The second commit in this PR, we want to replace only the specific use
which was visited in the `use-def` chain (when traversing from the
`tensor.insert_slice`'s source).
2024-12-18 23:57:13 +02:00
Christopher Bate
ced2fc7819
[mlir][bufferization] Fix OneShotBufferize when defaultMemorySpaceFn is used (#91524)
As described in issue llvm/llvm-project#91518, a previous PR
llvm/llvm-project#78484 introduced the `defaultMemorySpaceFn` into
bufferization options, allowing one to inform OneShotBufferize that it
should use a specified function to derive the memory space attribute
from the encoding attribute attached to tensor types.

However, introducing this feature exposed unhandled edge cases,
examples of which are introduced by this change in the new test under

`test/Dialect/Bufferization/Transforms/one-shot-bufferize-encodings.mlir`.

Fixing the inconsistencies introduced by `defaultMemorySpaceFn` is
pretty simple. This change:

- Updates the `bufferization.to_memref` and `bufferization.to_tensor`
  operations to explicitly include operand and destination types,
  whereas previously they relied on type inference to deduce the
  tensor types. Since the type inference cannot recover the correct
  tensor encoding/memory space, the operand and result types must be
  explicitly included. This is a small assembly format change, but it
  touches a large number of test files.

- Makes minor updates to other bufferization functions to handle the
  changes in building the above ops.

- Updates bufferization of `tensor.from_elements` to handle memory
  space.


Integration/upgrade guide:

In downstream projects, if you have tests or MLIR files that explicitly
use
`bufferization.to_tensor` or `bufferization.to_memref`, then update
them to the new assembly format as follows:

```
%1 = bufferization.to_memref %0 : memref<10xf32>
%2 = bufferization.to_tensor %1 : memref<10xf32>
```

becomes

```
%1 = bufferization.to_memref %0 : tensor<10xf32> to memref<10xf32>
%2 = bufferization.to_tensor %0 : memref<10xf32> to tensor<10xf32> 
```
2024-11-26 09:45:57 -07:00
Matthias Springer
cbc7802233
[mlir][bufferization] Remove finalizing-bufferize pass (#114154)
The dialect conversion-based bufferization passes have been migrated to
One-Shot Bufferize about two years ago. To clean up the code base, this
commit removes the `finalizing-bufferize` pass, one of the few remaining
parts of the old infrastructure. Most bufferization passes have already
been removed.

Note for LLVM integration: If you depend on this pass, migrate to
One-Shot Bufferize or copy the pass to your codebase.

Depends on #114152.
2024-11-21 10:51:23 +09:00
Matthias Springer
b0a4e958e8
[mlir][bufferization] Add support for non-unique func.return (#114017)
Multiple `func.return` ops inside of a `func.func` op are now supported
during bufferization. This PR extends the code base in 3 places:

- When inferring function return types, `memref.cast` ops are folded
away only if all `func.return` ops have matching buffer types. (E.g., we
don't fold if two `return` ops have operands with different layout
maps.)
- The alias sets of all `func.return` ops are merged. That's because
aliasing is a "may be" property.
- The equivalence sets of all `func.return` ops are taken only if they
match. If different `func.return` ops have different equivalence sets
for their operands, the equivalence information is dropped. That's
because equivalence is a "must be" property.

This commit is in preparation of removing the deprecated
`func-bufferize` pass. That pass can bufferize functions with multiple
`return` ops.
2024-11-13 08:51:39 +09:00
Matthias Springer
c271ba7f79
[mlir][bufferization] Add support for recursive function calls (#114003)
This commit adds support for recursive function calls to One-Shot
Bufferize.

The analysis does not support recursive function calls. The function
body itself can be analyzed, but we cannot make any assumptions about
the aliasing relation between function result and function arguments.
Similarly, when looking at a `call` op, we do not know whether the
operands will bufferize to a memory read/write. In the absence of such
information, we have to conservatively assume that they do.

This commit is in preparation of removing the deprecated
`func-bufferize` pass. That pass can bufferize recursive functions.
2024-11-05 10:18:35 +09:00
Matthias Springer
217700baf7
[mlir][bufferization] Support bufferization of external functions (#113999)
This commit adds support for bufferizing external functions that have no
body. Such functions were previously rejected by One-Shot Bufferize if
they returned a tensor value.

This commit is in preparation of removing the deprecated
`func-bufferize` pass. That pass can bufferize external functions.

Also update a few comments.
2024-10-30 21:49:10 +09:00
Matthias Springer
ea050ab1a9
[mlir][Transforms][NFC] Dialect conversion: Reformat materialization error message (#114176)
This commit changes the format of the materialization error message.

Previously: `failed to legalize unresolved materialization from ('f64')
to 'f32' that remained live after conversion`
Now: `failed to legalize unresolved materialization from ('f64') to
('f32') that remained live after conversion`

This commit is in preparation of merging the 1:1 and 1:N dialect
conversions. At that point, target materializations may create more than
one SSA value. I am sending this change as a separate PR to keep the
main PR smaller.
2024-10-30 21:36:39 +09:00
Andrzej Warzyński
91c11574e8
Revert "[MLIR] Make OneShotModuleBufferize use OpInterface (#110322)" (#113124)
This reverts commit 2026501cf107fcb3cbd51026ba25fda3af823941.

Failing bot:
  * https://lab.llvm.org/staging/#/builders/125/builds/389
2024-10-22 13:28:44 +01:00
Tzung-Han Juang
2026501cf1
[MLIR] Make OneShotModuleBufferize use OpInterface (#110322)
**Description:** 
This PR replaces a part of `FuncOp` and `CallOp` with
`FunctionOpInterface` and `CallOpInterface` in `OneShotModuleBufferize`.
Also fix the error from an integration test in the a previous PR
attempt. (https://github.com/llvm/llvm-project/pull/107295)

The below fixes skip `CallOpInterface` so that the assertions are not
triggered.


8d78000762/mlir/lib/Dialect/Bufferization/Transforms/OneShotModuleBufferize.cpp (L254-L259)


8d78000762/mlir/lib/Dialect/Bufferization/Transforms/OneShotModuleBufferize.cpp (L311-L315)

**Related Discord Discussion:**
[Link](https://discord.com/channels/636084430946959380/642426447167881246/1280556809911799900)

---------

Co-authored-by: erick-xanadu <110487834+erick-xanadu@users.noreply.github.com>
2024-10-01 15:58:52 +02:00
Matthias Springer
ae7b454f98
Revert "[MLIR] Make OneShotModuleBufferize use OpInterface" (#109919)
Reverts llvm/llvm-project#107295

This commit breaks an integration test:
```
build/bin/mlir-opt mlir/test/Integration/Dialect/Complex/CPU/correctness.mlir  -one-shot-bufferize="bufferize-function-boundaries"
```
2024-09-25 09:17:49 +02:00
Tzung-Han Juang
f586b1e3f4
[MLIR] Make OneShotModuleBufferize use OpInterface (#107295)
**Description:** 

`OneShotModuleBufferize` deals with the bufferization of `FuncOp`,
`CallOp` and `ReturnOp` but they are hard-coded. Any custom
function-like operations will not be handled. The PR replaces a part of
`FuncOp` and `CallOp` with `FunctionOpInterface` and `CallOpInterface`
in `OneShotModuleBufferize` so that custom function ops and call ops can
be bufferized.

**Related Discord Discussion:**
[Link](https://discord.com/channels/636084430946959380/642426447167881246/1280556809911799900)

---------

Co-authored-by: erick-xanadu <110487834+erick-xanadu@users.noreply.github.com>
2024-09-25 07:27:21 +02: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
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
Longsheng Mou
7f04a8ad13
[mlir][func][bufferization] Fix cast incompatible when bufferize callOp (#105929)
Handle caller/callee type mismatch using `castOrReallocMemRefValue`
instead of just a `CastOp`. The method insert a reallocation + copy if
it cannot be statically guaranteed that a direct cast would be valid.
Fix #105916.
2024-08-27 07:06:00 +08: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
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
Dennis Filimonov
6de04e6fe8
[mlir][bufferization] Adding the optimize-allocation-liveness pass (#101827)
Adding a pass that is expected to run after the deallocation pipeline
and will move buffer deallocations right after their last user or
dependency, thus optimizing the allocation liveness.
2024-08-14 13:22:47 +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
Christian Ulmann
6a5a64c56b
Revert "[mlir] Fix block merging" (#100510)
Reverts llvm/llvm-project#97697

This commit introduced non-trivial bugs related to type consistency.
2024-07-25 10:42:25 +02:00
Giuseppe Rossini
c63125d453
[mlir] Fix block merging (#97697)
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**: this a rework of #96871 . I ran all the integration tests
(`-DMLIR_INCLUDE_INTEGRATION_TESTS=ON`) and they passed.
2024-07-17 17:05:40 +01:00
donald chen
662c6fc74c
[mlir] [bufferize] fix bufferize deallocation error in nest symbol table (#98476)
In nested symbols, the dealloc_helper function generated by lower
deallocations pass was incorrectly positioned, causing calls fail. This
patch fixes this issue.
2024-07-15 12:52:46 +08:00
Mehdi Amini
28a11cc492
Revert "Fix block merging" (#97460)
Reverts llvm/llvm-project#96871

Bots are broken.
2024-07-02 20:57:16 +02:00
Giuseppe Rossini
6c3897d90e
Fix block merging (#96871)
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
- 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**: many tests are still not passing. But I wanted to submit the
code before changing all the tests (and probably adding a couple), so
that we can agree in principle on the algorithm/design.
2024-07-02 17:12:33 +01:00
zhicong zhong
1d4ce574a4
[mlir][bufferization] skip empty tensor elimination if they have different element type (#96998)
In the origin implementation, the empty tensor elimination will add a
`tensor.cast` and eliminate the tensor even if they have different
element type(f32, bf16). Here add a check for element type and skip the
elimination if they are different.
2024-07-01 09:30:04 +08:00
McCowan Zhang
a159b36724
Bufferization with ControlFlow Asserts (#95868)
Fixed incorrect bufferization interaction with cf.assert
- reordered bufferization condition checking
- fixed hasNeitherAllocateNorFreeSideEffect checking bug
- implemented memory interface for cf.assert

---------

Co-authored-by: McCowan Zhang <mccowan.z@ssi.samsung.com>
2024-06-26 08:00:39 +02:00
Matthias Springer
13896b6ce9
[mlir][bufferization] Fix handling of indirect function calls (#94896)
This commit fixes a crash in the ownership-based buffer deallocation
pass when indirectly calling a function via SSA value. Such functions
must be conservatively assumed to be public.

Fixes #94780.
2024-06-10 08:07:24 +02:00
klensy
f0b0c02504
[mlir][test] Fix filecheck annotation typos (#92897)
Moved fixes for mlir from
https://github.com/llvm/llvm-project/pull/91854, plus few additional in
second commit.

---------

Co-authored-by: klensy <nightouser@gmail.com>
2024-05-24 09:24:59 +02:00