MLIR  21.0.0git
BuiltinTypes.h
Go to the documentation of this file.
1 //===- BuiltinTypes.h - MLIR Builtin Type Classes ---------------*- C++ -*-===//
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 #ifndef MLIR_IR_BUILTINTYPES_H
10 #define MLIR_IR_BUILTINTYPES_H
11 
14 #include "mlir/Support/ADTExtras.h"
15 
16 namespace llvm {
17 class BitVector;
18 struct fltSemantics;
19 } // namespace llvm
20 
21 //===----------------------------------------------------------------------===//
22 // Tablegen Interface Declarations
23 //===----------------------------------------------------------------------===//
24 
25 namespace mlir {
26 class AffineExpr;
27 class AffineMap;
28 class IndexType;
29 class IntegerType;
30 class MemRefType;
31 class RankedTensorType;
32 class StringAttr;
33 class TypeRange;
34 
35 namespace detail {
36 struct FunctionTypeStorage;
37 struct IntegerTypeStorage;
38 struct TupleTypeStorage;
39 } // namespace detail
40 
41 /// Type trait indicating that the type has value semantics.
42 template <typename ConcreteType>
44  : public TypeTrait::TraitBase<ConcreteType, ValueSemantics> {};
45 
46 //===----------------------------------------------------------------------===//
47 // TensorType
48 //===----------------------------------------------------------------------===//
49 
50 /// Tensor types represent multi-dimensional arrays, and have two variants:
51 /// RankedTensorType and UnrankedTensorType.
52 /// Note: This class attaches the ShapedType trait to act as a mixin to
53 /// provide many useful utility functions. This inheritance has no effect
54 /// on derived tensor types.
55 class TensorType : public Type, public ShapedType::Trait<TensorType> {
56 public:
57  using Type::Type;
58 
59  /// Returns the element type of this tensor type.
60  Type getElementType() const;
61 
62  /// Returns if this type is ranked, i.e. it has a known number of dimensions.
63  bool hasRank() const;
64 
65  /// Returns the shape of this tensor type.
67 
68  /// Clone this type with the given shape and element type. If the
69  /// provided shape is `std::nullopt`, the current shape of the type is used.
70  TensorType cloneWith(std::optional<ArrayRef<int64_t>> shape,
71  Type elementType) const;
72 
73  // Make sure that base class overloads are visible.
75 
76  /// Return a clone of this type with the given new shape and element type.
77  /// The returned type is ranked, even if this type is unranked.
78  RankedTensorType clone(ArrayRef<int64_t> shape, Type elementType) const;
79 
80  /// Return a clone of this type with the given new shape. The returned type
81  /// is ranked, even if this type is unranked.
82  RankedTensorType clone(ArrayRef<int64_t> shape) const;
83 
84  /// Return true if the specified element type is ok in a tensor.
85  static bool isValidElementType(Type type);
86 
87  /// Methods for support type inquiry through isa, cast, and dyn_cast.
88  static bool classof(Type type);
89 
90  /// Allow implicit conversion to ShapedType.
91  operator ShapedType() const { return llvm::cast<ShapedType>(*this); }
92 };
93 
94 //===----------------------------------------------------------------------===//
95 // BaseMemRefType
96 //===----------------------------------------------------------------------===//
97 
98 /// This class provides a shared interface for ranked and unranked memref types.
99 /// Note: This class attaches the ShapedType trait to act as a mixin to
100 /// provide many useful utility functions. This inheritance has no effect
101 /// on derived memref types.
102 class BaseMemRefType : public Type,
103  public PtrLikeTypeInterface::Trait<BaseMemRefType>,
104  public ShapedType::Trait<BaseMemRefType> {
105 public:
106  using Type::Type;
107 
108  /// Returns the element type of this memref type.
109  Type getElementType() const;
110 
111  /// Returns if this type is ranked, i.e. it has a known number of dimensions.
112  bool hasRank() const;
113 
114  /// Returns the shape of this memref type.
115  ArrayRef<int64_t> getShape() const;
116 
117  /// Clone this type with the given shape and element type. If the
118  /// provided shape is `std::nullopt`, the current shape of the type is used.
119  BaseMemRefType cloneWith(std::optional<ArrayRef<int64_t>> shape,
120  Type elementType) const;
121 
122  /// Clone this type with the given memory space and element type. If the
123  /// provided element type is `std::nullopt`, the current element type of the
124  /// type is used.
125  FailureOr<PtrLikeTypeInterface>
126  clonePtrWith(Attribute memorySpace, std::optional<Type> elementType) const;
127 
128  // Make sure that base class overloads are visible.
130 
131  /// Return a clone of this type with the given new shape and element type.
132  /// The returned type is ranked, even if this type is unranked.
133  MemRefType clone(ArrayRef<int64_t> shape, Type elementType) const;
134 
135  /// Return a clone of this type with the given new shape. The returned type
136  /// is ranked, even if this type is unranked.
137  MemRefType clone(ArrayRef<int64_t> shape) const;
138 
139  /// Return true if the specified element type is ok in a memref.
140  static bool isValidElementType(Type type);
141 
142  /// Methods for support type inquiry through isa, cast, and dyn_cast.
143  static bool classof(Type type);
144 
145  /// Returns the memory space in which data referred to by this memref resides.
146  Attribute getMemorySpace() const;
147 
148  /// [deprecated] Returns the memory space in old raw integer representation.
149  /// New `Attribute getMemorySpace()` method should be used instead.
150  unsigned getMemorySpaceAsInt() const;
151 
152  /// Returns that this ptr-like object has non-empty ptr metadata.
153  bool hasPtrMetadata() const { return true; }
154 
155  /// Allow implicit conversion to ShapedType.
156  operator ShapedType() const { return llvm::cast<ShapedType>(*this); }
157 
158  /// Allow implicit conversion to PtrLikeTypeInterface.
159  operator PtrLikeTypeInterface() const {
160  return llvm::cast<PtrLikeTypeInterface>(*this);
161  }
162 };
163 
164 } // namespace mlir
165 
166 //===----------------------------------------------------------------------===//
167 // Tablegen Type Declarations
168 //===----------------------------------------------------------------------===//
169 
170 #define GET_TYPEDEF_CLASSES
171 #include "mlir/IR/BuiltinTypes.h.inc"
172 
173 namespace mlir {
174 #include "mlir/IR/BuiltinTypeConstraints.h.inc"
175 
176 //===----------------------------------------------------------------------===//
177 // MemRefType
178 //===----------------------------------------------------------------------===//
179 
180 /// This is a builder type that keeps local references to arguments. Arguments
181 /// that are passed into the builder must outlive the builder.
183 public:
184  // Build from another MemRefType.
185  explicit Builder(MemRefType other)
186  : shape(other.getShape()), elementType(other.getElementType()),
187  layout(other.getLayout()), memorySpace(other.getMemorySpace()) {}
188 
189  // Build from scratch.
190  Builder(ArrayRef<int64_t> shape, Type elementType)
191  : shape(shape), elementType(elementType) {}
192 
194  shape = newShape;
195  return *this;
196  }
197 
198  Builder &setElementType(Type newElementType) {
199  elementType = newElementType;
200  return *this;
201  }
202 
203  Builder &setLayout(MemRefLayoutAttrInterface newLayout) {
204  layout = newLayout;
205  return *this;
206  }
207 
208  Builder &setMemorySpace(Attribute newMemorySpace) {
209  memorySpace = newMemorySpace;
210  return *this;
211  }
212 
213  operator MemRefType() {
214  return MemRefType::get(shape, elementType, layout, memorySpace);
215  }
216 
217 private:
218  ArrayRef<int64_t> shape;
219  Type elementType;
220  MemRefLayoutAttrInterface layout;
221  Attribute memorySpace;
222 };
223 
224 //===----------------------------------------------------------------------===//
225 // RankedTensorType
226 //===----------------------------------------------------------------------===//
227 
228 /// This is a builder type that keeps local references to arguments. Arguments
229 /// that are passed into the builder must outlive the builder.
231 public:
232  /// Build from another RankedTensorType.
233  explicit Builder(RankedTensorType other)
234  : shape(other.getShape()), elementType(other.getElementType()),
235  encoding(other.getEncoding()) {}
236 
237  /// Build from scratch.
238  Builder(ArrayRef<int64_t> shape, Type elementType, Attribute encoding)
239  : shape(shape), elementType(elementType), encoding(encoding) {}
240 
242  shape = newShape;
243  return *this;
244  }
245 
246  Builder &setElementType(Type newElementType) {
247  elementType = newElementType;
248  return *this;
249  }
250 
251  Builder &setEncoding(Attribute newEncoding) {
252  encoding = newEncoding;
253  return *this;
254  }
255 
256  /// Erase a dim from shape @pos.
257  Builder &dropDim(unsigned pos) {
258  assert(pos < shape.size() && "overflow");
259  shape.erase(pos);
260  return *this;
261  }
262 
263  /// Insert a val into shape @pos.
264  Builder &insertDim(int64_t val, unsigned pos) {
265  assert(pos <= shape.size() && "overflow");
266  shape.insert(pos, val);
267  return *this;
268  }
269 
270  operator RankedTensorType() {
271  return RankedTensorType::get(shape, elementType, encoding);
272  }
273 
274 private:
276  Type elementType;
277  Attribute encoding;
278 };
279 
280 //===----------------------------------------------------------------------===//
281 // VectorType
282 //===----------------------------------------------------------------------===//
283 
284 /// This is a builder type that keeps local references to arguments. Arguments
285 /// that are passed into the builder must outlive the builder.
287 public:
288  /// Build from another VectorType.
289  explicit Builder(VectorType other)
290  : elementType(other.getElementType()), shape(other.getShape()),
291  scalableDims(other.getScalableDims()) {}
292 
293  /// Build from scratch.
294  Builder(ArrayRef<int64_t> shape, Type elementType,
295  ArrayRef<bool> scalableDims = {})
296  : elementType(elementType), shape(shape), scalableDims(scalableDims) {}
297 
299  ArrayRef<bool> newIsScalableDim = {}) {
300  shape = newShape;
301  scalableDims = newIsScalableDim;
302  return *this;
303  }
304 
305  Builder &setElementType(Type newElementType) {
306  elementType = newElementType;
307  return *this;
308  }
309 
310  /// Erase a dim from shape @pos.
311  Builder &dropDim(unsigned pos) {
312  assert(pos < shape.size() && "overflow");
313  shape.erase(pos);
314  if (!scalableDims.empty())
315  scalableDims.erase(pos);
316  return *this;
317  }
318 
319  /// Set a dim in shape @pos to val.
320  Builder &setDim(unsigned pos, int64_t val) {
321  assert(pos < shape.size() && "overflow");
322  shape.set(pos, val);
323  return *this;
324  }
325 
326  operator VectorType() {
327  return VectorType::get(shape, elementType, scalableDims);
328  }
329 
330 private:
331  Type elementType;
333  CopyOnWriteArrayRef<bool> scalableDims;
334 };
335 
336 /// Given an `originalShape` and a `reducedShape` assumed to be a subset of
337 /// `originalShape` with some `1` entries erased, return the set of indices
338 /// that specifies which of the entries of `originalShape` are dropped to obtain
339 /// `reducedShape`. The returned mask can be applied as a projection to
340 /// `originalShape` to obtain the `reducedShape`. This mask is useful to track
341 /// which dimensions must be kept when e.g. compute MemRef strides under
342 /// rank-reducing operations. Return std::nullopt if reducedShape cannot be
343 /// obtained by dropping only `1` entries in `originalShape`.
344 /// If `matchDynamic` is true, then dynamic dims in `originalShape` and
345 /// `reducedShape` will be considered matching with non-dynamic dims, unless
346 /// the non-dynamic dim is from `originalShape` and equal to 1. For example,
347 /// in ([1, 3, ?], [?, 5]), the mask would be {1, 0, 0}, since 3 and 5 will
348 /// match with the corresponding dynamic dims.
349 std::optional<llvm::SmallDenseSet<unsigned>>
351  ArrayRef<int64_t> reducedShape,
352  bool matchDynamic = false);
353 
354 /// Enum that captures information related to verifier error conditions on
355 /// slice insert/extract type of ops.
357  Success,
358  RankTooLarge,
359  SizeMismatch,
361  // Error codes to ops with a memory space and a layout annotation.
364 };
365 
366 /// Check if `originalType` can be rank reduced to `candidateReducedType` type
367 /// by dropping some dimensions with static size `1`.
368 /// Return `SliceVerificationResult::Success` on success or an appropriate error
369 /// code.
370 SliceVerificationResult isRankReducedType(ShapedType originalType,
371  ShapedType candidateReducedType);
372 
373 //===----------------------------------------------------------------------===//
374 // Convenience wrappers for VectorType
375 //
376 // These are provided to allow idiomatic code like:
377 // * isa<vector::ScalableVectorType>(type)
378 //===----------------------------------------------------------------------===//
379 /// A vector type containing at least one scalable dimension.
380 class ScalableVectorType : public VectorType {
381 public:
382  using VectorType::VectorType;
383 
384  static bool classof(Type type) {
385  auto vecTy = llvm::dyn_cast<VectorType>(type);
386  if (!vecTy)
387  return false;
388  return vecTy.isScalable();
389  }
390 };
391 
392 /// A vector type with no scalable dimensions.
393 class FixedVectorType : public VectorType {
394 public:
395  using VectorType::VectorType;
396 
397  static bool classof(Type type) {
398  auto vecTy = llvm::dyn_cast<VectorType>(type);
399  if (!vecTy)
400  return false;
401  return !vecTy.isScalable();
402  }
403 };
404 
405 //===----------------------------------------------------------------------===//
406 // Deferred Method Definitions
407 //===----------------------------------------------------------------------===//
408 
409 inline bool BaseMemRefType::classof(Type type) {
410  return llvm::isa<MemRefType, UnrankedMemRefType>(type);
411 }
412 
414  return type.isIntOrIndexOrFloat() ||
415  llvm::isa<ComplexType, MemRefType, VectorType, UnrankedMemRefType>(
416  type) ||
417  llvm::isa<MemRefElementTypeInterface>(type);
418 }
419 
420 inline bool TensorType::classof(Type type) {
421  return llvm::isa<RankedTensorType, UnrankedTensorType>(type);
422 }
423 
424 //===----------------------------------------------------------------------===//
425 // Type Utilities
426 //===----------------------------------------------------------------------===//
427 
428 /// Given MemRef `sizes` that are either static or dynamic, returns the
429 /// canonical "contiguous" strides AffineExpr. Strides are multiplicative and
430 /// once a dynamic dimension is encountered, all canonical strides become
431 /// dynamic and need to be encoded with a different symbol.
432 /// For canonical strides expressions, the offset is always 0 and the fastest
433 /// varying stride is always `1`.
434 ///
435 /// Examples:
436 /// - memref<3x4x5xf32> has canonical stride expression
437 /// `20*exprs[0] + 5*exprs[1] + exprs[2]`.
438 /// - memref<3x?x5xf32> has canonical stride expression
439 /// `s0*exprs[0] + 5*exprs[1] + exprs[2]`.
440 /// - memref<3x4x?xf32> has canonical stride expression
441 /// `s1*exprs[0] + s0*exprs[1] + exprs[2]`.
443  ArrayRef<AffineExpr> exprs,
444  MLIRContext *context);
445 
446 /// Return the result of makeCanonicalStrudedLayoutExpr for the common case
447 /// where `exprs` is {d0, d1, .., d_(sizes.size()-1)}
449  MLIRContext *context);
450 } // namespace mlir
451 
452 #endif // MLIR_IR_BUILTINTYPES_H
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity,...
Definition: SPIRVOps.cpp:188
static ArrayRef< int64_t > getShape(Type type)
Returns the shape of the given type.
Definition: Traits.cpp:118
Base type for affine expression.
Definition: AffineExpr.h:68
Attributes are known-constant values of operations.
Definition: Attributes.h:25
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:104
MemRefType clone(ArrayRef< int64_t > shape) const
Return a clone of this type with the given new shape.
ArrayRef< int64_t > getShape() const
Returns the shape of this memref type.
static bool isValidElementType(Type type)
Return true if the specified element type is ok in a memref.
Definition: BuiltinTypes.h:413
FailureOr< PtrLikeTypeInterface > clonePtrWith(Attribute memorySpace, std::optional< Type > elementType) const
Clone this type with the given memory space and element type.
bool hasPtrMetadata() const
Returns that this ptr-like object has non-empty ptr metadata.
Definition: BuiltinTypes.h:153
Attribute getMemorySpace() const
Returns the memory space in which data referred to by this memref resides.
static bool classof(Type type)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: BuiltinTypes.h:409
unsigned getMemorySpaceAsInt() const
[deprecated] Returns the memory space in old raw integer representation.
bool hasRank() const
Returns if this type is ranked, i.e. it has a known number of dimensions.
Type getElementType() const
Returns the element type of this memref type.
MemRefType clone(ArrayRef< int64_t > shape, Type elementType) const
Return a clone of this type with the given new shape and element type.
BaseMemRefType cloneWith(std::optional< ArrayRef< int64_t >> shape, Type elementType) const
Clone this type with the given shape and element type.
void erase(size_t index)
Definition: ADTExtras.h:40
size_t size() const
Definition: ADTExtras.h:54
void insert(size_t index, T value)
Definition: ADTExtras.h:35
A vector type with no scalable dimensions.
Definition: BuiltinTypes.h:393
static bool classof(Type type)
Definition: BuiltinTypes.h:397
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
This is a builder type that keeps local references to arguments.
Definition: BuiltinTypes.h:182
Builder(ArrayRef< int64_t > shape, Type elementType)
Definition: BuiltinTypes.h:190
Builder & setLayout(MemRefLayoutAttrInterface newLayout)
Definition: BuiltinTypes.h:203
Builder & setElementType(Type newElementType)
Definition: BuiltinTypes.h:198
Builder(MemRefType other)
Definition: BuiltinTypes.h:185
Builder & setShape(ArrayRef< int64_t > newShape)
Definition: BuiltinTypes.h:193
Builder & setMemorySpace(Attribute newMemorySpace)
Definition: BuiltinTypes.h:208
This is a builder type that keeps local references to arguments.
Definition: BuiltinTypes.h:230
Builder(ArrayRef< int64_t > shape, Type elementType, Attribute encoding)
Build from scratch.
Definition: BuiltinTypes.h:238
Builder & dropDim(unsigned pos)
Erase a dim from shape @pos.
Definition: BuiltinTypes.h:257
Builder & setShape(ArrayRef< int64_t > newShape)
Definition: BuiltinTypes.h:241
Builder & insertDim(int64_t val, unsigned pos)
Insert a val into shape @pos.
Definition: BuiltinTypes.h:264
Builder(RankedTensorType other)
Build from another RankedTensorType.
Definition: BuiltinTypes.h:233
Builder & setElementType(Type newElementType)
Definition: BuiltinTypes.h:246
Builder & setEncoding(Attribute newEncoding)
Definition: BuiltinTypes.h:251
A vector type containing at least one scalable dimension.
Definition: BuiltinTypes.h:380
static bool classof(Type type)
Definition: BuiltinTypes.h:384
Tensor types represent multi-dimensional arrays, and have two variants: RankedTensorType and Unranked...
Definition: BuiltinTypes.h:55
RankedTensorType clone(ArrayRef< int64_t > shape) const
Return a clone of this type with the given new shape.
static bool classof(Type type)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: BuiltinTypes.h:420
TensorType cloneWith(std::optional< ArrayRef< int64_t >> shape, Type elementType) const
Clone this type with the given shape and element type.
static bool isValidElementType(Type type)
Return true if the specified element type is ok in a tensor.
ArrayRef< int64_t > getShape() const
Returns the shape of this tensor type.
bool hasRank() const
Returns if this type is ranked, i.e. it has a known number of dimensions.
RankedTensorType clone(ArrayRef< int64_t > shape, Type elementType) const
Return a clone of this type with the given new shape and element type.
Type getElementType() const
Returns the element type of this tensor type.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
constexpr Type()=default
bool isIntOrIndexOrFloat() const
Return true if this is an integer (of any signedness), index, or float type.
Definition: Types.cpp:120
Type trait indicating that the type has value semantics.
Definition: BuiltinTypes.h:44
This is a builder type that keeps local references to arguments.
Definition: BuiltinTypes.h:286
Builder & dropDim(unsigned pos)
Erase a dim from shape @pos.
Definition: BuiltinTypes.h:311
Builder & setDim(unsigned pos, int64_t val)
Set a dim in shape @pos to val.
Definition: BuiltinTypes.h:320
Builder & setShape(ArrayRef< int64_t > newShape, ArrayRef< bool > newIsScalableDim={})
Definition: BuiltinTypes.h:298
Builder & setElementType(Type newElementType)
Definition: BuiltinTypes.h:305
Builder(VectorType other)
Build from another VectorType.
Definition: BuiltinTypes.h:289
Builder(ArrayRef< int64_t > shape, Type elementType, ArrayRef< bool > scalableDims={})
Build from scratch.
Definition: BuiltinTypes.h:294
Helper class for implementing traits for storage classes.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
Include the generated interface declarations.
SliceVerificationResult
Enum that captures information related to verifier error conditions on slice insert/extract type of o...
Definition: BuiltinTypes.h:356
Operation * clone(OpBuilder &b, Operation *op, TypeRange newResultTypes, ValueRange newOperands)
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
AffineExpr makeCanonicalStridedLayoutExpr(ArrayRef< int64_t > sizes, ArrayRef< AffineExpr > exprs, MLIRContext *context)
Given MemRef sizes that are either static or dynamic, returns the canonical "contiguous" strides Affi...
std::optional< llvm::SmallDenseSet< unsigned > > computeRankReductionMask(ArrayRef< int64_t > originalShape, ArrayRef< int64_t > reducedShape, bool matchDynamic=false)
Given an originalShape and a reducedShape assumed to be a subset of originalShape with some 1 entries...
SliceVerificationResult isRankReducedType(ShapedType originalType, ShapedType candidateReducedType)
Check if originalType can be rank reduced to candidateReducedType type by dropping some dimensions wi...