Commit Graph

204 Commits

Author SHA1 Message Date
Alex Zinenko
4b455a71b7 [mlir] adapt TransformEachOpTrait to parameter values
Adapt the implementation of TransformEachOpTrait to the existence of
parameter values recently introduced into the transform dialect. In
particular, allow `applyToOne` hooks to return a list containing a mix
of `Operation *` that will be associated with handles and `Attribute`
that will be associated with parameter values by the trait
implementation of the transform interface's `apply` method.

Disentangle the "transposition" of the list of per-payload op partial
results to decrease its overall complexity and detemplatize the code
that doesn't really need templates. This removes the poorly documented
special handling for single-result ops with TransformEachOpTrait that
could have assigned null pointer values to handles.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D140979
2023-01-06 12:23:41 +00:00
Matthias Springer
5f6d5ca0f8 [mlir][bufferize] Fix tensor copy insertion for dynamic tensors
TensorCopyInsertion inserts bufferization.alloc_tensor ops in case of RaW conflicts. If such a tensor is dynamically shaped, tensor.dim ops are inserted. There is an optimization for ops such as tensor.extract_slice: A copy of the result is created instead of the operand. Afterwards, all uses of the result are updated. E.g.:

```
%0 = tensor.extract_slice ... : tensor<?xf32> to tensor<?xf32>
%1 = tensor.dim %0, %c0 : tensor<?xf32>
%2 = bufferization.alloc_tensor(%dim) : tensor<?xf32>
```

All uses of %0, except for tensor.dim and bufferization.alloc_tensor (if any), should be replaced. Before this change, the use in tensor.dim was also replaced, resulting in IR that had a dominance error.

Note: There is no test case for this fix because the bug cannot be triggered with tensor.extract_slice, which implements an interface to reify result shapes. This bug appeared in an external project with a tensor.extract_slice-like op that does not implement that interface, in which case tensor.dim ops must be created. We do not have such an op in MLIR to trigger this bug.

Differential Revision: https://reviews.llvm.org/D140471
2022-12-21 12:42:02 +01:00
Ramkumar Ramachandra
e8bcc37fff mlir/{SPIRV,Bufferization}: use std::optional in .td files (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional. 22426110c5 changed the way mlir-tblgen generates .inc
files, emitting std::optional when an Optional attribute is specified in
a .td file. It also changed several .td files hard-coding llvm::Optional
to use std::optional. However, the patch excluded a few .td files in
SPIRV and Bufferization hard-coding llvm::Optional. This patch fixes
that defect, and after this patch, references to llvm::Optional in .cpp
and .h files can be replaced mechanically.

See also: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716

Signed-off-by: Ramkumar Ramachandra <r@artagnon.com>

Differential Revision: https://reviews.llvm.org/D140329
2022-12-20 09:23:58 +01:00
Lorenzo Chelini
e7d0cc76d7 [MLIR][Bufferization] Introduce EmptyTensorToAllocTensorOp
Introduce a new transform operation to replace `tensor.empty` with
`alloc_tensor` operations. The operation is a pass-through if the target
operation is already a `alloc_tensor`; otherwise, it expects a
`tensor.empty` as a target. Currently, it does not return any results.

The operation is expected to run before `one_shot_bufferize` as
`one_shot_bufferize` rejects `tensor.empty`.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D140026
2022-12-19 09:12:10 +01:00
Ramkumar Ramachandra
22426110c5 mlir/tblgen: use std::optional in generation
This is part of an effort to migrate from llvm::Optional to
std::optional. This patch changes the way mlir-tblgen generates .inc
files, and modifies tests and documentation appropriately. It is a "no
compromises" patch, and doesn't leave the user with an unpleasant mix of
llvm::Optional and std::optional.

A non-trivial change has been made to ControlFlowInterfaces to split one
constructor into two, relating to a build failure on Windows.

See also: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716

Signed-off-by: Ramkumar Ramachandra <r@artagnon.com>

Differential Revision: https://reviews.llvm.org/D138934
2022-12-17 11:13:26 +01:00
Matthias Springer
ae05bd99d3 [mlir][bufferize][NFC] Add statistics to OneShotBufferizePass
Print statistics about the number of alloc/deallocs and in-place/out-of-place bufferization.

Differential Revision: https://reviews.llvm.org/D139538
2022-12-15 18:02:51 +01:00
Matthias Springer
1742882a34 [mlir][bufferize] Fix typo in EmptyTensorElimination
The structure of the code has changed a while ago and the code was not updated properly.

There is no test case for this because we do currently not have an op
that could trigger this bug.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D139838
2022-12-12 14:31:38 +01:00
Matthias Springer
be630f07de [mlir][bufferize] Implement BufferizableOpInterface for tensor.empty
The op is not bufferizable but should be analyzable (for `EliminateEmptyTensors`, which uses the bufferization infrastructure).

Also improve debugging functionality and error messages.

Also adds a missing pass to the sparse pipeline. (tensor.empty should be replaced with bufferization.alloc_tensor, but it sometimes used to work without depending on how the tensor.empty is used. Now we always fail explicitly.)
2022-12-12 14:19:38 +01:00
Matthias Springer
4002eaaa01 [mlir][bufferize] Improve analysis of external functions
External functions have no body, so they cannot be analyzed. Assume conservatively that each tensor bbArg may be aliasing with each tensor result. Furthermore, assume that each function arg is read and written-to after bufferization. This default behavior can be controlled with `bufferization.access` (similar to `bufferization.memory_layout`) in test cases.

Also fix a bug in the dialect attribute verifier, which did not run for region argument attributes.

Differential Revision: https://reviews.llvm.org/D139517
2022-12-09 14:36:33 +01:00
Matthias Springer
5d04f0c937 [mlir][bufferize] Update remaining getMemorySpaceAsInt API uses
D138330 updated the deprecated `getMemorySpaceAsInt` uses to `getMemorySpace`. There are few uses that were missed.

Differential Revision: https://reviews.llvm.org/D139526
2022-12-07 12:28:14 +01:00
Matthias Springer
0abf513d0f [mlir][bufferize] Support parallel_insert_slice in EmptyTensorElimination
Differential Revision: https://reviews.llvm.org/D139431
2022-12-07 11:39:12 +01:00
Kazu Hirata
1a36588ec6 [mlir] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 18:50:27 -08:00
Peiming Liu
c7a9e5e5d2 [mlir][sparse][bufferization] cleanup bufferization attributes after SparsificationAndBufferizationPass
Reviewed By: aartbik, springerm

Differential Revision: https://reviews.llvm.org/D139218
2022-12-02 23:03:54 +00:00
River Riddle
b74192b7ae [mlir] Remove support for non-prefixed accessors
This finishes off a year long pursuit to LLVMify the generated
operation accessors, prefixing them with get/set. Support for
any other accessor naming is fully removed after this commit.

https://discourse.llvm.org/t/psa-raw-accessors-are-being-removed/65629

Differential Revision: https://reviews.llvm.org/D136727
2022-12-02 13:32:36 -08:00
Matthias Springer
c1fef4e88a [mlir][bufferization] Make TensorCopyInsertionPass a test pass
TensorCopyInsertion should not have been exposed as a pass. This was a flaw in the original design. It is a preparation step for bufferization and certain transforms (that would otherwise be legal) are illegal between TensorCopyInsertion and actual rewrite to MemRef ops. Therefore, even if broken down as two separate steps internally, they should be exposed as a single pass.

This change affects the sparse compiler, which uses `TensorCopyInsertionPass`. A new `SparsificationAndBufferizationPass` is added to replace all passes in the sparse tensor pipeline from `TensorCopyInsertionPass` until the actual bufferization (rewrite to memref/non-tensor). It is generally unsafe to run arbitrary passes in-between, in particular passes that hoist tensor ops out of loops or change SSA use-def chains along tensor ops.

Differential Revision: https://reviews.llvm.org/D138915
2022-12-02 15:38:02 +01:00
Matthias Springer
c069feb89c [mlir][bufferize] Improve error message when returning allocs
The previous error message was confusing. Also improve code documentation and some minor code cleanups.

Differential Revision: https://reviews.llvm.org/D138902
2022-11-30 09:28:12 +01:00
Matthias Springer
7cdfc843b5 [mlir][bufferize][NFC] Minor code and comment cleanups
Differential Revision: https://reviews.llvm.org/D135056
2022-11-22 17:04:09 +01:00
Matthias Springer
faa9be75ee [mlir][bufferize][NFC] Rename DialectAnalysisState and move to OneShotAnalysis
`DialectAnalysisState` is now `OneShotAnalysisState::Extension`.

This state extension mechanism is needed only for One-Shot Analysis, so it is moved from `BufferizableOpInterface.h` to `OneShotAnalysis.h`.

Extensions are now identified via TypeIDs instead of StringRefs. The API of state extensions is cleaned up and follows the same pattern as other extension mechanisms in MLIR (e.g., `transform::TransformState::Extension`).

Also delete some dead code.

Differential Revision: https://reviews.llvm.org/D135051
2022-11-22 14:34:55 +01:00
Lei Zhang
9bb633741a [mlir][bufferization] Support general Attribute as memory space
MemRef has been accepting a general Attribute as memory space for
a long time. This commits updates bufferization side to catch up,
which allows downstream users to plugin customized symbolic memory
space. This also eliminates quite a few `getMemorySpaceAsInt`
calls, which is deprecated.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D138330
2022-11-21 09:40:50 -05:00
Aliia Khasanova
399638f98c Merge kDynamicSize and kDynamicSentinel into one constant.
resolve conflicts

Differential Revision: https://reviews.llvm.org/D138282
2022-11-21 13:01:26 +00:00
Mahesh Ravishankar
fc367dfa67 [mlir] Remove Transforms/SideEffectUtils.h and move the methods into Interface/SideEffectInterfaces.h.
The methods in `SideEffectUtils.h` (and their implementations in
`SideEffectUtils.cpp`) seem to have similar intent to methods already
existing in `SideEffectInterfaces.h`. Move the decleration (and
implementation) from `SideEffectUtils.h` (and `SideEffectUtils.cpp`)
into `SideEffectInterfaces.h` (and `SideEffectInterface.cpp`).

Also drop the `SideEffectInterface::hasNoEffect` method in favor of
`mlir::isMemoryEffectFree` which actually recurses into the operation
instead of just relying on the `hasRecursiveMemoryEffectTrait`
exclusively.

Differential Revision: https://reviews.llvm.org/D137857
2022-11-15 20:07:35 +00:00
Lorenzo Chelini
c780184a84 [MLIR][Transform] Expose map layout option in OneShotBufferizeOp
Expose `function-boundary-type-conversion` in `OneShotBufferizeOp`. To
reuse options between passes and transform operations, create a
`BufferizationEnums.td`.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D137833
2022-11-14 18:09:54 +01:00
Matthias Springer
28b2f79215 [mlir][bufferize][NFC] Consolidate transform header files
Differential Revision: https://reviews.llvm.org/D137830
2022-11-11 14:33:23 +01:00
Matthias Springer
e62681e70a [mlir][bufferize] Eliminate tensor.empty ops instead of bufferization.alloc_tensor ops
tensor.empty op elimination is an optimization that brings IR in a more bufferization-friendly form. E.g.:

```
%0 = tensor.empty()
%1 = linalg.fill(%cst, %0) {inplace = [true]}
%2 = tensor.insert_slice %1 into %t[10][20][1]
```

Is rewritten to:

```
%0 = tensor.extract_slice %t[10][20][1]
%1 = linalg.fill(%cst, %0) {inplace = [true]}
%2 = tensor.insert_slice %1 into %t[10][20][1]
```

This optimization used to operate on bufferization.alloc_tensor ops. This is not correct because the documentation of bufferization.alloc_tensor says that it always bufferizes to an allocation. Instead, this optimization should operate on tensor.empty ops, which can then be lowered to bufferization.alloc_tensor ops (if they don't get eliminated).

Differential Revision: https://reviews.llvm.org/D137162
2022-11-11 11:39:18 +01:00
bixia1
26ef3868c5 [mlir][sparse] Add optional size_hint operand to bufferization.alloc_tensor.
Reviewed By: aartbik

Differential Revision: https://reviews.llvm.org/D137585
2022-11-09 16:19:49 -08:00
Emilio Cota
7e133eb49b [mlir][bufferize] Add filterFn option to BufferResultsToOutParams
This allows users to restrict the transformation to a
subset of the functions in a module.

For example, a user might want to apply the transformation to
a module's entry point, but not to the calls in the module
because those calls might refer to external C functions outside
of their control.

Reviewed By: springerm, nicolasvasilache
Differential Revision: https://reviews.llvm.org/D137264
2022-11-03 13:01:39 -04:00
Matthias Springer
e0b40af722 [mlir][bufferize][NFC] Better debug output for One-Shot Analysis
Run mlir-opt with `-debug-only="one-shot-analysis"` for detailed debug output.

Differential Revision: https://reviews.llvm.org/D135549
2022-10-31 11:09:23 +01:00
Matthias Springer
df23ede2f1 [mlir][bufferize][NFC] Debug output during bufferization
When running with `-debug`, print the IR after bufferizing each op.

Differential Revision: https://reviews.llvm.org/D137065
2022-10-31 10:26:26 +01:00
Matthias Springer
2d5edc644d [mlir][bufferize] Provide default BufferizableOpInterface impl for destination style ops
tensor.insert and tensor.insert_slice (as destination style ops) do no longer need to implement the entire BufferizableOpInterface.

Differential Revision: https://reviews.llvm.org/D136347
2022-10-27 10:52:47 +02:00
Matthias Springer
1b99f3a224 [mlir][bufferize] Treat certain aliasing-only uses like memory reads
This fixes an issue in One-Shot Bufferize that could lead to missing buffer copies in the future. This bug can currently not be triggered because of the order in which ops are analyzed (always bottom-to-top). However, if we consider different traversal orders for the analysis in the future, this bug can cause subtle issues that are difficult to debug.

Example:
```
%0 = ...
%1 = tensor.insert ... into %0
%2 = tensor.extract_slice %0
tensor.extract %2[...]
```

In case of a top-to-bottom analysis of the above IR, the `tensor.insert` is analyzed before the `tensor.extract_slice`. In that case, the `tensor.insert` will bufferize in-place because %2 is not yet known to become an alias of %0 (and therefore causing a conflict).

With this change, the `tensor.insert` will bufferize out-of-place, regardless of the traversal order.

Differential Revision: https://reviews.llvm.org/D135049
2022-10-14 10:40:45 +09:00
Mehdi Amini
0666e50e14 Apply clang-tidy fixes for modernize-use-equals-default in Bufferize.cpp (NFC) 2022-10-10 01:08:27 +00:00
Matthias Springer
1f8ffbd1cc [mlir][bufferize][NFC] Address review comments of D135420
These changes should have been landed as part of D135420.

Differential Revision: https://reviews.llvm.org/D135438
2022-10-07 19:54:08 +09:00
Matthias Springer
2e210034da [mlir][bufferize] Fix repetitive region conflict detection
This fixes a bug where a required buffer copy was not inserted.

Not only written aliases, but also read aliases should be taken into account when computing common enclosing repetitive regions. Furthermore, for writing ops, it does not matter where the destination tensor is defined, but where the op itself is located.

Differential Revision: https://reviews.llvm.org/D135420
2022-10-07 16:39:03 +09:00
Matthias Springer
f4e8f44811 [mlir][bufferize] Fix enclosing repetitive region computation
The wrong function overload was called.

Differential Revision: https://reviews.llvm.org/D135342
2022-10-07 10:37:04 +09:00
Matthias Springer
6cdd34b973 [mlir][tensor][bufferize] Bufferize inserts into equivalent tensors in-place
Inserting a tensor into an equivalent tensor is a no-op after bufferization. No alloc is needed.

Differential Revision: https://reviews.llvm.org/D132662
2022-10-06 15:06:33 +09:00
Matthias Springer
129420df51 [mlir][bufferization][NFC] Move EmptyTensorToAllocTensorPass
This change moves the pass from the Linalg dialect to the bufferization dialect.

Differential Revision: https://reviews.llvm.org/D135130
2022-10-05 09:57:22 +09:00
Jakub Kuderski
abc362a107 [mlir][arith] Change dialect name from Arithmetic to Arith
Suggested by @lattner in https://discourse.llvm.org/t/rfc-define-precise-arith-semantics/65507/22.

Tested with:
`ninja check-mlir check-mlir-integration check-mlir-mlir-spirv-cpu-runner check-mlir-mlir-vulkan-runner check-mlir-examples`

and `bazel build --config=generic_clang @llvm-project//mlir:all`.

Reviewed By: lattner, Mogball, rriddle, jpienaar, mehdi_amini

Differential Revision: https://reviews.llvm.org/D134762
2022-09-29 11:23:28 -04:00
Alex Zinenko
f096e72ce6 [mlir] switch bufferization to use strided layout attribute
Bufferization already makes the assumption that buffers pass function
boundaries in the strided form and uses the corresponding affine map layouts.
Switch it to use the recently introduced strided layout instead to avoid
unnecessary casts when bufferizing further operations to the memref dialect
counterparts that now largely rely on the strided layout attribute.

Depends On D133947

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D133951
2022-09-16 10:56:50 +02:00
Matthias Springer
f7dd9a3206 [mlir][bufferize] Add new debug flag: copy-before-write
If this flag is set, the analysis is skipped and buffers are copied before every write.

Differential Revision: https://reviews.llvm.org/D133288
2022-09-05 14:41:19 +02:00
Matthias Springer
f7f0c7f7e3 [mlir][bufferize] Add isRepetitiveRegion to BufferizableOpInterface
This method allows to declare regions as "repetitive" even if the parent op does not implement the RegionBranchOpInterface.

This is needed to support loop-like ops that have parallel semantics but do not branch between regions.

Differential Revision: https://reviews.llvm.org/D133113
2022-09-02 14:47:20 +02:00
Michele Scuttari
67d0d7ac0a [MLIR] Update pass declarations to new autogenerated files
The patch introduces the required changes to update the pass declarations and definitions to use the new autogenerated files and allow dropping the old infrastructure.

Reviewed By: mehdi_amini, rriddle

Differential Review: https://reviews.llvm.org/D132838
2022-08-31 12:28:45 +02:00
Michele Scuttari
039b969b32 Revert "[MLIR] Update pass declarations to new autogenerated files"
This reverts commit 2be8af8f0e.
2022-08-30 22:21:55 +02:00
Michele Scuttari
2be8af8f0e [MLIR] Update pass declarations to new autogenerated files
The patch introduces the required changes to update the pass declarations and definitions to use the new autogenerated files and allow dropping the old infrastructure.

Reviewed By: mehdi_amini, rriddle

Differential Review: https://reviews.llvm.org/D132838
2022-08-30 21:56:31 +02:00
Matthias Springer
123c4b0251 [mlir][SCF][bufferize] Support different iter_arg/init_arg types (scf.for)
Even though iter_arg and init_arg of an scf.for loop may have the same tensor type, their bufferized memref types are not necessarily equal. It is sometimes necessary to insert a cast in case of differing layout maps.

Differential Revision: https://reviews.llvm.org/D132860
2022-08-30 16:35:32 +02:00
Matthias Springer
111c919665 [mlir][bufferization] Generalize getBufferType
This change generalizes getBufferType. This function can be used to predict the buffer type of any tensor value (not just BlockArguments) without changing any IR. It also subsumes getMemorySpace. This is useful for loop bufferization, where the precise buffer type of an iter_arg cannot be known without examining the loop body.

Differential Revision: https://reviews.llvm.org/D132859
2022-08-30 16:26:44 +02:00
Johannes Reifferscheid
23dec4a352 Move BufferViewFlowAnalysis to the Bufferization dialect.
It's only used from there, and this lets us remove the dependency from Analysis
to the Arith dialect.

Reviewed By: springerm

Differential Revision: https://reviews.llvm.org/D132928
2022-08-30 14:25:49 +02:00
Matthias Springer
9ee12f4778 [mlir][tensor][bufferize] Bufferize tensor.pad
tensor.pad is lowered to tensor.generate + tensor.insert_slice during bufferization. For best performance with constant padding values, users should vectorize the IR before bufferizing it.

This change also relaxes tje restriction that no new ops that bufferize to a memory write should be added during bufferization. Since bufferization has been split into two steps a while ago (tensor copy insertion + bufferization), it is reasonable to allow this now.

Differential Revision: https://reviews.llvm.org/D132355
2022-08-22 17:00:33 +02:00
Kazu Hirata
258531b7ac Remove redundant initialization of Optional (NFC) 2022-08-20 21:18:28 -07:00
Matthias Springer
3f914d84c3 [mlir][bufferize] Better error handling: Fail if ToMemrefOps are found
bufferization.to_memref ops are not supported in One-Shot Analysis. They often trigger a failed assertion that can be confusing. Instead, scan for to_memref ops before running the analysis and immediately abort with a proper error message.

Differential Revision: https://reviews.llvm.org/D132027
2022-08-18 11:37:57 +02:00
root
894e8a5446 [MLIR] Add dealloc alias check to bufferization
Traverse the cloneOp for aliases to find the alloc op

Reviewed By: frgossen, bondhugula

Differential Revision: https://reviews.llvm.org/D131797
2022-08-17 19:11:59 -04:00