430 lines
14 KiB
TableGen
430 lines
14 KiB
TableGen
//===- ViewLikeInterface.td - ViewLike interface -----------*- tablegen -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Defines the interface for view-like operations.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MLIR_INTERFACES_VIEWLIKEINTERFACE
|
|
#define MLIR_INTERFACES_VIEWLIKEINTERFACE
|
|
|
|
include "mlir/IR/OpBase.td"
|
|
|
|
def ViewLikeOpInterface : OpInterface<"ViewLikeOpInterface"> {
|
|
let description = [{
|
|
A view-like operation "views" a buffer in a potentially different way. It
|
|
takes in a (view of) buffer (and potentially some other operands) and returns
|
|
another view of buffer.
|
|
}];
|
|
let cppNamespace = "::mlir";
|
|
|
|
let methods = [
|
|
InterfaceMethod<
|
|
"Returns the source buffer from which the view is created.",
|
|
"::mlir::Value", "getViewSource">,
|
|
InterfaceMethod<
|
|
/*desc=*/[{ Returns the buffer which the view created. }],
|
|
/*retTy=*/"::mlir::Value",
|
|
/*methodName=*/"getViewDest",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op->getResult(0);
|
|
}]
|
|
>
|
|
];
|
|
}
|
|
|
|
def OffsetSizeAndStrideOpInterface : OpInterface<"OffsetSizeAndStrideOpInterface"> {
|
|
let description = [{
|
|
Common 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. `getArrayAttrMaxRanks` 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.
|
|
4. `getOffsetSizeAndStrideStartOperandIndex` method that specifies the
|
|
starting index of the OffsetSizeAndStrideOpInterface operands
|
|
|
|
The invariants of this interface are:
|
|
1. `static_offsets`, `static_sizes` and `static_strides` have length
|
|
exactly `getArrayAttrMaxRanks()`[0] (resp. [1], [2]).
|
|
2. `offsets`, `sizes` and `strides` have each length at most
|
|
`getArrayAttrMaxRanks()`[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::kDynamic`, 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).
|
|
5. `offsets`, `sizes` and `strides` operands are specified in this order
|
|
at operand index starting at `getOffsetSizeAndStrideStartOperandIndex`.
|
|
6. `offsets` and `sizes` operands are non-negative.
|
|
|
|
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.
|
|
}];
|
|
|
|
let cppNamespace = "::mlir";
|
|
|
|
let methods = [
|
|
StaticInterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the number of leading operands before the `offsets`, `sizes` and
|
|
and `strides` operands.
|
|
}],
|
|
/*retTy=*/"unsigned",
|
|
/*methodName=*/"getOffsetSizeAndStrideStartOperandIndex",
|
|
/*args=*/(ins)
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the expected rank of each of the`static_offsets`, `static_sizes`
|
|
and `static_strides` attributes.
|
|
}],
|
|
/*retTy=*/"std::array<unsigned, 3>",
|
|
/*methodName=*/"getArrayAttrMaxRanks",
|
|
/*args=*/(ins)
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the dynamic offset operands.
|
|
}],
|
|
/*retTy=*/"::mlir::OperandRange",
|
|
/*methodName=*/"getOffsets",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getOffsets();
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the dynamic size operands.
|
|
}],
|
|
/*retTy=*/"::mlir::OperandRange",
|
|
/*methodName=*/"getSizes",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getSizes();
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the dynamic stride operands.
|
|
}],
|
|
/*retTy=*/"::mlir::OperandRange",
|
|
/*methodName=*/"getStrides",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getStrides();
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the static offset attributes.
|
|
}],
|
|
/*retTy=*/"::llvm::ArrayRef<int64_t>",
|
|
/*methodName=*/"getStaticOffsets",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getStaticOffsets();
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the static size attributes.
|
|
}],
|
|
/*retTy=*/"::llvm::ArrayRef<int64_t>",
|
|
/*methodName=*/"getStaticSizes",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getStaticSizes();
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return the dynamic stride attributes.
|
|
}],
|
|
/*retTy=*/"::llvm::ArrayRef<int64_t>",
|
|
/*methodName=*/"getStaticStrides",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getStaticStrides();
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return a vector of all the static or dynamic offsets of the op.
|
|
}],
|
|
/*retTy=*/"::llvm::SmallVector<::mlir::OpFoldResult>",
|
|
/*methodName=*/"getMixedOffsets",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
Builder b($_op->getContext());
|
|
return ::mlir::getMixedValues($_op.getStaticOffsets(),
|
|
$_op.getOffsets(), b);
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return a vector of all the static or dynamic sizes of the op.
|
|
}],
|
|
/*retTy=*/"::llvm::SmallVector<::mlir::OpFoldResult>",
|
|
/*methodName=*/"getMixedSizes",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
Builder b($_op->getContext());
|
|
return
|
|
::mlir::getMixedValues($_op.getStaticSizes(), $_op.getSizes(), b);
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return a vector of all the static or dynamic strides of the op.
|
|
}],
|
|
/*retTy=*/"::llvm::SmallVector<::mlir::OpFoldResult>",
|
|
/*methodName=*/"getMixedStrides",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
Builder b($_op->getContext());
|
|
return ::mlir::getMixedValues($_op.getStaticStrides(),
|
|
$_op.getStrides(), b);
|
|
}]
|
|
>,
|
|
|
|
InterfaceMethod<
|
|
/*desc=*/"Return true if the offset `idx` is dynamic.",
|
|
/*retTy=*/"bool",
|
|
/*methodName=*/"isDynamicOffset",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return ::mlir::ShapedType::isDynamic(getStaticOffsets()[idx]);
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/"Return true if the size `idx` is dynamic.",
|
|
/*retTy=*/"bool",
|
|
/*methodName=*/"isDynamicSize",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return ::mlir::ShapedType::isDynamic(getStaticSizes()[idx]);
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/"Return true if the stride `idx` is dynamic.",
|
|
/*retTy=*/"bool",
|
|
/*methodName=*/"isDynamicStride",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return ::mlir::ShapedType::isDynamic(getStaticStrides()[idx]);
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the offset `idx` is a static constant and return its value.
|
|
}],
|
|
/*retTy=*/"int64_t",
|
|
/*methodName=*/"getStaticOffset",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
assert(!$_op.isDynamicOffset(idx) && "expected static offset");
|
|
return getStaticOffsets()[idx];
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the size `idx` is a static constant and return its value.
|
|
}],
|
|
/*retTy=*/"int64_t",
|
|
/*methodName=*/"getStaticSize",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
assert(!$_op.isDynamicSize(idx) && "expected static size");
|
|
return getStaticSizes()[idx];
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the stride `idx` is a static constant and return its value.
|
|
}],
|
|
/*retTy=*/"int64_t",
|
|
/*methodName=*/"getStaticStride",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
assert(!$_op.isDynamicStride(idx) && "expected static stride");
|
|
return getStaticStrides()[idx];
|
|
}]
|
|
>,
|
|
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the offset `idx` is dynamic and return the position of the
|
|
corresponding operand.
|
|
}],
|
|
/*retTy=*/"unsigned",
|
|
/*methodName=*/"getIndexOfDynamicOffset",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
assert($_op.isDynamicOffset(idx) && "expected dynamic offset");
|
|
auto numDynamic = ::mlir::detail::getNumDynamicEntriesUpToIdx(
|
|
getStaticOffsets(), idx);
|
|
return $_op.getOffsetSizeAndStrideStartOperandIndex() + numDynamic;
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the size `idx` is dynamic and return the position of the
|
|
corresponding operand.
|
|
}],
|
|
/*retTy=*/"unsigned",
|
|
/*methodName=*/"getIndexOfDynamicSize",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
assert($_op.isDynamicSize(idx) && "expected dynamic size");
|
|
auto numDynamic = ::mlir::detail::getNumDynamicEntriesUpToIdx(
|
|
getStaticSizes(), idx);
|
|
return $_op.getOffsetSizeAndStrideStartOperandIndex() +
|
|
getOffsets().size() + numDynamic;
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the stride `idx` is dynamic and return the position of the
|
|
corresponding operand.
|
|
}],
|
|
/*retTy=*/"unsigned",
|
|
/*methodName=*/"getIndexOfDynamicStride",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
assert($_op.isDynamicStride(idx) && "expected dynamic stride");
|
|
auto numDynamic = ::mlir::detail::getNumDynamicEntriesUpToIdx(
|
|
getStaticStrides(), idx);
|
|
return $_op.getOffsetSizeAndStrideStartOperandIndex() +
|
|
getOffsets().size() + getSizes().size() + numDynamic;
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the offset `idx` is dynamic and return its value.
|
|
}],
|
|
/*retTy=*/"::mlir::Value",
|
|
/*methodName=*/"getDynamicOffset",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getOperand(getIndexOfDynamicOffset(idx));
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the size `idx` is dynamic and return its value.
|
|
}],
|
|
/*retTy=*/"::mlir::Value",
|
|
/*methodName=*/"getDynamicSize",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getOperand(getIndexOfDynamicSize(idx));
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Assert the stride `idx` is dynamic and return its value.
|
|
}],
|
|
/*retTy=*/"::mlir::Value",
|
|
/*methodName=*/"getDynamicStride",
|
|
/*args=*/(ins "unsigned":$idx),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return $_op.getOperand(getIndexOfDynamicStride(idx));
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{
|
|
Return true if all `other`'s offsets, sizes and strides are the same.
|
|
Takes a custom `cmp` comparison function on OpFoldResult to avoid taking
|
|
a dialect dependence.
|
|
}],
|
|
/*retTy=*/"bool",
|
|
/*methodName=*/"isSameAs",
|
|
/*args=*/(ins "::mlir::OffsetSizeAndStrideOpInterface":$other,
|
|
"::llvm::function_ref<bool(::mlir::OpFoldResult, ::mlir::OpFoldResult)>":$cmp),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return ::mlir::detail::sameOffsetsSizesAndStrides(
|
|
::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(
|
|
$_op.getOperation()), other, cmp);
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{ Return true if all strides are guaranteed to be 1. }],
|
|
/*retTy=*/"bool",
|
|
/*methodName=*/"hasUnitStride",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return ::llvm::all_of(getMixedStrides(), [](::mlir::OpFoldResult ofr) {
|
|
return ::mlir::getConstantIntValue(ofr) == static_cast<int64_t>(1);
|
|
});
|
|
}]
|
|
>,
|
|
InterfaceMethod<
|
|
/*desc=*/[{ Return true if all offsets are guaranteed to be 0. }],
|
|
/*retTy=*/"bool",
|
|
/*methodName=*/"hasZeroOffset",
|
|
/*args=*/(ins),
|
|
/*methodBody=*/"",
|
|
/*defaultImplementation=*/[{
|
|
return ::llvm::all_of(getMixedOffsets(), [](::mlir::OpFoldResult ofr) {
|
|
return ::mlir::getConstantIntValue(ofr) == static_cast<int64_t>(0);
|
|
});
|
|
}]
|
|
>,
|
|
];
|
|
|
|
let verify = [{
|
|
return ::mlir::detail::verifyOffsetSizeAndStrideOp(
|
|
::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>($_op));
|
|
}];
|
|
}
|
|
|
|
// This trai indicates that pointer-like objects (such as memrefs) returned
|
|
// from this operation will never alias with each other. This provides a
|
|
// guarantee to optimization passes that accesses through different results
|
|
// of this operation can be safely reordered, as they will never reference
|
|
// overlapping memory locations.
|
|
//
|
|
// Operations with this trait take multiple pointer-like operands
|
|
// and return the same operands with additional non-aliasing guarantees.
|
|
// If the access to the results of this operation aliases at runtime, the
|
|
// behavior of such access is undefined.
|
|
def DistinctObjectsTrait : NativeOpTrait<"DistinctObjectsTrait">;
|
|
|
|
#endif // MLIR_INTERFACES_VIEWLIKEINTERFACE
|