xref: /llvm-project/mlir/include/mlir/Interfaces/ViewLikeInterface.td (revision 693a458287d019c5c6a66fe3019d099df2978cdb)
1//===- ViewLikeInterface.td - ViewLike interface -----------*- tablegen -*-===//
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// Defines the interface for view-like operations.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_INTERFACES_VIEWLIKEINTERFACE
14#define MLIR_INTERFACES_VIEWLIKEINTERFACE
15
16include "mlir/IR/OpBase.td"
17
18def ViewLikeOpInterface : OpInterface<"ViewLikeOpInterface"> {
19  let description = [{
20    A view-like operation "views" a buffer in a potentially different way. It
21    takes in a (view of) buffer (and potentially some other operands) and returns
22    another view of buffer.
23  }];
24  let cppNamespace = "::mlir";
25
26  let methods = [
27    InterfaceMethod<
28      "Returns the source buffer from which the view is created.",
29      "::mlir::Value", "getViewSource">
30  ];
31}
32
33def OffsetSizeAndStrideOpInterface : OpInterface<"OffsetSizeAndStrideOpInterface"> {
34  let description = [{
35    Common interface for ops that allow specifying mixed dynamic and static
36    offsets, sizes and strides variadic operands.
37    Ops that implement this interface need to expose the following methods:
38      1. `getArrayAttrMaxRanks` to specify the length of static integer
39          attributes.
40      2. `offsets`, `sizes` and `strides` variadic operands.
41      3. `static_offsets`, resp. `static_sizes` and `static_strides` integer
42          array attributes.
43      4. `getOffsetSizeAndStrideStartOperandIndex` method that specifies the
44         starting index of the OffsetSizeAndStrideOpInterface operands
45
46    The invariants of this interface are:
47      1. `static_offsets`, `static_sizes` and `static_strides` have length
48          exactly `getArrayAttrMaxRanks()`[0] (resp. [1], [2]).
49      2. `offsets`, `sizes` and `strides` have each length at most
50         `getArrayAttrMaxRanks()`[0] (resp. [1], [2]).
51      3. if an entry of `static_offsets` (resp. `static_sizes`,
52         `static_strides`) is equal to a special sentinel value, namely
53         `ShapedType::kDynamic`, then the corresponding entry is a dynamic
54         offset (resp. size, stride).
55      4. a variadic `offset` (resp. `sizes`, `strides`) operand  must be present
56         for each dynamic offset (resp. size, stride).
57      5. `offsets`, `sizes` and `strides` operands are specified in this order
58         at operand index starting at `getOffsetSizeAndStrideStartOperandIndex`.
59      6. `offsets` and `sizes` operands are non-negative.
60
61    This interface is useful to factor out common behavior and provide support
62    for carrying or injecting static behavior through the use of the static
63    attributes.
64  }];
65
66  let cppNamespace = "::mlir";
67
68  let methods = [
69    StaticInterfaceMethod<
70      /*desc=*/[{
71        Return the number of leading operands before the `offsets`, `sizes` and
72        and `strides` operands.
73      }],
74      /*retTy=*/"unsigned",
75      /*methodName=*/"getOffsetSizeAndStrideStartOperandIndex",
76      /*args=*/(ins)
77    >,
78    InterfaceMethod<
79      /*desc=*/[{
80        Return the expected rank of each of the`static_offsets`, `static_sizes`
81        and `static_strides` attributes.
82      }],
83      /*retTy=*/"std::array<unsigned, 3>",
84      /*methodName=*/"getArrayAttrMaxRanks",
85      /*args=*/(ins)
86    >,
87    InterfaceMethod<
88      /*desc=*/[{
89        Return the dynamic offset operands.
90      }],
91      /*retTy=*/"::mlir::OperandRange",
92      /*methodName=*/"getOffsets",
93      /*args=*/(ins),
94      /*methodBody=*/"",
95      /*defaultImplementation=*/[{
96        return $_op.getOffsets();
97      }]
98    >,
99    InterfaceMethod<
100      /*desc=*/[{
101        Return the dynamic size operands.
102      }],
103      /*retTy=*/"::mlir::OperandRange",
104      /*methodName=*/"getSizes",
105      /*args=*/(ins),
106      /*methodBody=*/"",
107      /*defaultImplementation=*/[{
108        return $_op.getSizes();
109      }]
110    >,
111    InterfaceMethod<
112      /*desc=*/[{
113        Return the dynamic stride operands.
114      }],
115      /*retTy=*/"::mlir::OperandRange",
116      /*methodName=*/"getStrides",
117      /*args=*/(ins),
118      /*methodBody=*/"",
119      /*defaultImplementation=*/[{
120        return $_op.getStrides();
121      }]
122    >,
123    InterfaceMethod<
124      /*desc=*/[{
125        Return the static offset attributes.
126      }],
127      /*retTy=*/"::llvm::ArrayRef<int64_t>",
128      /*methodName=*/"getStaticOffsets",
129      /*args=*/(ins),
130      /*methodBody=*/"",
131      /*defaultImplementation=*/[{
132        return $_op.getStaticOffsets();
133      }]
134    >,
135    InterfaceMethod<
136      /*desc=*/[{
137        Return the static size attributes.
138      }],
139      /*retTy=*/"::llvm::ArrayRef<int64_t>",
140      /*methodName=*/"getStaticSizes",
141      /*args=*/(ins),
142      /*methodBody=*/"",
143      /*defaultImplementation=*/[{
144        return $_op.getStaticSizes();
145      }]
146    >,
147    InterfaceMethod<
148      /*desc=*/[{
149        Return the dynamic stride attributes.
150      }],
151      /*retTy=*/"::llvm::ArrayRef<int64_t>",
152      /*methodName=*/"getStaticStrides",
153      /*args=*/(ins),
154      /*methodBody=*/"",
155      /*defaultImplementation=*/[{
156        return $_op.getStaticStrides();
157      }]
158    >,
159    InterfaceMethod<
160      /*desc=*/[{
161        Return a vector of all the static or dynamic offsets of the op.
162      }],
163      /*retTy=*/"::llvm::SmallVector<::mlir::OpFoldResult, 4>",
164      /*methodName=*/"getMixedOffsets",
165      /*args=*/(ins),
166      /*methodBody=*/"",
167      /*defaultImplementation=*/[{
168        Builder b($_op->getContext());
169        return ::mlir::getMixedValues($_op.getStaticOffsets(),
170                                      $_op.getOffsets(), b);
171      }]
172    >,
173    InterfaceMethod<
174      /*desc=*/[{
175        Return a vector of all the static or dynamic sizes of the op.
176      }],
177      /*retTy=*/"::llvm::SmallVector<::mlir::OpFoldResult, 4>",
178      /*methodName=*/"getMixedSizes",
179      /*args=*/(ins),
180      /*methodBody=*/"",
181      /*defaultImplementation=*/[{
182        Builder b($_op->getContext());
183        return
184            ::mlir::getMixedValues($_op.getStaticSizes(), $_op.getSizes(), b);
185      }]
186    >,
187    InterfaceMethod<
188      /*desc=*/[{
189        Return a vector of all the static or dynamic strides of the op.
190      }],
191      /*retTy=*/"::llvm::SmallVector<::mlir::OpFoldResult, 4>",
192      /*methodName=*/"getMixedStrides",
193      /*args=*/(ins),
194      /*methodBody=*/"",
195      /*defaultImplementation=*/[{
196        Builder b($_op->getContext());
197        return ::mlir::getMixedValues($_op.getStaticStrides(),
198                                      $_op.getStrides(), b);
199      }]
200    >,
201
202    InterfaceMethod<
203      /*desc=*/"Return true if the offset `idx` is dynamic.",
204      /*retTy=*/"bool",
205      /*methodName=*/"isDynamicOffset",
206      /*args=*/(ins "unsigned":$idx),
207      /*methodBody=*/"",
208      /*defaultImplementation=*/[{
209        return ::mlir::ShapedType::isDynamic(getStaticOffsets()[idx]);
210      }]
211    >,
212    InterfaceMethod<
213      /*desc=*/"Return true if the size `idx` is dynamic.",
214      /*retTy=*/"bool",
215      /*methodName=*/"isDynamicSize",
216      /*args=*/(ins "unsigned":$idx),
217      /*methodBody=*/"",
218      /*defaultImplementation=*/[{
219        return ::mlir::ShapedType::isDynamic(getStaticSizes()[idx]);
220      }]
221    >,
222    InterfaceMethod<
223      /*desc=*/"Return true if the stride `idx` is dynamic.",
224      /*retTy=*/"bool",
225      /*methodName=*/"isDynamicStride",
226      /*args=*/(ins "unsigned":$idx),
227      /*methodBody=*/"",
228      /*defaultImplementation=*/[{
229        return ::mlir::ShapedType::isDynamic(getStaticStrides()[idx]);
230      }]
231    >,
232    InterfaceMethod<
233      /*desc=*/[{
234        Assert the offset `idx` is a static constant and return its value.
235      }],
236      /*retTy=*/"int64_t",
237      /*methodName=*/"getStaticOffset",
238      /*args=*/(ins "unsigned":$idx),
239      /*methodBody=*/"",
240      /*defaultImplementation=*/[{
241        assert(!$_op.isDynamicOffset(idx) && "expected static offset");
242        return getStaticOffsets()[idx];
243      }]
244    >,
245    InterfaceMethod<
246      /*desc=*/[{
247        Assert the size `idx` is a static constant and return its value.
248      }],
249      /*retTy=*/"int64_t",
250      /*methodName=*/"getStaticSize",
251      /*args=*/(ins "unsigned":$idx),
252      /*methodBody=*/"",
253      /*defaultImplementation=*/[{
254        assert(!$_op.isDynamicSize(idx) && "expected static size");
255        return getStaticSizes()[idx];
256      }]
257    >,
258    InterfaceMethod<
259      /*desc=*/[{
260        Assert the stride `idx` is a static constant and return its value.
261      }],
262      /*retTy=*/"int64_t",
263      /*methodName=*/"getStaticStride",
264      /*args=*/(ins "unsigned":$idx),
265      /*methodBody=*/"",
266      /*defaultImplementation=*/[{
267        assert(!$_op.isDynamicStride(idx) && "expected static stride");
268        return getStaticStrides()[idx];
269      }]
270    >,
271
272    InterfaceMethod<
273      /*desc=*/[{
274        Assert the offset `idx` is dynamic and return the position of the
275        corresponding operand.
276      }],
277      /*retTy=*/"unsigned",
278      /*methodName=*/"getIndexOfDynamicOffset",
279      /*args=*/(ins "unsigned":$idx),
280      /*methodBody=*/"",
281      /*defaultImplementation=*/[{
282        assert($_op.isDynamicOffset(idx) && "expected dynamic offset");
283        auto numDynamic = ::mlir::detail::getNumDynamicEntriesUpToIdx(
284          getStaticOffsets(), idx);
285        return $_op.getOffsetSizeAndStrideStartOperandIndex() + numDynamic;
286      }]
287    >,
288    InterfaceMethod<
289      /*desc=*/[{
290        Assert the size `idx` is dynamic and return the position of the
291        corresponding operand.
292      }],
293      /*retTy=*/"unsigned",
294      /*methodName=*/"getIndexOfDynamicSize",
295      /*args=*/(ins "unsigned":$idx),
296      /*methodBody=*/"",
297      /*defaultImplementation=*/[{
298        assert($_op.isDynamicSize(idx) && "expected dynamic size");
299        auto numDynamic = ::mlir::detail::getNumDynamicEntriesUpToIdx(
300          getStaticSizes(), idx);
301        return $_op.getOffsetSizeAndStrideStartOperandIndex() +
302          getOffsets().size() + numDynamic;
303      }]
304    >,
305    InterfaceMethod<
306      /*desc=*/[{
307        Assert the stride `idx` is dynamic and return the position of the
308        corresponding operand.
309      }],
310      /*retTy=*/"unsigned",
311      /*methodName=*/"getIndexOfDynamicStride",
312      /*args=*/(ins "unsigned":$idx),
313      /*methodBody=*/"",
314      /*defaultImplementation=*/[{
315        assert($_op.isDynamicStride(idx) && "expected dynamic stride");
316        auto numDynamic = ::mlir::detail::getNumDynamicEntriesUpToIdx(
317          getStaticStrides(), idx);
318        return $_op.getOffsetSizeAndStrideStartOperandIndex() +
319          getOffsets().size() + getSizes().size() + numDynamic;
320      }]
321    >,
322    InterfaceMethod<
323      /*desc=*/[{
324        Assert the offset `idx` is dynamic and return its value.
325      }],
326      /*retTy=*/"::mlir::Value",
327      /*methodName=*/"getDynamicOffset",
328      /*args=*/(ins "unsigned":$idx),
329      /*methodBody=*/"",
330      /*defaultImplementation=*/[{
331        return $_op.getOperand(getIndexOfDynamicOffset(idx));
332      }]
333    >,
334    InterfaceMethod<
335      /*desc=*/[{
336        Assert the size `idx` is dynamic and return its value.
337      }],
338      /*retTy=*/"::mlir::Value",
339      /*methodName=*/"getDynamicSize",
340      /*args=*/(ins "unsigned":$idx),
341      /*methodBody=*/"",
342      /*defaultImplementation=*/[{
343        return $_op.getOperand(getIndexOfDynamicSize(idx));
344      }]
345    >,
346    InterfaceMethod<
347      /*desc=*/[{
348        Assert the stride `idx` is dynamic and return its value.
349      }],
350      /*retTy=*/"::mlir::Value",
351      /*methodName=*/"getDynamicStride",
352      /*args=*/(ins "unsigned":$idx),
353      /*methodBody=*/"",
354      /*defaultImplementation=*/[{
355        return $_op.getOperand(getIndexOfDynamicStride(idx));
356      }]
357    >,
358    InterfaceMethod<
359      /*desc=*/[{
360        Return true if all `other`'s offsets, sizes and strides are the same.
361        Takes a custom `cmp` comparison function on OpFoldResult to avoid taking
362        a dialect dependence.
363      }],
364      /*retTy=*/"bool",
365      /*methodName=*/"isSameAs",
366      /*args=*/(ins "::mlir::OffsetSizeAndStrideOpInterface":$other,
367                    "::llvm::function_ref<bool(::mlir::OpFoldResult, ::mlir::OpFoldResult)>":$cmp),
368      /*methodBody=*/"",
369      /*defaultImplementation=*/[{
370        return ::mlir::detail::sameOffsetsSizesAndStrides(
371          ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(
372            $_op.getOperation()), other, cmp);
373      }]
374    >,
375    InterfaceMethod<
376      /*desc=*/[{ Return true if all strides are guaranteed to be 1. }],
377      /*retTy=*/"bool",
378      /*methodName=*/"hasUnitStride",
379      /*args=*/(ins),
380      /*methodBody=*/"",
381      /*defaultImplementation=*/[{
382        return ::llvm::all_of(getMixedStrides(), [](::mlir::OpFoldResult ofr) {
383          return ::mlir::getConstantIntValue(ofr) == static_cast<int64_t>(1);
384        });
385      }]
386    >,
387    InterfaceMethod<
388      /*desc=*/[{ Return true if all offsets are guaranteed to be 0. }],
389      /*retTy=*/"bool",
390      /*methodName=*/"hasZeroOffset",
391      /*args=*/(ins),
392      /*methodBody=*/"",
393      /*defaultImplementation=*/[{
394        return ::llvm::all_of(getMixedOffsets(), [](::mlir::OpFoldResult ofr) {
395          return ::mlir::getConstantIntValue(ofr) == static_cast<int64_t>(0);
396        });
397      }]
398    >,
399  ];
400
401  let verify = [{
402    return ::mlir::detail::verifyOffsetSizeAndStrideOp(
403        ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>($_op));
404  }];
405}
406
407#endif // MLIR_INTERFACES_VIEWLIKEINTERFACE
408