Coverage Report

Created: 2020-06-26 05:44

/home/arjun/llvm-project/mlir/include/mlir/IR/Types.h
Line
Count
Source (jump to first uncovered line)
1
//===- Types.h - MLIR 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_TYPES_H
10
#define MLIR_IR_TYPES_H
11
12
#include "mlir/IR/TypeSupport.h"
13
#include "llvm/ADT/ArrayRef.h"
14
#include "llvm/ADT/DenseMapInfo.h"
15
#include "llvm/Support/PointerLikeTypeTraits.h"
16
17
namespace mlir {
18
class FloatType;
19
class Identifier;
20
class IndexType;
21
class IntegerType;
22
class MLIRContext;
23
class TypeStorage;
24
25
namespace detail {
26
struct FunctionTypeStorage;
27
struct OpaqueTypeStorage;
28
} // namespace detail
29
30
/// Instances of the Type class are immutable and uniqued.  They wrap a pointer
31
/// to the storage object owned by MLIRContext.  Therefore, instances of Type
32
/// are passed around by value.
33
///
34
/// Some types are "primitives" meaning they do not have any parameters, for
35
/// example the Index type.  Parametric types have additional information that
36
/// differentiates the types of the same kind between them, for example the
37
/// Integer type has bitwidth, making i8 and i16 belong to the same kind by be
38
/// different instances of the IntegerType.
39
///
40
/// Types are constructed and uniqued via the 'detail::TypeUniquer' class.
41
///
42
/// Derived type classes are expected to implement several required
43
/// implementation hooks:
44
///  * Required:
45
///    - static bool kindof(unsigned kind);
46
///      * Returns if the provided type kind corresponds to an instance of the
47
///        current type. Used for isa/dyn_cast casting functionality.
48
///
49
///  * Optional:
50
///    - static LogicalResult verifyConstructionInvariants(Location loc,
51
///                                                        Args... args)
52
///      * This method is invoked when calling the 'TypeBase::get/getChecked'
53
///        methods to ensure that the arguments passed in are valid to construct
54
///        a type instance with.
55
///      * This method is expected to return failure if a type cannot be
56
///        constructed with 'args', success otherwise.
57
///      * 'args' must correspond with the arguments passed into the
58
///        'TypeBase::get' call after the type kind.
59
///
60
///
61
/// Type storage objects inherit from TypeStorage and contain the following:
62
///    - The type kind (for LLVM-style RTTI).
63
///    - The dialect that defined the type.
64
///    - Any parameters of the type.
65
/// For non-parametric types, a convenience DefaultTypeStorage is provided.
66
/// Parametric storage types must derive TypeStorage and respect the following:
67
///    - Define a type alias, KeyTy, to a type that uniquely identifies the
68
///      instance of the type within its kind.
69
///      * The key type must be constructible from the values passed into the
70
///        detail::TypeUniquer::get call after the type kind.
71
///      * If the KeyTy does not have an llvm::DenseMapInfo specialization, the
72
///        storage class must define a hashing method:
73
///         'static unsigned hashKey(const KeyTy &)'
74
///
75
///    - Provide a method, 'bool operator==(const KeyTy &) const', to
76
///      compare the storage instance against an instance of the key type.
77
///
78
///    - Provide a construction method:
79
///        'DerivedStorage *construct(TypeStorageAllocator &, const KeyTy &key)'
80
///      that builds a unique instance of the derived storage. The arguments to
81
///      this function are an allocator to store any uniqued data within the
82
///      context and the key type for this storage.
83
class Type {
84
public:
85
  /// Integer identifier for all the concrete type kinds.
86
  /// Note: This is not an enum class as each dialect will likely define a
87
  /// separate enumeration for the specific types that they define. Not being an
88
  /// enum class also simplifies the handling of type kinds by not requiring
89
  /// casts for each use.
90
  enum Kind {
91
    // Builtin types.
92
    Function,
93
    Opaque,
94
    LAST_BUILTIN_TYPE = Opaque,
95
96
  // Reserve type kinds for dialect specific type system extensions.
97
#define DEFINE_SYM_KIND_RANGE(Dialect)                                         \
98
  FIRST_##Dialect##_TYPE, LAST_##Dialect##_TYPE = FIRST_##Dialect##_TYPE + 0xff,
99
#include "DialectSymbolRegistry.def"
100
  };
101
102
  /// Utility class for implementing types.
103
  template <typename ConcreteType, typename BaseType,
104
            typename StorageType = DefaultTypeStorage>
105
  using TypeBase = detail::StorageUserBase<ConcreteType, BaseType, StorageType,
106
                                           detail::TypeUniquer>;
107
108
  using ImplType = TypeStorage;
109
110
0
  constexpr Type() : impl(nullptr) {}
111
  /* implicit */ Type(const ImplType *impl)
112
0
      : impl(const_cast<ImplType *>(impl)) {}
113
114
  Type(const Type &other) = default;
115
  Type &operator=(const Type &other) = default;
116
117
0
  bool operator==(Type other) const { return impl == other.impl; }
118
0
  bool operator!=(Type other) const { return !(*this == other); }
119
0
  explicit operator bool() const { return impl; }
120
121
0
  bool operator!() const { return impl == nullptr; }
122
123
  template <typename U> bool isa() const;
124
  template <typename U> U dyn_cast() const;
125
  template <typename U> U dyn_cast_or_null() const;
126
  template <typename U> U cast() const;
127
128
  // Support type casting Type to itself.
129
0
  static bool classof(Type) { return true; }
130
131
  /// Return the classification for this type.
132
  unsigned getKind() const;
133
134
  /// Return the LLVMContext in which this type was uniqued.
135
  MLIRContext *getContext() const;
136
137
  /// Get the dialect this type is registered to.
138
  Dialect &getDialect() const;
139
140
  // Convenience predicates.  This is only for floating point types,
141
  // derived types should use isa/dyn_cast.
142
  bool isIndex();
143
  bool isBF16();
144
  bool isF16();
145
  bool isF32();
146
  bool isF64();
147
148
  /// Return true if this is an integer type with the specified width.
149
  bool isInteger(unsigned width);
150
  /// Return true if this is a signless integer type (with the specified width).
151
  bool isSignlessInteger();
152
  bool isSignlessInteger(unsigned width);
153
  /// Return true if this is a signed integer type (with the specified width).
154
  bool isSignedInteger();
155
  bool isSignedInteger(unsigned width);
156
  /// Return true if this is an unsigned integer type (with the specified
157
  /// width).
158
  bool isUnsignedInteger();
159
  bool isUnsignedInteger(unsigned width);
160
161
  /// Return the bit width of an integer or a float type, assert failure on
162
  /// other types.
163
  unsigned getIntOrFloatBitWidth();
164
165
  /// Return true if this is a signless integer or index type.
166
  bool isSignlessIntOrIndex();
167
  /// Return true if this is a signless integer, index, or float type.
168
  bool isSignlessIntOrIndexOrFloat();
169
  /// Return true of this is a signless integer or a float type.
170
  bool isSignlessIntOrFloat();
171
172
  /// Return true if this is an integer (of any signedness) or an index type.
173
  bool isIntOrIndex();
174
  /// Return true if this is an integer (of any signedness) or a float type.
175
  bool isIntOrFloat();
176
  /// Return true if this is an integer (of any signedness), index, or float
177
  /// type.
178
  bool isIntOrIndexOrFloat();
179
180
  /// Print the current type.
181
  void print(raw_ostream &os);
182
  void dump();
183
184
  friend ::llvm::hash_code hash_value(Type arg);
185
186
  unsigned getSubclassData() const;
187
  void setSubclassData(unsigned val);
188
189
  /// Methods for supporting PointerLikeTypeTraits.
190
0
  const void *getAsOpaquePointer() const {
191
0
    return static_cast<const void *>(impl);
192
0
  }
193
0
  static Type getFromOpaquePointer(const void *pointer) {
194
0
    return Type(reinterpret_cast<ImplType *>(const_cast<void *>(pointer)));
195
0
  }
196
197
protected:
198
  ImplType *impl;
199
};
200
201
0
inline raw_ostream &operator<<(raw_ostream &os, Type type) {
202
0
  type.print(os);
203
0
  return os;
204
0
}
205
206
/// Function types map from a list of inputs to a list of results.
207
class FunctionType
208
    : public Type::TypeBase<FunctionType, Type, detail::FunctionTypeStorage> {
209
public:
210
  using Base::Base;
211
212
  static FunctionType get(ArrayRef<Type> inputs, ArrayRef<Type> results,
213
                          MLIRContext *context);
214
215
  // Input types.
216
0
  unsigned getNumInputs() const { return getSubclassData(); }
217
218
0
  Type getInput(unsigned i) const { return getInputs()[i]; }
219
220
  ArrayRef<Type> getInputs() const;
221
222
  // Result types.
223
  unsigned getNumResults() const;
224
225
0
  Type getResult(unsigned i) const { return getResults()[i]; }
226
227
  ArrayRef<Type> getResults() const;
228
229
  /// Methods for support type inquiry through isa, cast, and dyn_cast.
230
0
  static bool kindof(unsigned kind) { return kind == Kind::Function; }
231
};
232
233
/// Opaque types represent types of non-registered dialects. These are types
234
/// represented in their raw string form, and can only usefully be tested for
235
/// type equality.
236
class OpaqueType
237
    : public Type::TypeBase<OpaqueType, Type, detail::OpaqueTypeStorage> {
238
public:
239
  using Base::Base;
240
241
  /// Get or create a new OpaqueType with the provided dialect and string data.
242
  static OpaqueType get(Identifier dialect, StringRef typeData,
243
                        MLIRContext *context);
244
245
  /// Get or create a new OpaqueType with the provided dialect and string data.
246
  /// If the given identifier is not a valid namespace for a dialect, then a
247
  /// null type is returned.
248
  static OpaqueType getChecked(Identifier dialect, StringRef typeData,
249
                               MLIRContext *context, Location location);
250
251
  /// Returns the dialect namespace of the opaque type.
252
  Identifier getDialectNamespace() const;
253
254
  /// Returns the raw type data of the opaque type.
255
  StringRef getTypeData() const;
256
257
  /// Verify the construction of an opaque type.
258
  static LogicalResult verifyConstructionInvariants(Location loc,
259
                                                    Identifier dialect,
260
                                                    StringRef typeData);
261
262
0
  static bool kindof(unsigned kind) { return kind == Kind::Opaque; }
263
};
264
265
// Make Type hashable.
266
0
inline ::llvm::hash_code hash_value(Type arg) {
267
0
  return ::llvm::hash_value(arg.impl);
268
0
}
269
270
0
template <typename U> bool Type::isa() const {
271
0
  assert(impl && "isa<> used on a null type.");
272
0
  return U::classof(*this);
273
0
}
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_11IntegerTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_9FloatTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_11ComplexTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_10OpaqueTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_10VectorTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_9IndexTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_10MemRefTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_12FunctionTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_10TensorTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_18UnrankedMemRefTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_16RankedTensorTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_18UnrankedTensorTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_8NoneTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_10ShapedTypeEEEbv
Unexecuted instantiation: _ZNK4mlir4Type3isaINS_9TupleTypeEEEbv
274
0
template <typename U> U Type::dyn_cast() const {
275
0
  return isa<U>() ? U(impl) : U(nullptr);
276
0
}
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_10MemRefTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_10VectorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_16RankedTensorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_11IntegerTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_10ShapedTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_9FloatTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_18UnrankedMemRefTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_10TensorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_12FunctionTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_11ComplexTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_9TupleTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type8dyn_castINS_10OpaqueTypeEEET_v
277
template <typename U> U Type::dyn_cast_or_null() const {
278
  return (impl && isa<U>()) ? U(impl) : U(nullptr);
279
}
280
0
template <typename U> U Type::cast() const {
281
0
  assert(isa<U>());
282
0
  return U(impl);
283
0
}
Unexecuted instantiation: _ZNK4mlir4Type4castINS_10MemRefTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_10VectorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_10TensorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_12FunctionTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_11IntegerTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_10ShapedTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_11ComplexTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_10OpaqueTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_16RankedTensorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_18UnrankedTensorTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_18UnrankedMemRefTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_9TupleTypeEEET_v
Unexecuted instantiation: _ZNK4mlir4Type4castINS_9FloatTypeEEET_v
284
285
} // end namespace mlir
286
287
namespace llvm {
288
289
// Type hash just like pointers.
290
template <> struct DenseMapInfo<mlir::Type> {
291
0
  static mlir::Type getEmptyKey() {
292
0
    auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
293
0
    return mlir::Type(static_cast<mlir::Type::ImplType *>(pointer));
294
0
  }
295
0
  static mlir::Type getTombstoneKey() {
296
0
    auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
297
0
    return mlir::Type(static_cast<mlir::Type::ImplType *>(pointer));
298
0
  }
299
0
  static unsigned getHashValue(mlir::Type val) { return mlir::hash_value(val); }
300
0
  static bool isEqual(mlir::Type LHS, mlir::Type RHS) { return LHS == RHS; }
301
};
302
303
/// We align TypeStorage by 8, so allow LLVM to steal the low bits.
304
template <> struct PointerLikeTypeTraits<mlir::Type> {
305
public:
306
0
  static inline void *getAsVoidPointer(mlir::Type I) {
307
0
    return const_cast<void *>(I.getAsOpaquePointer());
308
0
  }
309
0
  static inline mlir::Type getFromVoidPointer(void *P) {
310
0
    return mlir::Type::getFromOpaquePointer(P);
311
0
  }
312
  static constexpr int NumLowBitsAvailable = 3;
313
};
314
315
} // namespace llvm
316
317
#endif // MLIR_IR_TYPES_H