1 //===- ViewLikeInterface.h - View-like operations interface ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the operation interface for view-like operations.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_INTERFACES_VIEWLIKEINTERFACE_H_
14 #define MLIR_INTERFACES_VIEWLIKEINTERFACE_H_
15 
16 #include "mlir/Dialect/Utils/StaticValueUtils.h"
17 #include "mlir/IR/Builders.h"
18 #include "mlir/IR/BuiltinAttributes.h"
19 #include "mlir/IR/BuiltinTypes.h"
20 #include "mlir/IR/OpImplementation.h"
21 
22 namespace mlir {
23 /// Auxiliary range data structure to unpack the offset, size and stride
24 /// operands into a list of triples. Such a list can be more convenient to
25 /// manipulate.
26 struct Range {
27   Value offset;
28   Value size;
29   Value stride;
30 };
31 
32 class OffsetSizeAndStrideOpInterface;
33 
34 /// Return a vector of all the static or dynamic offsets of the op from provided
35 /// external static and dynamic offsets.
36 SmallVector<OpFoldResult, 4> getMixedOffsets(OffsetSizeAndStrideOpInterface op,
37                                              ArrayAttr staticOffsets,
38                                              ValueRange offsets);
39 
40 /// Return a vector of all the static or dynamic sizes of the op from provided
41 /// external static and dynamic sizes.
42 SmallVector<OpFoldResult, 4> getMixedSizes(OffsetSizeAndStrideOpInterface op,
43                                            ArrayAttr staticSizes,
44                                            ValueRange sizes);
45 
46 /// Return a vector of all the static or dynamic strides of the op from provided
47 /// external static and dynamic strides.
48 SmallVector<OpFoldResult, 4> getMixedStrides(OffsetSizeAndStrideOpInterface op,
49                                              ArrayAttr staticStrides,
50                                              ValueRange strides);
51 
52 /// Decompose a vector of mixed static or dynamic strides/offsets into the
53 /// corresponding pair of arrays. This is the inverse function of
54 /// `getMixedStrides` and `getMixedOffsets`.
55 std::pair<ArrayAttr, SmallVector<Value>> decomposeMixedStridesOrOffsets(
56     OpBuilder &b, const SmallVectorImpl<OpFoldResult> &mixedValues);
57 
58 /// Decompose a vector of mixed static or dynamic strides/offsets into the
59 /// corresponding pair of arrays. This is the inverse function of
60 /// `getMixedSizes`.
61 std::pair<ArrayAttr, SmallVector<Value>>
62 decomposeMixedSizes(OpBuilder &b,
63                     const SmallVectorImpl<OpFoldResult> &mixedValues);
64 
65 namespace detail {
66 LogicalResult verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op);
67 
68 bool sameOffsetsSizesAndStrides(
69     OffsetSizeAndStrideOpInterface a, OffsetSizeAndStrideOpInterface b,
70     llvm::function_ref<bool(OpFoldResult, OpFoldResult)> cmp);
71 } // namespace detail
72 } // namespace mlir
73 
74 /// Include the generated interface declarations.
75 #include "mlir/Interfaces/ViewLikeInterface.h.inc"
76 
77 namespace mlir {
78 
79 /// Printer hook for custom directive in assemblyFormat.
80 ///
81 ///   custom<OperandsOrIntegersOffsetsOrStridesList>($values, $integers)
82 ///
83 /// where `values` is of ODS type `Variadic<Index>` and `integers` is of ODS
84 /// type `I64ArrayAttr`.  for use in in assemblyFormat. Prints a list with
85 /// either (1) the static integer value in `integers` if the value is
86 /// ShapedType::kDynamicStrideOrOffset or (2) the next value otherwise.  This
87 /// allows idiomatic printing of mixed value and integer attributes in a
88 /// list. E.g. `[%arg0, 7, 42, %arg42]`.
89 void printOperandsOrIntegersOffsetsOrStridesList(OpAsmPrinter &printer,
90                                                  Operation *op,
91                                                  OperandRange values,
92                                                  ArrayAttr integers);
93 
94 /// Printer hook for custom directive in assemblyFormat.
95 ///
96 ///   custom<OperandsOrIntegersSizesList>($values, $integers)
97 ///
98 /// where `values` is of ODS type `Variadic<Index>` and `integers` is of ODS
99 /// type `I64ArrayAttr`.  for use in in assemblyFormat. Prints a list with
100 /// either (1) the static integer value in `integers` if the value is
101 /// ShapedType::kDynamicSize or (2) the next value otherwise.  This
102 /// allows idiomatic printing of mixed value and integer attributes in a
103 /// list. E.g. `[%arg0, 7, 42, %arg42]`.
104 void printOperandsOrIntegersSizesList(OpAsmPrinter &printer, Operation *op,
105                                       OperandRange values, ArrayAttr integers);
106 
107 /// Pasrer hook for custom directive in assemblyFormat.
108 ///
109 ///   custom<OperandsOrIntegersOffsetsOrStridesList>($values, $integers)
110 ///
111 /// where `values` is of ODS type `Variadic<Index>` and `integers` is of ODS
112 /// type `I64ArrayAttr`.  for use in in assemblyFormat. Parse a mixed list with
113 /// either (1) static integer values or (2) SSA values.  Fill `integers` with
114 /// the integer ArrayAttr, where ShapedType::kDynamicStrideOrOffset encodes the
115 /// position of SSA values. Add the parsed SSA values to `values` in-order.
116 //
117 /// E.g. after parsing "[%arg0, 7, 42, %arg42]":
118 ///   1. `result` is filled with the i64 ArrayAttr "[`dynVal`, 7, 42, `dynVal`]"
119 ///   2. `ssa` is filled with "[%arg0, %arg1]".
120 ParseResult parseOperandsOrIntegersOffsetsOrStridesList(
121     OpAsmParser &parser,
122     SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,
123     ArrayAttr &integers);
124 
125 /// Pasrer hook for custom directive in assemblyFormat.
126 ///
127 ///   custom<OperandsOrIntegersSizesList>($values, $integers)
128 ///
129 /// where `values` is of ODS type `Variadic<Index>` and `integers` is of ODS
130 /// type `I64ArrayAttr`.  for use in in assemblyFormat. Parse a mixed list with
131 /// either (1) static integer values or (2) SSA values.  Fill `integers` with
132 /// the integer ArrayAttr, where ShapedType::kDynamicSize encodes the
133 /// position of SSA values. Add the parsed SSA values to `values` in-order.
134 //
135 /// E.g. after parsing "[%arg0, 7, 42, %arg42]":
136 ///   1. `result` is filled with the i64 ArrayAttr "[`dynVal`, 7, 42, `dynVal`]"
137 ///   2. `ssa` is filled with "[%arg0, %arg1]".
138 ParseResult parseOperandsOrIntegersSizesList(
139     OpAsmParser &parser,
140     SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,
141     ArrayAttr &integers);
142 
143 /// Verify that a the `values` has as many elements as the number of entries in
144 /// `attr` for which `isDynamic` evaluates to true.
145 LogicalResult verifyListOfOperandsOrIntegers(
146     Operation *op, StringRef name, unsigned expectedNumElements, ArrayAttr attr,
147     ValueRange values, llvm::function_ref<bool(int64_t)> isDynamic);
148 
149 } // namespace mlir
150 
151 #endif // MLIR_INTERFACES_VIEWLIKEINTERFACE_H_
152