2020-04-22 23:16:34 +08:00
|
|
|
//===- ViewLikeInterface.cpp - View-like operations in MLIR ---------------===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "mlir/Interfaces/ViewLikeInterface.h"
|
|
|
|
|
|
|
|
using namespace mlir;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ViewLike Interfaces
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// Include the definitions of the loop-like interfaces.
|
|
|
|
#include "mlir/Interfaces/ViewLikeInterface.cpp.inc"
|
[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 22:23:57 +08:00
|
|
|
|
2020-12-18 06:42:40 +08:00
|
|
|
LogicalResult mlir::verifyListOfOperandsOrIntegers(
|
2021-01-27 16:06:40 +08:00
|
|
|
Operation *op, StringRef name, unsigned maxNumElements, ArrayAttr attr,
|
2020-12-18 06:42:40 +08:00
|
|
|
ValueRange values, llvm::function_ref<bool(int64_t)> isDynamic) {
|
2021-01-27 16:06:40 +08:00
|
|
|
/// Check static and dynamic offsets/sizes/strides does not overflow type.
|
|
|
|
if (attr.size() > maxNumElements)
|
|
|
|
return op->emitError("expected <= ")
|
|
|
|
<< maxNumElements << " " << name << " values";
|
[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 22:23:57 +08:00
|
|
|
unsigned expectedNumDynamicEntries =
|
|
|
|
llvm::count_if(attr.getValue(), [&](Attribute attr) {
|
|
|
|
return isDynamic(attr.cast<IntegerAttr>().getInt());
|
|
|
|
});
|
|
|
|
if (values.size() != expectedNumDynamicEntries)
|
2020-12-18 06:42:40 +08:00
|
|
|
return op->emitError("expected ")
|
[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 22:23:57 +08:00
|
|
|
<< expectedNumDynamicEntries << " dynamic " << name << " values";
|
|
|
|
return success();
|
|
|
|
}
|
|
|
|
|
2021-05-05 15:47:33 +08:00
|
|
|
LogicalResult
|
|
|
|
mlir::detail::verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) {
|
2021-01-27 16:06:40 +08:00
|
|
|
std::array<unsigned, 3> maxRanks = op.getArrayAttrMaxRanks();
|
|
|
|
// Offsets can come in 2 flavors:
|
|
|
|
// 1. Either single entry (when maxRanks == 1).
|
|
|
|
// 2. Or as an array whose rank must match that of the mixed sizes.
|
|
|
|
// So that the result type is well-formed.
|
|
|
|
if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) &&
|
|
|
|
op.getMixedOffsets().size() != op.getMixedSizes().size())
|
|
|
|
return op->emitError(
|
|
|
|
"expected mixed offsets rank to match mixed sizes rank (")
|
|
|
|
<< op.getMixedOffsets().size() << " vs " << op.getMixedSizes().size()
|
|
|
|
<< ") so the rank of the result type is well-formed.";
|
|
|
|
// Ranks of mixed sizes and strides must always match so the result type is
|
|
|
|
// well-formed.
|
|
|
|
if (op.getMixedSizes().size() != op.getMixedStrides().size())
|
|
|
|
return op->emitError(
|
|
|
|
"expected mixed sizes rank to match mixed strides rank (")
|
|
|
|
<< op.getMixedSizes().size() << " vs " << op.getMixedStrides().size()
|
|
|
|
<< ") so the rank of the result type is well-formed.";
|
|
|
|
|
2020-12-18 06:42:40 +08:00
|
|
|
if (failed(verifyListOfOperandsOrIntegers(
|
2021-01-27 16:06:40 +08:00
|
|
|
op, "offset", maxRanks[0], op.static_offsets(), op.offsets(),
|
2020-12-18 06:42:40 +08:00
|
|
|
ShapedType::isDynamicStrideOrOffset)))
|
[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 22:23:57 +08:00
|
|
|
return failure();
|
2021-01-27 16:06:40 +08:00
|
|
|
if (failed(verifyListOfOperandsOrIntegers(op, "size", maxRanks[1],
|
2020-12-18 06:42:40 +08:00
|
|
|
op.static_sizes(), op.sizes(),
|
|
|
|
ShapedType::isDynamic)))
|
[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 22:23:57 +08:00
|
|
|
return failure();
|
2020-12-18 06:42:40 +08:00
|
|
|
if (failed(verifyListOfOperandsOrIntegers(
|
2021-01-27 16:06:40 +08:00
|
|
|
op, "stride", maxRanks[2], op.static_strides(), op.strides(),
|
2020-12-18 06:42:40 +08:00
|
|
|
ShapedType::isDynamicStrideOrOffset)))
|
[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 22:23:57 +08:00
|
|
|
return failure();
|
|
|
|
return success();
|
|
|
|
}
|
[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 22:54:06 +08:00
|
|
|
|
2021-02-02 11:03:12 +08:00
|
|
|
template <int64_t dynVal>
|
|
|
|
static void printOperandsOrIntegersListImpl(OpAsmPrinter &p, ValueRange values,
|
|
|
|
ArrayAttr arrayAttr) {
|
2020-11-25 03:52:24 +08:00
|
|
|
p << '[';
|
2021-02-02 11:03:12 +08:00
|
|
|
if (arrayAttr.empty()) {
|
|
|
|
p << "]";
|
|
|
|
return;
|
|
|
|
}
|
2020-11-25 03:52:24 +08:00
|
|
|
unsigned idx = 0;
|
|
|
|
llvm::interleaveComma(arrayAttr, p, [&](Attribute a) {
|
|
|
|
int64_t val = a.cast<IntegerAttr>().getInt();
|
2021-02-02 11:03:12 +08:00
|
|
|
if (val == dynVal)
|
2020-11-25 03:52:24 +08:00
|
|
|
p << values[idx++];
|
|
|
|
else
|
|
|
|
p << val;
|
|
|
|
});
|
|
|
|
p << ']';
|
|
|
|
}
|
|
|
|
|
2021-02-02 11:03:12 +08:00
|
|
|
void mlir::printOperandsOrIntegersOffsetsOrStridesList(OpAsmPrinter &p,
|
|
|
|
Operation *op,
|
|
|
|
OperandRange values,
|
|
|
|
ArrayAttr integers) {
|
|
|
|
return printOperandsOrIntegersListImpl<ShapedType::kDynamicStrideOrOffset>(
|
|
|
|
p, values, integers);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mlir::printOperandsOrIntegersSizesList(OpAsmPrinter &p, Operation *op,
|
|
|
|
OperandRange values,
|
|
|
|
ArrayAttr integers) {
|
|
|
|
return printOperandsOrIntegersListImpl<ShapedType::kDynamicSize>(p, values,
|
|
|
|
integers);
|
2020-11-25 03:52:24 +08:00
|
|
|
}
|
|
|
|
|
2021-02-02 11:03:12 +08:00
|
|
|
template <int64_t dynVal>
|
|
|
|
static ParseResult
|
|
|
|
parseOperandsOrIntegersImpl(OpAsmParser &parser,
|
|
|
|
SmallVectorImpl<OpAsmParser::OperandType> &values,
|
|
|
|
ArrayAttr &integers) {
|
[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 22:54:06 +08:00
|
|
|
if (failed(parser.parseLSquare()))
|
|
|
|
return failure();
|
|
|
|
// 0-D.
|
|
|
|
if (succeeded(parser.parseOptionalRSquare())) {
|
2021-02-02 11:03:12 +08:00
|
|
|
integers = parser.getBuilder().getArrayAttr({});
|
[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 22:54:06 +08:00
|
|
|
return success();
|
|
|
|
}
|
|
|
|
|
|
|
|
SmallVector<int64_t, 4> attrVals;
|
|
|
|
while (true) {
|
|
|
|
OpAsmParser::OperandType operand;
|
|
|
|
auto res = parser.parseOptionalOperand(operand);
|
|
|
|
if (res.hasValue() && succeeded(res.getValue())) {
|
2021-02-02 11:03:12 +08:00
|
|
|
values.push_back(operand);
|
[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 22:54:06 +08:00
|
|
|
attrVals.push_back(dynVal);
|
|
|
|
} else {
|
|
|
|
IntegerAttr attr;
|
|
|
|
if (failed(parser.parseAttribute<IntegerAttr>(attr)))
|
|
|
|
return parser.emitError(parser.getNameLoc())
|
|
|
|
<< "expected SSA value or integer";
|
|
|
|
attrVals.push_back(attr.getInt());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (succeeded(parser.parseOptionalComma()))
|
|
|
|
continue;
|
|
|
|
if (failed(parser.parseRSquare()))
|
|
|
|
return failure();
|
|
|
|
break;
|
|
|
|
}
|
2021-02-02 11:03:12 +08:00
|
|
|
integers = parser.getBuilder().getI64ArrayAttr(attrVals);
|
[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 22:54:06 +08:00
|
|
|
return success();
|
|
|
|
}
|
|
|
|
|
2021-02-02 11:03:12 +08:00
|
|
|
ParseResult mlir::parseOperandsOrIntegersOffsetsOrStridesList(
|
|
|
|
OpAsmParser &parser, SmallVectorImpl<OpAsmParser::OperandType> &values,
|
|
|
|
ArrayAttr &integers) {
|
|
|
|
return parseOperandsOrIntegersImpl<ShapedType::kDynamicStrideOrOffset>(
|
|
|
|
parser, values, integers);
|
2020-11-25 03:52:24 +08:00
|
|
|
}
|
|
|
|
|
2021-02-02 11:03:12 +08:00
|
|
|
ParseResult mlir::parseOperandsOrIntegersSizesList(
|
|
|
|
OpAsmParser &parser, SmallVectorImpl<OpAsmParser::OperandType> &values,
|
|
|
|
ArrayAttr &integers) {
|
|
|
|
return parseOperandsOrIntegersImpl<ShapedType::kDynamicSize>(parser, values,
|
|
|
|
integers);
|
[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 22:54:06 +08:00
|
|
|
}
|
2021-05-27 20:19:39 +08:00
|
|
|
|
|
|
|
bool mlir::detail::sameOffsetsSizesAndStrides(
|
|
|
|
OffsetSizeAndStrideOpInterface a, OffsetSizeAndStrideOpInterface b,
|
|
|
|
llvm::function_ref<bool(OpFoldResult, OpFoldResult)> cmp) {
|
|
|
|
if (a.static_offsets().size() != b.static_offsets().size())
|
|
|
|
return false;
|
|
|
|
if (a.static_sizes().size() != b.static_sizes().size())
|
|
|
|
return false;
|
|
|
|
if (a.static_strides().size() != b.static_strides().size())
|
|
|
|
return false;
|
|
|
|
for (auto it : llvm::zip(a.getMixedOffsets(), b.getMixedOffsets()))
|
|
|
|
if (!cmp(std::get<0>(it), std::get<1>(it)))
|
|
|
|
return false;
|
|
|
|
for (auto it : llvm::zip(a.getMixedSizes(), b.getMixedSizes()))
|
|
|
|
if (!cmp(std::get<0>(it), std::get<1>(it)))
|
|
|
|
return false;
|
|
|
|
for (auto it : llvm::zip(a.getMixedStrides(), b.getMixedStrides()))
|
|
|
|
if (!cmp(std::get<0>(it), std::get<1>(it)))
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|