51 Commits

Author SHA1 Message Date
Maya Amrami
e138c95155
[mlir] ViewLikeInterface - verify ranks in verifyOffsetSizeAndStrideOp (#147926)
getMixedOffsets() calls getMixedValues() with `static_offsets` and
`offsets`. It is assumed that the number of dynamic offsets in
`static_offsets` equals the rank of `offsets`. Otherwise, we fail on
assert when trying to access an array out of its bounds.
The same applies to getMixedStrides() and getMixedOffsets().

A verification of this assumption is added to
verifyOffsetSizeAndStrideOp() and a clear assert is added in
getMixedValues().
2025-07-20 14:20:16 +03:00
Jakub Kuderski
6512ca7ddb
[mlir] Add isStatic* size check for ShapedTypes. NFCI. (#147085)
The motivation is to avoid having to negate `isDynamic*` checks, avoid
double negations, and allow for `ShapedType::isStaticDim` to be used in
ADT functions without having to wrap it in a lambda performing the
negation.

Also add the new functions to C and Python bindings.
2025-07-07 14:57:27 -04:00
Kazu Hirata
85480a4d37
[mlir] Directly call ShapedType::isDynamic without lambdas (NFC) (#142994)
We do not need lambdas in these places.
2025-06-05 16:14:27 -07:00
Matthias Springer
529ee3cf3b
[mlir][tensor] Fix slice canonicalizer for out-of-bounds cases (#132534)
Since #130487, `tensor.extract_slice` and `tensor.insert_slice` ops that
are statically detected to go out of bounds are rejected by the
verifier.

This commit fixes canonicalization patterns that currently fold
dynamically out-of-bounds ops (valid IR) to statically out-of-bounds ops
(invalid IR).
2025-03-24 14:39:37 +01:00
Diego Caballero
ef4800c916
[mlir][Interfaces][NFC] Update doc of ViewLikeOpInterface parser/printer handlers (#122555)
This PR addresses part of the feedback provided in #115808.
2025-01-14 17:58:52 -08:00
srcarroll
2c1c67674c
[mlir][transform] Consistent linalg transform op syntax for dynamic index lists (#90897)
This patch is a first pass at making consistent syntax across the
`LinalgTransformOp`s that use dynamic index lists for size parameters.
Previously, there were two different forms: inline types in the list, or
place them in the functional style tuple. This patch goes for the
latter.

In order to do this, the `printPackedOrDynamicIndexList`,
`printDynamicIndexList` and their `parse` counterparts were modified so
that the types can be optionally provided to the corresponding custom
directives.

All affected ops now use tablegen `assemblyFormat`, so custom
`parse`/`print` functions have been removed. There are a couple ops that
will likely add dynamic size support, and once that happens it should be
made sure that the assembly remains consistent with the changes in this
patch.

The affected ops are as follows: `pack`, `pack_greedily`,
`tile_using_forall`. The `tile_using_for` and `vectorize` ops already
used this syntax, but their custom assembly was removed.

---------

Co-authored-by: Oleksandr "Alex" Zinenko <ftynse@gmail.com>
2024-05-08 09:11:53 -05:00
Mehdi Amini
e0b19e957e [MLIR] Remove unused implicit capture in the lambda (NFC)
This lambda does not capture anything, the `&` is just misleading.
2024-03-18 14:52:06 -07:00
Rik Huijzer
1949fe90bf
[mlir] Verify non-negative offset and size (#72059)
In #71153, the `memref.subview` canonicalizer crashes due to a negative
`size` being passed as an operand. During `SubViewOp::verify` this
negative `size` is not yet detectable since it is dynamic and only
available after constant folding, which happens during the
canonicalization passes. As discussed in
<https://discourse.llvm.org/t/rfc-more-opfoldresult-and-mixed-indices-in-ops-that-deal-with-shaped-values/72510>,
the verifier should not be extended as it should "only verify local
aspects of an operation".

This patch fixes #71153 by not folding in aforementioned situation.

Also, this patch adds a basic offset and size check in the
`OffsetSizeAndStrideOpInterface` verifier.

Note: only `offset` and `size` are checked because `stride` is allowed
to be negative
(54d81e49e3).
2023-11-16 07:42:37 +01:00
Matthias Springer
b2d1de2d63 [mlir][Interfaces][NFC] Delete dead code from OffsetSizeAndStrideOpInterface
Also make `getNumDynamicEntriesUpToIdx` a helper function. It does not have to be an interface method.

Differential Revision: https://reviews.llvm.org/D156864
2023-08-03 11:47:01 +02:00
Matthias Springer
a1f04b7037 [mlir][Interfaces][NFC] Use camel case for offset/size/stride accessors
This is for consistency with the remaining MLIR code base.

Differential Revision: https://reviews.llvm.org/D156857
2023-08-03 11:32:17 +02:00
Benjamin Kramer
c73053c26e Make python into C++
`not` is a C++ keyword, but it seems to cause trouble with MSVC
2023-07-05 17:49:25 +02:00
Andrzej Warzynski
ad7ef1923f [mlir][transform] Allow arbitrary indices to be scalable
This change lifts the limitation that only the trailing dimensions/sizes
in dynamic index lists can be scalable. It allows us to extend
`MaskedVectorizeOp` and `TileOp` from the Transform dialect so that the
following is allowed:

  %1, %loops:3 = transform.structured.tile %0 [4, [4], [4]]

This is also a follow up for https://reviews.llvm.org/D153372
that will enable the following (middle vector dimension is scalable):

  transform.structured.masked_vectorize %0 vector_sizes [2, [4], 8]

To facilate this change, the hooks for parsing and printing dynamic
index lists are updated accordingly (`printDynamicIndexList` and
`parseDynamicIndexList`, respectively). `MaskedVectorizeOp` and `TileOp`
are updated to include an array of attribute of bools that captures
whether the corresponding vector dimension/tile size, respectively, are
scalable or not.

NOTE 1: I am re-landing this after the initial version was reverted. To
fix the regression and in addition to the original patch, this revision
updates the Python bindings for the transform dialect

NOTE 2: This change is a part of a larger effort to enable scalable
vectorisation in Linalg. See this RFC for more context:
  * https://discourse.llvm.org/t/rfc-scalable-vectorisation-in-linalg/

This relands 048764f23a380fd6f8cc562a0008dcc6095fb594 with fixes.

Differential Revision: https://reviews.llvm.org/D154336
2023-07-05 09:53:26 +01:00
Alexander Belyaev
14d073b50f Revert "[mlir][transform] Allow arbitrary indices to be scalable"
This reverts commit 048764f23a380fd6f8cc562a0008dcc6095fb594.

Breaks https://lab.llvm.org/buildbot/#/builders/61/builds/45451
2023-07-04 09:40:52 +02:00
Andrzej Warzynski
048764f23a [mlir][transform] Allow arbitrary indices to be scalable
This change lifts the limitation that only the trailing dimensions/sizes
in dynamic index lists can be scalable. It allows us to extend
`MaskedVectorizeOp` and `TileOp` from the Transform dialect so that the
following is allowed:

  %1, %loops:3 = transform.structured.tile %0 [[4], [4], 4]

This is also a follow up for https://reviews.llvm.org/D153372
that will enable the following (middle vector dimension is scalable):

  transform.structured.masked_vectorize %0 vector_sizes [2, [4], 8]

To facilate this change, the hooks for parsing and printing dynamic
index lists are updated accordingly (`printDynamicIndexList` and
`parseDynamicIndexList`, respectively). `MaskedVectorizeOp` and `TileOp`
are updated to include an array of attribute of bools that captures
whether the corresponding vector dimension/tile size, respectively, are
scalable or not.

This change is a part of a larger effort to enable scalable
vectorisation in Linalg. See this RFC for more context:
  * https://discourse.llvm.org/t/rfc-scalable-vectorisation-in-linalg/

Differential Revision: https://reviews.llvm.org/D154336
2023-07-03 23:09:35 +01:00
Andrzej Warzynski
7a52f79126 [mlir][transform] Add support for expressing scalable vector sizes
This patch enables specifying scalable vector sizes when using the
Transform dialect to drive vectorisation, e.g.:
```
transform.structured.masked_vectorize %0 vector_sizes [8, 16, [4]]
```
This is implemented by extending the MaskedVectorizeOp with a dedicated
attribute for "scalability" and by overloading `parseDynamicIndexList`
so that MaskedVectorizeOp can continue using the auto-generated parser
and printer.

At the moment, only the trailing vec size can be scalable. The following
is not yet supported:
```
transform.structured.masked_vectorize %0 vector_sizes [8, [16], [4]]
```

As the vectoriser does not support scalable vectorisation just yet, a
warning is issues when scalable vector sizes are used. You can also use
the debug output, `--debug-only=linalg-vectorization`, to check whether
scalable vectorisation has been switched on.

This change is a part of a larger effort to enable scalable
vectorisation in Linalg. See this RFC for more context:
  * https://discourse.llvm.org/t/rfc-scalable-vectorisation-in-linalg/
Similar patch for tiling: https://reviews.llvm.org/D150944

Differential Revision: https://reviews.llvm.org/D151892
2023-06-08 20:54:17 +01:00
Andrzej Warzynski
726835cd51 [mlir] Update how scalable indices are printed
This patch makes sure that scalable indices (that would normally
represent scalable tile or vector sizes) are printed correctly, i.e.
with additional square brackets:
```
%1, %loop = transform.structured.tile %0 [2, 8, [4]]
```

This change complements https://reviews.llvm.org/D150944 and is a part
of a larger effort to enable scalable vectorisation in Linalg. See this
RFC for more context:
  * https://discourse.llvm.org/t/rfc-scalable-vectorisation-in-linalg/

Differential Revision: https://reviews.llvm.org/D151978
2023-06-02 16:47:56 +01:00
Andrzej Warzynski
a5b3677ddc [mlir][transform] Add support for expressing scalable tile sizes
This patch enables specifying scalable tile sizes when using the
Transform dialect to drive tiling, e.g.:
```
%1, %loop = transform.structured.tile %0 [[4]]
```
This is implemented by extending the TileOp with a dedicated attribute
for "scalability" and by updating various parsing hooks. At the moment,
only the trailing tile size can be scalable. The following is not yet
supported:
```
%1, %loop = transform.structured.tile %0 [[4], [4]]
```

This change is a part of larger effort to enable scalable vectorisation
in Linalg. See this RFC for more context:
  * https://discourse.llvm.org/t/rfc-scalable-vectorisation-in-linalg/

Differential Revision: https://reviews.llvm.org/D150944
2023-06-01 09:28:03 +01:00
Alex Zinenko
2fe4d90cac [mlir] make structured transform ops use types
Types have been introduced a while ago and provide for better
readability and transform-time verification. Use them in the ops from
the structured transform dialect extension.

In most cases, the types are appended as trailing functional types or a
derived format of the functional type that allows for an empty right
hand size without the annoying `-> ()` syntax (similarly to `func.func`
declaration that may omit the arrow). When handles are used inside mixed
static/dynamic lists, such as tile sizes, types of those handles follow
them immediately as in `sizes [%0 : !transform.any_value, 42]`. This
allows for better readability than matching the trailing type.

Update code to remove hardcoded PDL dependencies and expunge PDL from
structured transform op code.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D144515
2023-05-16 08:16:56 +00: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
Jacques Pienaar
ee308c99ed [mlir][py] Fix infer return type invocation for variadics
Previously we only allowed the flattened list passed in, but the same
input provided here as to buildGeneric so flatten accordingly. We have
less info here than in buildGeneric so the error is more generic if
unpacking fails.

Differential Revision: https://reviews.llvm.org/D143240
2023-02-06 17:01:53 -08:00
Lorenzo Chelini
baca3b382b [MLIR] Simplify logic in parseDynamicIndexList (NFC)
We can use `parseCommaSeparatedList` to simplify the logic of
`parseDynamicIndexList`. We don't need to explicitly check delimiters
and comma anymore, this is done for us by `parseCommaSeparatedList`.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D138694
2022-11-28 11:02:09 +01:00
Lorenzo Chelini
a9733b8a5e [MLIR] Adopt DenseI64ArrayAttr in tensor, memref and linalg transform
This commit is a first step toward removing inconsistencies between dynamic
and static attributes (i64 v. index) by dropping `I64ArrayAttr` and
using `DenseI64ArrayAttr` in Tensor, Memref and Linalg Transform ops.
In Linalg Transform ops only `TileToScfForOp` and `TileOp` have been updated.

See related discussion: https://discourse.llvm.org/t/rfc-inconsistency-between-dynamic-and-static-attributes-i64-v-index/66612/1

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D138567
2022-11-25 09:43:30 +01:00
Alexander Belyaev
65b72a78cc [mlir] Clean-up ViewLikeOpInterface w.r.t. kDynamic change.
Differential Revision: https://reviews.llvm.org/D138478
2022-11-22 10:51:53 +01: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
Mehdi Amini
0b1aee38bd Revert "[mlir][Tensor] Add rewrites to extract slices through tensor.collape_shape"
This reverts commit 5711957875738c1318f89afd7bf4be388f85a087.

A circular dependency is introduced here from Dialect/Utils/ to the
ViewLikeInterface, but it already depends on Dialect/Utils.

Also this introduces a dependency from lib/Dialect/Tensor to Linalg,
which isn't obviously correct from a layering point of view.
2022-09-02 23:34:52 +00:00
Christopher Bate
5711957875 [mlir][Tensor] Add rewrites to extract slices through tensor.collape_shape
This change adds a set of utilities to replace the result of a
`tensor.collapse_shape -> tensor.extract_slice` chain with the
equivalent result formed by aggregating slices of the
`tensor.collapse_shape` source. In general, it is not possible to
commute `extract_slice` and `collapse_shape` if linearized dimensions
are sliced. The i-th dimension of the `tensor.collapse_shape`
result is a "linearized sliced dimension" if:

1) Reassociation indices of tensor.collapse_shape in the i'th position
   is greater than size 1 (multiple dimensions of the input are collapsed)
2) The i-th dimension is sliced by `tensor.extract_slice`.

We can work around this by stitching together the result of
`tensor.extract_slice` by iterating over any linearized sliced dimensions.
This is equivalent to "tiling" the linearized-and-sliced dimensions of
the `tensor.collapse_shape` operation in order to manifest the result
tile (the result of the `tensor.extract_slice`). The user of the
utilities must provide the mechanism to create the tiling (e.g. a loop).
In the tests, it is demonstrated how to apply the utilities using either
`scf.for` or `scf.foreach_thread`.

The below example illustrates the pattern using `scf.for`:

```
%0 = linalg.generic ... -> tensor<3x7x11x10xf32>
%1 = tensor.collapse_shape %0 [[0, 1, 2], [3]] : ... to tensor<341x10xf32>
%2 = tensor.extract_slice %1 [13, 0] [10, 10] [2, 1] : .... tensor<10x10xf32>
```

We can construct %2 by generating the following IR:

```
%dest = linalg.init_tensor() : tensor<10x10xf32>
%2 = scf.for %iv = %c0 to %c10 step %c1 iter_args(%arg0) -> tensor<10x10xf32> {
   // Step 1: Map this output idx (%iv) to a multi-index for the input (%3):
   %linear_index = affine.apply affine_map<(d0)[]->(d0*2 + 11)>(%iv)
   %3:3 = arith.delinearize_index %iv into (3, 7, 11)
   // Step 2: Extract the slice from the input
   %4 = tensor.extract_slice %0 [%3#0, %3#1, %3#2, 0] [1, 1, 1, 10] [1, 1, 1, 1] :
         tensor<3x7x11x10xf32> to tensor<1x1x1x10xf32>
   %5 = tensor.collapse_shape %4 [[0, 1, 2], [3]] :
         tensor<1x1x1x10xf32> into tensor<1x10xf32>
   // Step 3: Insert the slice into the destination
   %6 = tensor.insert_slice %5 into %arg0 [%iv, 0] [1, 10] [1, 1] :
         tensor<1x10xf32> into tensor<10x10xf32>
   scf.yield %6 : tensor<10x10xf32>
}
```

The pattern was discussed in the RFC here: https://discourse.llvm.org/t/rfc-tensor-extracting-slices-from-tensor-collapse-shape/64034

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D129699
2022-09-02 11:29:04 -06:00
Jeff Niu
a2ad3ec7ac [mlir][ods] Support string literals in custom directives
This patch adds support for string literals as `custom` directive
arguments. This can be useful for re-using custom parsers and printers
when arguments have a known value. For example:

```
ParseResult parseTypedAttr(AsmParser &parser, Attribute &attr, Type type) {
  return parser.parseAttribute(attr, type);
}

void printTypedAttr(AsmPrinter &printer, Attribute attr, Type type) {
  return parser.printAttributeWithoutType(attr);
}
```

And in TableGen:

```
def FooOp : ... {
  let arguments = (ins AnyAttr:$a);
  let assemblyFormat = [{ custom<TypedAttr>($a, "$_builder.getI1Type()")
                          attr-dict }];
}

def BarOp : ... {
  let arguments = (ins AnyAttr:$a);
  let assemblyFormat = [{ custom<TypedAttr>($a, "$_builder.getIndexType()")
                          attr-dict }];
}
```

Instead of writing two separate sets of custom parsers and printers.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D131603
2022-08-12 20:55:11 -04: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
Frederik Gossen
f98d73f4e0 [MLIR] Make the implementations for getMixedOffsets/Sizes/Strides independent of OffsetSizeAndStrideOpInterface
The functions are effectively independent of the interface already, however, they take it as an argument for no reason.
The current state complicates reuse outside of MLIR.

Differential Revision: https://reviews.llvm.org/D131120
2022-08-04 11:58:15 -04:00
Alexander Belyaev
68b0aaad56 Revert "Revert "[mlir] Reuse the code between getMixed*s() funcs in ViewLikeInterface.cpp.""
This reverts commit e78d7637fbb08ec2c2e59939c015faadd47e32e7.

Differential Revision: https://reviews.llvm.org/D130706
2022-07-31 21:46:18 +02:00
Alexander Belyaev
e78d7637fb Revert "[mlir] Reuse the code between getMixed*s() funcs in ViewLikeInterface.cpp."
This reverts commit e8c2877565149587fd66fbee591b7d44eecd667d.
2022-07-31 21:25:20 +02:00
Alexander Belyaev
e8c2877565 [mlir] Reuse the code between getMixed*s() funcs in ViewLikeInterface.cpp.
Differential Revision: https://reviews.llvm.org/D130706
2022-07-31 21:09:30 +02:00
Matthias Springer
fb0654ced3 [mlir][interfaces][NFC] Remove ViewLikeInterface::expandToRank
This helper function is no longer needed.

Differential Revision: https://reviews.llvm.org/D129145
2022-07-05 16:59:18 +02:00
Mehdi Amini
84124ff891 Apply clang-tidy fixes for readability-simplify-boolean-expr in ViewLikeInterface.cpp (NFC) 2022-06-29 12:15:39 +00:00
Kazu Hirata
3b7c3a654c Revert "Don't use Optional::hasValue (NFC)"
This reverts commit aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d.
2022-06-25 11:56:50 -07:00
Kazu Hirata
aa8feeefd3 Don't use Optional::hasValue (NFC) 2022-06-25 11:55:57 -07:00
Frederik Gossen
02d29afd16 [MLIR] Add decomposeMixedStridesOrOffsets and decomposeMixedSizes
Add the reverse functions to the ViewLikeInterface's functions
`getMixedStrides`, `getMixedSizes`, and `getMixedOffsets`. The new functions
are useful to build view-like operations from an array of mixed static/dynamic
values.

Differential Revision: https://reviews.llvm.org/D128376
2022-06-23 19:08:36 -04:00
Markus Böck
e13d23bc6c [mlir] Rename OpAsmParser::OperandType to OpAsmParser::UnresolvedOperand
I am not sure about the meaning of Type in the name (was it meant be interpreted as Kind?), and given the importance and meaning of Type in the context of MLIR, its probably better to rename it. Given the comment in the source code, the suggestion in the GitHub issue and the final discussions in the review, this patch renames the OperandType to UnresolvedOperand.

Fixes https://github.com/llvm/llvm-project/issues/54446

Differential Revision: https://reviews.llvm.org/D122142
2022-03-21 21:42:13 +01:00
Ivan Butygin
b65f21a498 [mlir] Provide getMixedOffsets/sizes/strides as free functions
* This is useful when you need to build mixed array from external static/dynamic arrays (e.g. from adaptor during dialect conversion)
* Also, to reduce C++ code in td and generated files

Differential Revision: https://reviews.llvm.org/D117106
2022-01-13 13:46:31 +03:00
Nicolas Vasilache
d0ee094d6a [mlir][Bufferize] Fix incorrect bufferization of rank-reducing tensor ops.
This revision fixes SubviewOp, InsertSliceOp, ExtractSliceOp construction during bufferization
where not all offset/size/stride operands were properly specified.

A test that exhibited problematic behaviors related to incorrect memref casts is introduced.
Init tensor optimization is disabled in teh testing func bufferize pass.

Differential Revision: https://reviews.llvm.org/D116899
2022-01-10 10:14:55 -05:00
MaheshRavishankar
7df7586a0b [mlir][MemRef] Deprecate unspecified trailing offset, size, and strides semantics of OffsetSizeAndStrideOpInterface.
The semantics of the ops that implement the
`OffsetSizeAndStrideOpInterface` is that if the number of offsets,
sizes or strides are less than the rank of the source, then some
default values are filled along the trailing dimensions (0 for offset,
source dimension of sizes, and 1 for strides). This is confusing,
especially with rank-reducing semantics. Immediate issue here is that
the methods of `OffsetSizeAndStridesOpInterface` assumes that the
number of values is same as the source rank. This cause out-of-bounds
errors.

So simplifying the specification of `OffsetSizeAndStridesOpInterface`
to make it invalid to specify number of offsets/sizes/strides not
equal to the source rank.

Differential Revision: https://reviews.llvm.org/D115677
2021-12-29 11:18:29 -08:00
Nicolas Vasilache
ce4f99e7f2 [mlir][Linalg] Add comprehensive bufferization support for subtensor (5/n)
This revision refactors and simplifies the pattern detection logic: thanks to SSA value properties, we can actually look at all the uses of a given value and avoid having to pattern-match specific chains of operations.

A bufferization pattern for subtensor is added and specific inplaceability analysis is implemented for the simple case of subtensor. More advanced use cases will follow.

Differential revision: https://reviews.llvm.org/D102512
2021-05-27 12:48:08 +00:00
Uday Bondhugula
62851ea7ea [MLIR] Rename free function verify on OffsetSizeAndStrideOpInterface
Using a free function verify(<Op>) is error prone. Rename it.

Differential Revision: https://reviews.llvm.org/D101886
2021-05-05 17:44:15 +05:30
MaheshRavishankar
342d4662e1 [mlir] Add custom directive hooks for printing mixed integer or value operands.
Add printer and parser hooks for a custom directive that allows
parsing and printing of idioms that can represent a list of values
each of which is either an integer or an SSA value. For example in

`subview %source[%offset_0, 1] [4, %size_1] [%stride_0, 3]`

each of the list (which represents offset, size and strides) is a mix
of either statically know integer values or dynamically computed SSA
values. Since this is used in many places adding a custom directive to
parse/print this idiom allows using assembly format on operations
which use this idiom.

Differential Revision: https://reviews.llvm.org/D95773
2021-02-01 19:03:49 -08:00
Nicolas Vasilache
5133673df4 [mlir] Extend semantic of OffsetSizeAndStrideOpInterface.
OffsetSizeAndStrideOpInterface now have the ability to specify only a leading subset of
offset, sizes, strides operands/attributes.
The size of that leading subset must be limited by the corresponding entry in `getArrayAttrMaxRanks` to avoid overflows.
Missing trailing dimensions are assumed to span the whole range (i.e. [0 .. dim)).
This brings more natural semantics to slice-like op on top of subview and is a simplifies to removing all uses of SliceOp in dependent projects.

Differential revision: https://reviews.llvm.org/D95441
2021-01-27 09:02:35 +00:00
MaheshRavishankar
118a715654 [mlir][Linalg] Define a linalg.init_tensor operation.
This operation is used to materialize a tensor of a particular
shape. The shape could be specified as a mix of static and dynamic
values.

The use of this operation is to be an `init` tensor for Linalg
structured operation on tensors where the bounds of the computation
depends on the shape of the output of the linalg operation. The result
of this operation will be used as the `init` tensor of such Linalg
operations. To note,

1) The values in the tensor materialized is not used. Any operation to
   which this is an init tensor is expected to overwrite the entire
   tensor.
2) The tensor is materialized only for the shape of the output and to
   make the loop bounds depend only on operands of the structured
   operation.

Based on (1) and (2) it is assumed that these operations eventually go
away since they are only used in `dim` operations that can be
canonicalized to make this operation dead. Such canonicalization are
added here too.

Differential Revision: https://reviews.llvm.org/D93374
2020-12-17 14:45:51 -08:00
Nicolas Vasilache
c247081025 [mlir] NFC - Refactor and expose a helper printOffsetSizesAndStrides helper function.
Print part of an op of the form:
```
  <optional-offset-prefix>`[` offset-list `]`
  <optional-size-prefix>`[` size-list `]`
  <optional-stride-prefix>[` stride-list `]`
```

Also address some leftover nits.

Differential revision: https://reviews.llvm.org/D92031
2020-11-24 20:00:59 +00:00
Nicolas Vasilache
b6c71c13a3 [mlir] NFC - Refactor and expose a parsing helper for OffsetSizeAndStrideInterface
Parse trailing part of an op of the form:
```
  <optional-offset-prefix>`[` offset-list `]`
  <optional-size-prefix>`[` size-list `]`
  <optional-stride-prefix>[` stride-list `]`
```
Each entry in the offset, size and stride list either resolves to an integer
constant or an operand of index type.
Constants are added to the `result` as named integer array attributes with
name `OffsetSizeAndStrideOpInterface::getStaticOffsetsAttrName()` (resp.
`getStaticSizesAttrName()`, `getStaticStridesAttrName()`).

Append the number of offset, size and stride operands to `segmentSizes`
before adding it to `result` as the named attribute:
`OpTrait::AttrSizedOperandSegments<void>::getOperandSegmentSizeAttr()`.
Offset, size and stride operands resolution occurs after `preResolutionFn`
to give a chance to leading operands to resolve first, after parsing the
types.
```
ParseResult parseOffsetsSizesAndStrides(
    OpAsmParser &parser, OperationState &result, ArrayRef<int> segmentSizes,
    llvm::function_ref<ParseResult(OpAsmParser &, OperationState &)>
        preResolutionFn = nullptr,
    llvm::function_ref<ParseResult(OpAsmParser &)> parseOptionalOffsetPrefix =
        nullptr,
    llvm::function_ref<ParseResult(OpAsmParser &)> parseOptionalSizePrefix =
        nullptr,
    llvm::function_ref<ParseResult(OpAsmParser &)> parseOptionalStridePrefix =
        nullptr);
```

Differential revision: https://reviews.llvm.org/D92030
2020-11-24 19:45:16 +00:00
Nicolas Vasilache
a8de412f51 [mlir] NFC - Expose an OffsetSizeAndStrideOpInterface
This revision will make it easier to create new ops base on the strided memref abstraction outside of the std dialect.

OffsetSizeAndStrideOpInterface is an interface for ops that allow specifying mixed dynamic and static offsets, sizes and strides variadic operands.
    Ops that implement this interface need to expose the following methods:
      1. `getArrayAttrRanks` to specify the length of static integer
          attributes.
      2. `offsets`, `sizes` and `strides` variadic operands.
      3. `static_offsets`, resp. `static_sizes` and `static_strides` integer
          array attributes.

    The invariants of this interface are:
      1. `static_offsets`, `static_sizes` and `static_strides` have length
          exactly `getArrayAttrRanks()`[0] (resp. [1], [2]).
      2. `offsets`, `sizes` and `strides` have each length at most
         `getArrayAttrRanks()`[0] (resp. [1], [2]).
      3. if an entry of `static_offsets` (resp. `static_sizes`,
         `static_strides`) is equal to a special sentinel value, namely
         `ShapedType::kDynamicStrideOrOffset` (resp. `ShapedType::kDynamicSize`,
         `ShapedType::kDynamicStrideOrOffset`), then the corresponding entry is
         a dynamic offset (resp. size, stride).
      4. a variadic `offset` (resp. `sizes`, `strides`) operand  must be present
         for each dynamic offset (resp. size, stride).

    This interface is useful to factor out common behavior and provide support
    for carrying or injecting static behavior through the use of the static
    attributes.

Differential Revision: https://reviews.llvm.org/D92011
2020-11-24 14:42:47 +00:00