MLIR  14.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 
13 #include "SubElementInterfaces.h"
14 
15 namespace llvm {
16 struct fltSemantics;
17 } // namespace llvm
18 
19 //===----------------------------------------------------------------------===//
20 // Tablegen Interface Declarations
21 //===----------------------------------------------------------------------===//
22 
23 #include "mlir/IR/BuiltinTypeInterfaces.h.inc"
24 
25 namespace mlir {
26 class AffineExpr;
27 class AffineMap;
28 class FloatType;
29 class IndexType;
30 class IntegerType;
31 class StringAttr;
32 class TypeRange;
33 
34 //===----------------------------------------------------------------------===//
35 // FloatType
36 //===----------------------------------------------------------------------===//
37 
38 class FloatType : public Type {
39 public:
40  using Type::Type;
41 
42  // Convenience factories.
43  static FloatType getBF16(MLIRContext *ctx);
44  static FloatType getF16(MLIRContext *ctx);
45  static FloatType getF32(MLIRContext *ctx);
46  static FloatType getF64(MLIRContext *ctx);
47  static FloatType getF80(MLIRContext *ctx);
48  static FloatType getF128(MLIRContext *ctx);
49 
50  /// Methods for support type inquiry through isa, cast, and dyn_cast.
51  static bool classof(Type type);
52 
53  /// Return the bitwidth of this float type.
54  unsigned getWidth();
55 
56  /// Get or create a new FloatType with bitwidth scaled by `scale`.
57  /// Return null if the scaled element type cannot be represented.
58  FloatType scaleElementBitwidth(unsigned scale);
59 
60  /// Return the floating semantics of this float type.
61  const llvm::fltSemantics &getFloatSemantics();
62 };
63 
64 //===----------------------------------------------------------------------===//
65 // TensorType
66 //===----------------------------------------------------------------------===//
67 
68 /// Tensor types represent multi-dimensional arrays, and have two variants:
69 /// RankedTensorType and UnrankedTensorType.
70 /// Note: This class attaches the ShapedType trait to act as a mixin to
71 /// provide many useful utility functions. This inheritance has no effect
72 /// on derived tensor types.
73 class TensorType : public Type, public ShapedType::Trait<TensorType> {
74 public:
75  using Type::Type;
76 
77  /// Returns the element type of this tensor type.
78  Type getElementType() const;
79 
80  /// Returns if this type is ranked, i.e. it has a known number of dimensions.
81  bool hasRank() const;
82 
83  /// Returns the shape of this tensor type.
85 
86  /// Clone this type with the given shape and element type. If the
87  /// provided shape is `None`, the current shape of the type is used.
88  TensorType cloneWith(Optional<ArrayRef<int64_t>> shape,
89  Type elementType) const;
90 
91  /// Return true if the specified element type is ok in a tensor.
92  static bool isValidElementType(Type type);
93 
94  /// Methods for support type inquiry through isa, cast, and dyn_cast.
95  static bool classof(Type type);
96 
97  /// Allow implicit conversion to ShapedType.
98  operator ShapedType() const { return cast<ShapedType>(); }
99 };
100 
101 //===----------------------------------------------------------------------===//
102 // BaseMemRefType
103 //===----------------------------------------------------------------------===//
104 
105 /// This class provides a shared interface for ranked and unranked memref types.
106 /// Note: This class attaches the ShapedType trait to act as a mixin to
107 /// provide many useful utility functions. This inheritance has no effect
108 /// on derived memref types.
109 class BaseMemRefType : public Type, public ShapedType::Trait<BaseMemRefType> {
110 public:
111  using Type::Type;
112 
113  /// Returns the element type of this memref type.
114  Type getElementType() const;
115 
116  /// Returns if this type is ranked, i.e. it has a known number of dimensions.
117  bool hasRank() const;
118 
119  /// Returns the shape of this memref type.
120  ArrayRef<int64_t> getShape() const;
121 
122  /// Clone this type with the given shape and element type. If the
123  /// provided shape is `None`, the current shape of the type is used.
124  BaseMemRefType cloneWith(Optional<ArrayRef<int64_t>> shape,
125  Type elementType) const;
126 
127  /// Return true if the specified element type is ok in a memref.
128  static bool isValidElementType(Type type);
129 
130  /// Methods for support type inquiry through isa, cast, and dyn_cast.
131  static bool classof(Type type);
132 
133  /// Returns the memory space in which data referred to by this memref resides.
134  Attribute getMemorySpace() const;
135 
136  /// [deprecated] Returns the memory space in old raw integer representation.
137  /// New `Attribute getMemorySpace()` method should be used instead.
138  unsigned getMemorySpaceAsInt() const;
139 
140  /// Allow implicit conversion to ShapedType.
141  operator ShapedType() const { return cast<ShapedType>(); }
142 };
143 
144 } // namespace mlir
145 
146 //===----------------------------------------------------------------------===//
147 // Tablegen Type Declarations
148 //===----------------------------------------------------------------------===//
149 
150 #define GET_TYPEDEF_CLASSES
151 #include "mlir/IR/BuiltinTypes.h.inc"
152 
153 namespace mlir {
154 
155 //===----------------------------------------------------------------------===//
156 // MemRefType
157 //===----------------------------------------------------------------------===//
158 
159 /// This is a builder type that keeps local references to arguments. Arguments
160 /// that are passed into the builder must outlive the builder.
162 public:
163  // Build from another MemRefType.
164  explicit Builder(MemRefType other)
165  : shape(other.getShape()), elementType(other.getElementType()),
166  layout(other.getLayout()), memorySpace(other.getMemorySpace()) {}
167 
168  // Build from scratch.
169  Builder(ArrayRef<int64_t> shape, Type elementType)
170  : shape(shape), elementType(elementType) {}
171 
173  shape = newShape;
174  return *this;
175  }
176 
177  Builder &setElementType(Type newElementType) {
178  elementType = newElementType;
179  return *this;
180  }
181 
182  Builder &setLayout(MemRefLayoutAttrInterface newLayout) {
183  layout = newLayout;
184  return *this;
185  }
186 
187  Builder &setMemorySpace(Attribute newMemorySpace) {
188  memorySpace = newMemorySpace;
189  return *this;
190  }
191 
192  // [deprecated] `setMemorySpace(Attribute)` should be used instead.
193  Builder &setMemorySpace(unsigned newMemorySpace);
194 
195  operator MemRefType() {
196  return MemRefType::get(shape, elementType, layout, memorySpace);
197  }
198 
199 private:
200  ArrayRef<int64_t> shape;
201  Type elementType;
202  MemRefLayoutAttrInterface layout;
203  Attribute memorySpace;
204 };
205 
206 //===----------------------------------------------------------------------===//
207 // RankedTensorType
208 //===----------------------------------------------------------------------===//
209 
210 /// This is a builder type that keeps local references to arguments. Arguments
211 /// that are passed into the builder must outlive the builder.
213 public:
214  /// Build from another RankedTensorType.
215  explicit Builder(RankedTensorType other)
216  : shape(other.getShape()), elementType(other.getElementType()),
217  encoding(other.getEncoding()) {}
218 
219  /// Build from scratch.
220  Builder(ArrayRef<int64_t> shape, Type elementType, Attribute encoding)
221  : shape(shape), elementType(elementType), encoding(encoding) {}
222 
224  shape = newShape;
225  return *this;
226  }
227 
228  Builder &setElementType(Type newElementType) {
229  elementType = newElementType;
230  return *this;
231  }
232 
233  Builder &setEncoding(Attribute newEncoding) {
234  encoding = newEncoding;
235  return *this;
236  }
237 
238  /// Erase a dim from shape @pos.
239  Builder &dropDim(unsigned pos) {
240  assert(pos < shape.size() && "overflow");
241  if (storage.empty())
242  storage.append(shape.begin(), shape.end());
243  storage.erase(storage.begin() + pos);
244  shape = {storage.data(), storage.size()};
245  return *this;
246  }
247 
248  operator RankedTensorType() {
249  return RankedTensorType::get(shape, elementType, encoding);
250  }
251 
252 private:
253  ArrayRef<int64_t> shape;
254  // Owning shape data for copy-on-write operations.
255  SmallVector<int64_t> storage;
256  Type elementType;
257  Attribute encoding;
258 };
259 
260 //===----------------------------------------------------------------------===//
261 // VectorType
262 //===----------------------------------------------------------------------===//
263 
264 /// This is a builder type that keeps local references to arguments. Arguments
265 /// that are passed into the builder must outlive the builder.
267 public:
268  /// Build from another VectorType.
269  explicit Builder(VectorType other)
270  : shape(other.getShape()), elementType(other.getElementType()),
271  numScalableDims(other.getNumScalableDims()) {}
272 
273  /// Build from scratch.
274  Builder(ArrayRef<int64_t> shape, Type elementType,
275  unsigned numScalableDims = 0)
276  : shape(shape), elementType(elementType),
277  numScalableDims(numScalableDims) {}
278 
280  unsigned newNumScalableDims = 0) {
281  numScalableDims = newNumScalableDims;
282  shape = newShape;
283  return *this;
284  }
285 
286  Builder &setElementType(Type newElementType) {
287  elementType = newElementType;
288  return *this;
289  }
290 
291  /// Erase a dim from shape @pos.
292  Builder &dropDim(unsigned pos) {
293  assert(pos < shape.size() && "overflow");
294  if (pos >= shape.size() - numScalableDims)
295  numScalableDims--;
296  if (storage.empty())
297  storage.append(shape.begin(), shape.end());
298  storage.erase(storage.begin() + pos);
299  shape = {storage.data(), storage.size()};
300  return *this;
301  }
302 
303  /// In the particular case where the vector has a single dimension that we
304  /// drop, return the scalar element type.
305  // TODO: unify once we have a VectorType that supports 0-D.
306  operator Type() {
307  if (shape.empty())
308  return elementType;
309  return VectorType::get(shape, elementType, numScalableDims);
310  }
311 
312 private:
313  ArrayRef<int64_t> shape;
314  // Owning shape data for copy-on-write operations.
315  SmallVector<int64_t> storage;
316  Type elementType;
317  unsigned numScalableDims;
318 };
319 
320 /// Given an `originalShape` and a `reducedShape` assumed to be a subset of
321 /// `originalShape` with some `1` entries erased, return the set of indices
322 /// that specifies which of the entries of `originalShape` are dropped to obtain
323 /// `reducedShape`. The returned mask can be applied as a projection to
324 /// `originalShape` to obtain the `reducedShape`. This mask is useful to track
325 /// which dimensions must be kept when e.g. compute MemRef strides under
326 /// rank-reducing operations. Return None if reducedShape cannot be obtained
327 /// by dropping only `1` entries in `originalShape`.
330  ArrayRef<int64_t> reducedShape);
331 
332 /// Enum that captures information related to verifier error conditions on
333 /// slice insert/extract type of ops.
335  Success,
336  RankTooLarge,
337  SizeMismatch,
339  // Error codes to ops with a memory space and a layout annotation.
342 };
343 
344 /// Check if `originalType` can be rank reduced to `candidateReducedType` type
345 /// by dropping some dimensions with static size `1`.
346 /// Return `SliceVerificationResult::Success` on success or an appropriate error
347 /// code.
348 SliceVerificationResult isRankReducedType(ShapedType originalType,
349  ShapedType candidateReducedType);
350 
351 //===----------------------------------------------------------------------===//
352 // Deferred Method Definitions
353 //===----------------------------------------------------------------------===//
354 
355 inline bool BaseMemRefType::classof(Type type) {
356  return type.isa<MemRefType, UnrankedMemRefType>();
357 }
358 
359 inline bool BaseMemRefType::isValidElementType(Type type) {
360  return type.isIntOrIndexOrFloat() ||
361  type.isa<ComplexType, MemRefType, VectorType, UnrankedMemRefType>() ||
362  type.isa<MemRefElementTypeInterface>();
363 }
364 
365 inline bool FloatType::classof(Type type) {
366  return type.isa<BFloat16Type, Float16Type, Float32Type, Float64Type,
367  Float80Type, Float128Type>();
368 }
369 
370 inline FloatType FloatType::getBF16(MLIRContext *ctx) {
371  return BFloat16Type::get(ctx);
372 }
373 
374 inline FloatType FloatType::getF16(MLIRContext *ctx) {
375  return Float16Type::get(ctx);
376 }
377 
378 inline FloatType FloatType::getF32(MLIRContext *ctx) {
379  return Float32Type::get(ctx);
380 }
381 
382 inline FloatType FloatType::getF64(MLIRContext *ctx) {
383  return Float64Type::get(ctx);
384 }
385 
386 inline FloatType FloatType::getF80(MLIRContext *ctx) {
387  return Float80Type::get(ctx);
388 }
389 
390 inline FloatType FloatType::getF128(MLIRContext *ctx) {
391  return Float128Type::get(ctx);
392 }
393 
394 inline bool TensorType::classof(Type type) {
395  return type.isa<RankedTensorType, UnrankedTensorType>();
396 }
397 
398 //===----------------------------------------------------------------------===//
399 // Type Utilities
400 //===----------------------------------------------------------------------===//
401 
402 /// Returns the strides of the MemRef if the layout map is in strided form.
403 /// MemRefs with a layout map in strided form include:
404 /// 1. empty or identity layout map, in which case the stride information is
405 /// the canonical form computed from sizes;
406 /// 2. single affine map layout of the form `K + k0 * d0 + ... kn * dn`,
407 /// where K and ki's are constants or symbols.
408 ///
409 /// A stride specification is a list of integer values that are either static
410 /// or dynamic (encoded with getDynamicStrideOrOffset()). Strides encode the
411 /// distance in the number of elements between successive entries along a
412 /// particular dimension.
413 ///
414 /// For example, `memref<42x16xf32, (64 * d0 + d1)>` specifies a view into a
415 /// non-contiguous memory region of `42` by `16` `f32` elements in which the
416 /// distance between two consecutive elements along the outer dimension is `1`
417 /// and the distance between two consecutive elements along the inner dimension
418 /// is `64`.
419 ///
420 /// The convention is that the strides for dimensions d0, .. dn appear in
421 /// order to make indexing intuitive into the result.
423  SmallVectorImpl<int64_t> &strides,
424  int64_t &offset);
427  AffineExpr &offset);
428 
429 /// Given a list of strides (in which MemRefType::getDynamicStrideOrOffset()
430 /// represents a dynamic value), return the single result AffineMap which
431 /// represents the linearized strided layout map. Dimensions correspond to the
432 /// offset followed by the strides in order. Symbols are inserted for each
433 /// dynamic dimension in order. A stride cannot take value `0`.
434 ///
435 /// Examples:
436 /// =========
437 ///
438 /// 1. For offset: 0 strides: ?, ?, 1 return
439 /// (i, j, k)[M, N]->(M * i + N * j + k)
440 ///
441 /// 2. For offset: 3 strides: 32, ?, 16 return
442 /// (i, j, k)[M]->(3 + 32 * i + M * j + 16 * k)
443 ///
444 /// 3. For offset: ? strides: ?, ?, ? return
445 /// (i, j, k)[off, M, N, P]->(off + M * i + N * j + P * k)
447  MLIRContext *context);
448 
449 /// Return a version of `t` with identity layout if it can be determined
450 /// statically that the layout is the canonical contiguous strided layout.
451 /// Otherwise pass `t`'s layout into `simplifyAffineMap` and return a copy of
452 /// `t` with simplified layout.
453 MemRefType canonicalizeStridedLayout(MemRefType t);
454 
455 /// Return a version of `t` with a layout that has all dynamic offset and
456 /// strides. This is used to erase the static layout.
457 MemRefType eraseStridedLayout(MemRefType t);
458 
459 /// Given MemRef `sizes` that are either static or dynamic, returns the
460 /// canonical "contiguous" strides AffineExpr. Strides are multiplicative and
461 /// once a dynamic dimension is encountered, all canonical strides become
462 /// dynamic and need to be encoded with a different symbol.
463 /// For canonical strides expressions, the offset is always 0 and and fastest
464 /// varying stride is always `1`.
465 ///
466 /// Examples:
467 /// - memref<3x4x5xf32> has canonical stride expression
468 /// `20*exprs[0] + 5*exprs[1] + exprs[2]`.
469 /// - memref<3x?x5xf32> has canonical stride expression
470 /// `s0*exprs[0] + 5*exprs[1] + exprs[2]`.
471 /// - memref<3x4x?xf32> has canonical stride expression
472 /// `s1*exprs[0] + s0*exprs[1] + exprs[2]`.
474  ArrayRef<AffineExpr> exprs,
475  MLIRContext *context);
476 
477 /// Return the result of makeCanonicalStrudedLayoutExpr for the common case
478 /// where `exprs` is {d0, d1, .., d_(sizes.size()-1)}
480  MLIRContext *context);
481 
482 /// Return true if the layout for `t` is compatible with strided semantics.
483 bool isStrided(MemRefType t);
484 
485 /// Return the layout map in strided linear layout AffineMap form.
486 /// Return null if the layout is not compatible with a strided layout.
488 
489 /// Helper determining if a memref is static-shape and contiguous-row-major
490 /// layout, while still allowing for an arbitrary offset (any static or
491 /// dynamic value).
492 bool isStaticShapeAndContiguousRowMajor(MemRefType memrefType);
493 
494 } // namespace mlir
495 
496 #endif // MLIR_IR_BUILTINTYPES_H
Include the generated interface declarations.
MemRefType eraseStridedLayout(MemRefType t)
Return a version of t with a layout that has all dynamic offset and strides.
Builder(ArrayRef< int64_t > shape, Type elementType, unsigned numScalableDims=0)
Build from scratch.
Definition: BuiltinTypes.h:274
AffineMap getStridedLinearLayoutMap(MemRefType t)
Return the layout map in strided linear layout AffineMap form.
llvm::Optional< llvm::SmallDenseSet< unsigned > > computeRankReductionMask(ArrayRef< int64_t > originalShape, ArrayRef< int64_t > reducedShape)
Given an originalShape and a reducedShape assumed to be a subset of originalShape with some 1 entries...
bool isIntOrIndexOrFloat() const
Return true if this is an integer (of any signedness), index, or float type.
Definition: Types.cpp:89
AffineExpr makeCanonicalStridedLayoutExpr(ArrayRef< int64_t > sizes, MLIRContext *context)
Return the result of makeCanonicalStrudedLayoutExpr for the common case where exprs is {d0...
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:639
Builder & setEncoding(Attribute newEncoding)
Definition: BuiltinTypes.h:233
SliceVerificationResult isRankReducedType(ShapedType originalType, ShapedType candidateReducedType)
Check if originalType can be rank reduced to candidateReducedType type by dropping some dimensions wi...
static ArrayRef< int64_t > getShape(Type type)
Returns the shape of the given type.
Definition: Traits.cpp:117
Builder & dropDim(unsigned pos)
Erase a dim from shape .
Definition: BuiltinTypes.h:292
Builder(MemRefType other)
Definition: BuiltinTypes.h:164
Builder(RankedTensorType other)
Build from another RankedTensorType.
Definition: BuiltinTypes.h:215
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
bool isStrided(MemRefType t)
Return true if the layout for t is compatible with strided semantics.
Attributes are known-constant values of operations.
Definition: Attributes.h:24
SliceVerificationResult
Enum that captures information related to verifier error conditions on slice insert/extract type of o...
Definition: BuiltinTypes.h:334
Base type for affine expression.
Definition: AffineExpr.h:68
Builder & dropDim(unsigned pos)
Erase a dim from shape .
Definition: BuiltinTypes.h:239
A multi-dimensional affine map Affine map&#39;s are immutable like Type&#39;s, and they are uniqued...
Definition: AffineMap.h:38
Tensor types represent multi-dimensional arrays, and have two variants: RankedTensorType and Unranked...
Definition: BuiltinTypes.h:73
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
LogicalResult getStridesAndOffset(MemRefType t, SmallVectorImpl< AffineExpr > &strides, AffineExpr &offset)
This is a builder type that keeps local references to arguments.
Definition: BuiltinTypes.h:212
This is a builder type that keeps local references to arguments.
Definition: BuiltinTypes.h:266
Builder(VectorType other)
Build from another VectorType.
Definition: BuiltinTypes.h:269
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:109
Builder & setElementType(Type newElementType)
Definition: BuiltinTypes.h:177
This is a builder type that keeps local references to arguments.
Definition: BuiltinTypes.h:161
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
AffineMap makeStridedLinearLayoutMap(ArrayRef< int64_t > strides, int64_t offset, MLIRContext *context)
Given a list of strides (in which MemRefType::getDynamicStrideOrOffset() represents a dynamic value)...
MemRefType canonicalizeStridedLayout(MemRefType t)
Return a version of t with identity layout if it can be determined statically that the layout is the ...
Builder(ArrayRef< int64_t > shape, Type elementType, Attribute encoding)
Build from scratch.
Definition: BuiltinTypes.h:220
Builder & setMemorySpace(Attribute newMemorySpace)
Definition: BuiltinTypes.h:187
Builder(ArrayRef< int64_t > shape, Type elementType)
Definition: BuiltinTypes.h:169
Builder & setLayout(MemRefLayoutAttrInterface newLayout)
Definition: BuiltinTypes.h:182
Builder & setElementType(Type newElementType)
Definition: BuiltinTypes.h:286
bool isa() const
Definition: Types.h:234
Builder & setShape(ArrayRef< int64_t > newShape, unsigned newNumScalableDims=0)
Definition: BuiltinTypes.h:279
Builder & setShape(ArrayRef< int64_t > newShape)
Definition: BuiltinTypes.h:223
Builder & setShape(ArrayRef< int64_t > newShape)
Definition: BuiltinTypes.h:172
Builder & setElementType(Type newElementType)
Definition: BuiltinTypes.h:228
unsigned getMemorySpaceAsInt(Attribute memorySpace)
[deprecated] Returns the memory space in old raw integer representation.
bool isStaticShapeAndContiguousRowMajor(MemRefType memrefType)
Helper determining if a memref is static-shape and contiguous-row-major layout, while still allowing ...