62 Commits

Author SHA1 Message Date
Nicolas Vasilache
aafb52d7c9 [mlir][GPUTransforms] NFC - Refactor GPUTransforms.cpp in preparation for improvements.
Depends on: D145977

Differential Revision: https://reviews.llvm.org/D145980
2023-03-14 05:00:01 -07:00
Matthias Springer
42c31d8302 [mlir][IR] Clean up mergeBlockBefore and mergeBlocks
* `RewriterBase::mergeBlocks` is simplified: it is implemented in terms of `mergeBlockBefore`.
* The signature of `mergeBlockBefore` is consistent with other API (such as `inlineRegionBefore`): an overload for a `Block::iterator` is added.
* Additional safety checks are added to `mergeBlockBefore`: detect cases where the resulting IR could be invalid (no more `dropAllUses`) or partly unreachable (likely a case of incorrect API usage).
* Rename `mergeBlockBefore` to `inlineBlockBefore`.

Differential Revision: https://reviews.llvm.org/D144969
2023-03-06 13:46:08 +01:00
Jacques Pienaar
bbda411f0e [mlir][scf] Relax type requirement on for
scf.for loop was restricted to only operate on Index type since
splitting out from affine.for. Relax requirement to allow for signless
integer types additionally. This allows specifying explicitly different
bitwidths for different loops as well as specialize from index to iN
while still using scf.for.

Differential Revision: https://reviews.llvm.org/D145288
2023-03-05 07:37:58 -08:00
Nicolas Vasilache
c888a0ce88 [mlir][MemRef] Rewrite multi-buffering with proper composable abstractions
Rewrite and document multi-buffering properly:
1. Use IndexingUtils / StaticValueUtils instead of duplicating functionality
2. Properly plumb RewriterBase through.
3. Add support
4. Better debug messages.

This revision is otherwise almost NFC, if it weren't for the extra DeallocOp
support that would previoulsy make multi-buffering fail.

Depends on: D145036

Differential Revision: https://reviews.llvm.org/D145055
2023-03-01 07:25:31 -08:00
Frederik Gossen
e7b52c46bf [MLIR] Add primitive builders for scf.if
Differential Revision: https://reviews.llvm.org/D144886
2023-02-27 13:53:39 -05:00
Matthias Springer
61f3775804 [mlir][SCF] Fix incorrect API usage in RewritePatterns
Incorrect API usage was detected by D144552.

Differential Revision: https://reviews.llvm.org/D144636
2023-02-27 09:36:14 +01:00
Alexander Belyaev
a5cdcf49b2 [mlir] Fix folding for scf.for(tensor.cast).
We should only fold tensor.casts that provide some new static information about
shapes, instead of looking for a symmetric pattern cast(for(cast)).

Differential Revision: https://reviews.llvm.org/D144577
2023-02-23 11:23:11 +01:00
Kazu Hirata
9e5d2495ac Use APInt::isOne instead of APInt::isOneValue (NFC)
Note that isOneValue has been soft-deprecated in favor of isOne.
2023-02-19 23:06:36 -08:00
Alexander Belyaev
cdf8f06469 [mlir] Add a folder for lbs, ubs, steps of scf.forall.
Differential Revision: https://reviews.llvm.org/D144245
2023-02-17 11:01:13 +01:00
Alexander Belyaev
eb2f946e78 [mlir][scf] Rename ForeachThreadOp->ForallOp, PerformConcurrentlyOp->InParallelOp.
Differential Revision: https://reviews.llvm.org/D144242
2023-02-17 09:59:39 +01:00
Alexander Belyaev
310deca248 [mlir] Add loop bounds to scf.foreach_thread.
https://discourse.llvm.org/t/rfc-parallel-loops-on-tensors-in-mlir/68332

Differential Revision: https://reviews.llvm.org/D144072
2023-02-17 08:57:52 +01:00
Ingo Müller
b716bf84ea [mlir][scf] Fix builder of WhileOp with region builder arguments.
The overload of WhileOp::build with arguments for builder functions for
the regions of the op was broken: It did not compute correctly the types
(and locations) of the region arguments, which lead to failed assertions
when the result types were different from the operand types.
Specifically, it used the result types (and operand locations) for *both*
regions, instead of the operand types (and locations) for the 'before'
region and the result types (and loecations) for the 'after' region.

Reviewed By: Mogball, mehdi_amini

Differential Revision: https://reviews.llvm.org/D142952
2023-02-07 13:40:54 +00:00
Frederik Gossen
1125c5c0b2 [MLIR] Remove scf.if builder with explicit result types and callbacks
Instead, use the builder and infer the return type based on the inner `yield` ops.
Also, fix uses that do not create the terminator as required for the callback builders.

Differential Revision: https://reviews.llvm.org/D142056
2023-01-20 10:52:08 -05:00
Frederik Gossen
029f1a4efd [MLIR] Address post-submit comments on scf.if's InferTypeOpInterface
Differential Revision: https://reviews.llvm.org/D142155
2023-01-20 10:37:25 -05:00
Mehdi Amini
a47819345d Remove useless / untested verifier in scf.foreach_thread (NFC) 2023-01-19 19:54:10 +00:00
Frederik Gossen
7f66e1833f [MLIR] Add InferTypeOpInterface to scf.if op
Differential Revision: https://reviews.llvm.org/D142049
2023-01-19 13:19:50 -05:00
Frederik Gossen
d2f136920b [MLIR] Add return type inference to scf.if builder
Differential Revision: https://reviews.llvm.org/D141928
2023-01-17 14:09:22 -05:00
Mehdi Amini
9d7da415d2 Fix crash in scf.parallel verifier
Fixes #59989

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D141911
2023-01-17 16:21:28 +00:00
Mehdi Amini
4cef3f2232 Fix scf.while verifier crash (NFC)
Harden the verifier against invalid IR.
2023-01-14 01:27:38 +00:00
Jeff Niu
4d67b27817 [mlir] Add operations to BlockAndValueMapping and rename it to IRMapping
The patch adds operations to `BlockAndValueMapping` and renames it to `IRMapping`. When operations are cloned, old operations are mapped to the cloned operations. This allows mapping from an operation to a cloned operation. Example:

```
Operation *opWithRegion = ...
Operation *opInsideRegion = &opWithRegion->front().front();

IRMapping map
Operation *newOpWithRegion = opWithRegion->clone(map);
Operation *newOpInsideRegion = map.lookupOrNull(opInsideRegion);
```

Migration instructions:
All includes to `mlir/IR/BlockAndValueMapping.h` should be replaced with `mlir/IR/IRMapping.h`. All uses of `BlockAndValueMapping` need to be renamed to `IRMapping`.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D139665
2023-01-12 13:16:05 -08:00
Markus Böck
7df761217c [mlir][NFC] Migrate rest of the dialects to the new fold API 2023-01-11 21:47:25 +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
Mehdi Amini
cffd7b144b [mlir][scf] Fixes IndexSwitchOp verifier crash
Fixes #59460
2022-12-13 09:42:34 +00:00
Kazu Hirata
70c73d1b72 [mlir] Use std::nullopt instead of None in comments (NFC)
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-04 17:23:50 -08: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
Christian Sigg
be065c41d8 [mlir] Change scf::LoopNest to store 'results'.
This fixes the case where scf::LoopNest::loops is empty.

Change LoopVector and ValueVector to SmallVector.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D136926
2022-12-01 06:51:45 +01:00
Matthias Springer
0d9761d50e [mlir][SCF] Add tensor.dim(scf.foreach_thread) folding
Dim sizes of `scf.foreach_thread` op results match the dim sizes of their respective tied shared_outs operands.

Differential Revision: https://reviews.llvm.org/D138484
2022-11-22 11:28:27 +01:00
Mohammed Anany
77533d79f7 [mlir][SCF] Adding custom builder to SCF::WhileOp.
This is a similar builder to the one for SCF::IfOp which allows users to pass region builders to it. Refer to the builders for IfOp.

Reviewed By: tpopp

Differential Revision: https://reviews.llvm.org/D137709
2022-11-15 18:16:49 +01:00
Nicolas Vasilache
f0a411da77 [mlir][Transform]Significantly cleanup scf.foreach_thread and GPU transform permutation handling
Previously, the need for a dense permutation leaked into the thread_dim_mapping specification.
This revision allows to use a sparse specification of the thread_dim_mapping and the proper completion / sorting is applied automatically.

In the process, the sematics of scf.foreach_thread is tightened to require a matching number of thread dimensions and mappings.
The relevant negative test is added.

Differential Revision: https://reviews.llvm.org/D137906
2022-11-14 09:19:49 -08:00
Alexander Belyaev
07665e78cb [mlir] Fix forward the fix for incorrect Optional<ArrayAttr> usage. 2022-11-11 10:53:04 +01:00
Alexander Belyaev
b7162e136e [mlir] Fix incorrect access to the Optional<ArrayAttr> underlying values. 2022-11-11 10:46:04 +01:00
Guray Ozen
6663f34704 [mlir] Introduce device mapper attribute for thread_dim_map and mapped to dims
`scf.foreach_thread` defines mapping its loops to processors via an integer array, see an example below. A lowering can use this mapping. However, expressing mapping as an integer array is very confusing, especially when there are multiple levels of parallelism. In addition, the op does not verify the integer array. This change introduces device mapping attribute to make mapping descriptive and verifiable. Then it makes GPU transform dialect use it.

```
scf.foreach_thread (%i, %j) in (%c1, %c2) {
	scf.foreach_thread (%i2, %j2) in (%c1, %c2)
	{...} { thread_dim_mapping = [0, 1]}
} { thread_dim_mapping = [0, 1]}
```

It first introduces a `DeviceMappingInterface` which is an attribute interface. `scf.foreach_thread` defines its mapping via this interface. A lowering must define its attributes and implement this interface as well. This way gives us a clear validation.

The change also introduces two new attributes (`#gpu.thread<x/y/z>` and `#gpu.block<x,y,z>` ). After this change, the above code prints as below, as seen here, this way clarifies the loop mappings. The change also implements consuming of these two new attribute by the transform dialect. Transform dialect binds the outermost loops to the thread blocks and innermost loops to threads.

```
scf.foreach_thread (%i, %j) in (%c1, %c2) {
	scf.foreach_thread (%i2, %j2) in (%c1, %c2)
	{...} { thread_dim_mapping = [#gpu.thread<x>, #gpu.thread<y>]}
} { thread_dim_mapping = [#gpu.block<x>, #gpu.block<y>]}
```

Reviewed By: ftynse, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D137413
2022-11-11 08:44:57 +01:00
Mehdi Amini
34233d4995 Apply clang-tidy fixes for readability-redundant-smartptr-get in SCF.cpp (NFC) 2022-11-09 00:41:30 +00:00
Mehdi Amini
f5865c8701 Apply clang-tidy fixes for llvm-qualified-auto in SCF.cpp (NFC) 2022-11-09 00:41:30 +00:00
Kazu Hirata
585e35a998 [mlir] Use llvm::is_contained (NFC) 2022-11-06 19:56:15 -08:00
Sanjoy Das
788390c130 Make scf.for and affine.for conditionally speculatable
for (I = Start; I < End; I += 1) always terminates so mark
{scf|affine}.for as RecursivelySpeculatable when step is known to be
1.

Reviewed By: chelini

Differential Revision: https://reviews.llvm.org/D136376
2022-10-30 16:08:42 -07:00
Jeff Niu
07d8fe9391 [mlir][scf] Add an IndexSwitchOp
The `scf.index_switch` is a control-flow operation that branches to one of the
given regions based on the values of the argument and the cases. The
argument is always of type `index`.

Example:

```mlir
%0 = scf.index_switch %arg0 -> i32
case 2 {
  %1 = arith.constant 10 : i32
  scf.yield %1 : i32
}
case 5 {
  %2 = arith.constant 20 : i32
  scf.yield %2 : i32
}
default {
  %3 = arith.constant 30 : i32
  scf.yield %3 : i32
}
```

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D136003
2022-10-21 09:21:10 -07:00
Jeff Niu
6005a1d8af [mlir][scf] Match any constants instead of arith.constant
By matching `arith.constant` specifically, SCF canonicalizers/folders
are incompatible with other kinds of constants. Use the generic
matchers instead.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D135517
2022-10-12 18:01:57 -07: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
Peiming Liu
52887071ea [mlir][scf] Support simple symbolic expression without depending on AffineDialect to simply trivial loops.
Remove dependence of AffineDialect

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D134291
2022-09-20 18:13:05 +00:00
Peiming Liu
d518fc28b6 [mlir][scf] Support simple symbolic expression when simplify loops
Reviewed By: aartbik, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D134204
2022-09-19 21:50:01 +00:00
Guray Ozen
233de4e808 [mlir] Add map_nested_foreach_thread_to_gpu_threads op to transform dialect
This revision adds a new op `map_nested_foreach_thread_to_gpu_threads` to transform dialect. The op searches `scf.foreach_threads` inside the `gpu_launch` and distributes them with `gpu.thread_id` attribute.

Loop mapping is explicit and given by the `map_nested_foreach_thread_to_gpu_threads` op. Mapping is done one-to-one, therefore the loops dissappear.

The dynamic trip count or trip count that are larger than thread size are not supported for the time being. However, we can indeed support them by generating a loop inside with cyclic scheduling.

For the time being, trip counts that are dynamic or bigger than thread sizes are not supported. However, in the future the compiler can indeed generate a loop with static cyclic scheduling to support these cases.

Current mechanism allows `scf.foreach_threads` to be siblings or nested. There cannot be interleaving code between the loops when they are nested.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D133950
2022-09-19 16:27:30 +02:00
Matthias Springer
4cd7362083 [mlir][SCF] foreach_thread: Capture shared output tensors explicitly
This change refines the semantics of scf.foreach_thread. Tensors that are inserted into in the terminator must now be passed to the region explicitly via `shared_outs`. Inside of the body of the op, those tensors are then accessed via block arguments.

The body of a scf.foreach_thread is now treated as a repetitive region. I.e., op dominance can no longer be used in conflict detection when using a value that is defined outside of the body. Such uses may now be considered as conflicts (if there is at least one read and one write in the body), effectively privatizing the tensor. Shared outputs are not privatized when they are used via their corresponding block arguments.

As part of this change, it was also necessary to update the "tiling to scf.foreach_thread", such that the generated tensor.extract_slice ops use the scf.foreach_thread's block arguments. This is implemented by cloning the TilingInterface op inside the scf.foreach_thread, rewriting all of its outputs with block arguments and then calling the tiling implementation. Afterwards, the cloned op is deleted again.

Differential Revision: https://reviews.llvm.org/D133114
2022-09-02 14:54:04 +02:00
Jeff Niu
27e8ee208c [mlir] Remove a not very useful eraseArguments overload
This overload just wraps a bitvector, and in most cases a bitvector
could be used directly instead of a list.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D132896
2022-08-29 16:07:32 -07:00
Jeff Niu
58a47508f0 (Reland) [mlir] Switch segment size attributes to DenseI32ArrayAttr
This reland includes changes to the Python bindings.

Switch variadic operand and result segment size attributes to use the
dense i32 array. Dense integer arrays were introduced primarily to
represent index lists. They are a better fit for segment sizes than
dense elements attrs.

Depends on D131801

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D131803
2022-08-12 19:44:52 -04:00
Alex Zinenko
e8e718fa4b Revert "[mlir] Switch segment size attributes to DenseI32ArrayAttr"
This reverts commit 30171e76f0e5ea8037bc4d1450dd3e12af4d9938.

Breaks Python tests in MLIR, missing C API and Python changes.
2022-08-12 10:22:47 +02:00
Jeff Niu
30171e76f0 [mlir] Switch segment size attributes to DenseI32ArrayAttr
Switch variadic operand and result segment size attributes to use the
dense i32 array. Dense integer arrays were introduced primarily to
represent index lists. They are a better fit for segment sizes than
dense elements attrs.

Depends on D131738

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D131702
2022-08-11 20:56:45 -04:00
Benjamin Kramer
9fa59e7643 [mlir] Use C++17 structured bindings instead of std::tie where applicable. NFCI 2022-08-09 13:34:17 +02:00
Kazu Hirata
c8e6ebd74e Use value instead of getValue (NFC) 2022-08-06 11:21:39 -07:00
Kazu Hirata
9750648cb4 [mlir, flang] Use has_value instead of hasValue (NFC) 2022-08-06 11:12:47 -07:00