MLIR  20.0.0git
ViewLikeInterface.h
Go to the documentation of this file.
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 
17 #include "mlir/IR/Builders.h"
19 #include "mlir/IR/BuiltinTypes.h"
21 #include "mlir/IR/PatternMatch.h"
22 
23 namespace mlir {
24 
25 class OffsetSizeAndStrideOpInterface;
26 
27 namespace detail {
28 
29 LogicalResult verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op);
30 
32  OffsetSizeAndStrideOpInterface a, OffsetSizeAndStrideOpInterface b,
33  llvm::function_ref<bool(OpFoldResult, OpFoldResult)> cmp);
34 
35 /// Helper method to compute the number of dynamic entries of `staticVals`,
36 /// up to `idx`.
37 unsigned getNumDynamicEntriesUpToIdx(ArrayRef<int64_t> staticVals,
38  unsigned idx);
39 
40 } // namespace detail
41 } // namespace mlir
42 
43 /// Include the generated interface declarations.
44 #include "mlir/Interfaces/ViewLikeInterface.h.inc"
45 
46 namespace mlir {
47 
48 /// Pattern to rewrite dynamic offsets/sizes/strides of view/slice-like ops as
49 /// constant arguments. This pattern assumes that the op has a suitable builder
50 /// that takes a result type, a "source" operand and mixed offsets, sizes and
51 /// strides.
52 ///
53 /// `OpType` is the type of op to which this pattern is applied. `ResultTypeFn`
54 /// returns the new result type of the op, based on the new offsets, sizes and
55 /// strides. `CastOpFunc` is used to generate a cast op if the result type of
56 /// the op has changed.
57 template <typename OpType, typename ResultTypeFn, typename CastOpFunc>
59  : public OpRewritePattern<OpType> {
60 public:
62 
63  LogicalResult matchAndRewrite(OpType op,
64  PatternRewriter &rewriter) const override {
65  SmallVector<OpFoldResult> mixedOffsets(op.getMixedOffsets());
66  SmallVector<OpFoldResult> mixedSizes(op.getMixedSizes());
67  SmallVector<OpFoldResult> mixedStrides(op.getMixedStrides());
68 
69  // No constant operands were folded, just return;
70  if (failed(foldDynamicIndexList(mixedOffsets, /*onlyNonNegative=*/true)) &&
71  failed(foldDynamicIndexList(mixedSizes, /*onlyNonNegative=*/true)) &&
72  failed(foldDynamicIndexList(mixedStrides)))
73  return failure();
74 
75  // Create the new op in canonical form.
76  auto resultType =
77  ResultTypeFn()(op, mixedOffsets, mixedSizes, mixedStrides);
78  if (!resultType)
79  return failure();
80  auto newOp =
81  rewriter.create<OpType>(op.getLoc(), resultType, op.getSource(),
82  mixedOffsets, mixedSizes, mixedStrides);
83  CastOpFunc()(rewriter, op, newOp);
84 
85  return success();
86  }
87 };
88 
89 /// Printer hook for custom directive in assemblyFormat.
90 ///
91 /// custom<DynamicIndexList>($values, $integers)
92 /// custom<DynamicIndexList>($values, $integers, type($values))
93 ///
94 /// where `values` is of ODS type `Variadic<*>` and `integers` is of ODS
95 /// type `I64ArrayAttr`. Prints a list with either (1) the static integer value
96 /// in `integers` is `kDynamic` or (2) the next value otherwise. If `valueTypes`
97 /// is non-empty, it is expected to contain as many elements as `values`
98 /// indicating their types. This allows idiomatic printing of mixed value and
99 /// integer attributes in a list. E.g.
100 /// `[%arg0 : index, 7, 42, %arg42 : i32]`.
101 ///
102 /// Indices can be scalable. For example, "4" in "[2, [4], 8]" is scalable.
103 /// This notation is similar to how scalable dims are marked when defining
104 /// Vectors. For each value in `integers`, the corresponding `bool` in
105 /// `scalables` encodes whether it's a scalable index. If `scalableVals` is
106 /// empty then assume that all indices are non-scalable.
108  OpAsmPrinter &printer, Operation *op, OperandRange values,
109  ArrayRef<int64_t> integers, ArrayRef<bool> scalables,
110  TypeRange valueTypes = TypeRange(),
112 inline void printDynamicIndexList(OpAsmPrinter &printer, Operation *op,
113  OperandRange values,
114  ArrayRef<int64_t> integers,
115  AsmParser::Delimiter delimiter) {
116  return printDynamicIndexList(printer, op, values, integers, {}, TypeRange(),
117  delimiter);
118 }
120  OpAsmPrinter &printer, Operation *op, OperandRange values,
121  ArrayRef<int64_t> integers, TypeRange valueTypes = TypeRange(),
123  return printDynamicIndexList(printer, op, values, integers, {}, valueTypes,
124  delimiter);
125 }
126 
127 /// Parser hook for custom directive in assemblyFormat.
128 ///
129 /// custom<DynamicIndexList>($values, $integers)
130 /// custom<DynamicIndexList>($values, $integers, type($values))
131 ///
132 /// where `values` is of ODS type `Variadic<*>` and `integers` is of ODS
133 /// type `I64ArrayAttr`. Parse a mixed list with either (1) static integer
134 /// values or (2) SSA values. Fill `integers` with the integer ArrayAttr, where
135 /// `kDynamic` encodes the position of SSA values. Add the parsed SSA values
136 /// to `values` in-order. If `valueTypes` is non-null, fill it with types
137 /// corresponding to values; otherwise the caller must handle the types.
138 ///
139 /// E.g. after parsing "[%arg0 : index, 7, 42, %arg42 : i32]":
140 /// 1. `result` is filled with the i64 ArrayAttr "[`kDynamic`, 7, 42,
141 /// `kDynamic`]"
142 /// 2. `ssa` is filled with "[%arg0, %arg1]".
143 ///
144 /// Indices can be scalable. For example, "4" in "[2, [4], 8]" is scalable.
145 /// This notation is similar to how scalable dims are marked when defining
146 /// Vectors. For each value in `integers`, the corresponding `bool` in
147 /// `scalableVals` encodes whether it's a scalable index.
148 ParseResult parseDynamicIndexList(
149  OpAsmParser &parser,
150  SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,
151  DenseI64ArrayAttr &integers, DenseBoolArrayAttr &scalableVals,
152  SmallVectorImpl<Type> *valueTypes = nullptr,
154 inline ParseResult
157  DenseI64ArrayAttr &integers,
158  AsmParser::Delimiter delimiter) {
159  DenseBoolArrayAttr scalableVals = {};
160  return parseDynamicIndexList(parser, values, integers, scalableVals, nullptr,
161  delimiter);
162 }
163 inline ParseResult parseDynamicIndexList(
164  OpAsmParser &parser,
166  DenseI64ArrayAttr &integers, SmallVectorImpl<Type> *valueTypes = nullptr,
168  DenseBoolArrayAttr scalableVals = {};
169  return parseDynamicIndexList(parser, values, integers, scalableVals,
170  valueTypes, delimiter);
171 }
172 inline ParseResult parseDynamicIndexList(
173  OpAsmParser &parser,
175  DenseI64ArrayAttr &integers, SmallVectorImpl<Type> &valueTypes,
177  DenseBoolArrayAttr scalableVals = {};
178  return parseDynamicIndexList(parser, values, integers, scalableVals,
179  &valueTypes, delimiter);
180 }
181 inline ParseResult parseDynamicIndexList(
182  OpAsmParser &parser,
184  DenseI64ArrayAttr &integers, SmallVectorImpl<Type> &valueTypes,
185  DenseBoolArrayAttr &scalableVals,
187 
188  return parseDynamicIndexList(parser, values, integers, scalableVals,
189  &valueTypes, delimiter);
190 }
191 
192 /// Verify that a the `values` has as many elements as the number of entries in
193 /// `attr` for which `isDynamic` evaluates to true.
194 LogicalResult verifyListOfOperandsOrIntegers(Operation *op, StringRef name,
195  unsigned expectedNumElements,
196  ArrayRef<int64_t> attr,
197  ValueRange values);
198 
199 } // namespace mlir
200 
201 #endif // MLIR_INTERFACES_VIEWLIKEINTERFACE_H_
Delimiter
These are the supported delimiters around operand lists and region argument lists,...
@ Square
Square brackets surrounding zero or more operands.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:497
Pattern to rewrite dynamic offsets/sizes/strides of view/slice-like ops as constant arguments.
LogicalResult matchAndRewrite(OpType op, PatternRewriter &rewriter) const override
This class implements the operand iterators for the Operation class.
Definition: ValueRange.h:42
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
Definition: PatternMatch.h:791
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
Base class for DenseArrayAttr that is instantiated and specialized for each supported element type be...
bool sameOffsetsSizesAndStrides(OffsetSizeAndStrideOpInterface a, OffsetSizeAndStrideOpInterface b, llvm::function_ref< bool(OpFoldResult, OpFoldResult)> cmp)
unsigned getNumDynamicEntriesUpToIdx(ArrayRef< int64_t > staticVals, unsigned idx)
Helper method to compute the number of dynamic entries of staticVals, up to idx.
LogicalResult verifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op)
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
void printDynamicIndexList(OpAsmPrinter &printer, Operation *op, OperandRange values, ArrayRef< int64_t > integers, ArrayRef< bool > scalables, TypeRange valueTypes=TypeRange(), AsmParser::Delimiter delimiter=AsmParser::Delimiter::Square)
Printer hook for custom directive in assemblyFormat.
detail::DenseArrayAttrImpl< bool > DenseBoolArrayAttr
LogicalResult verifyListOfOperandsOrIntegers(Operation *op, StringRef name, unsigned expectedNumElements, ArrayRef< int64_t > attr, ValueRange values)
Verify that a the values has as many elements as the number of entries in attr for which isDynamic ev...
ParseResult parseDynamicIndexList(OpAsmParser &parser, SmallVectorImpl< OpAsmParser::UnresolvedOperand > &values, DenseI64ArrayAttr &integers, DenseBoolArrayAttr &scalableVals, SmallVectorImpl< Type > *valueTypes=nullptr, AsmParser::Delimiter delimiter=AsmParser::Delimiter::Square)
Parser hook for custom directive in assemblyFormat.
LogicalResult foldDynamicIndexList(SmallVectorImpl< OpFoldResult > &ofrs, bool onlyNonNegative=false, bool onlyNonZero=false)
Returns "success" when any of the elements in ofrs is a constant value.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...
Definition: PatternMatch.h:358