MLIR 23.0.0git
Types.h
Go to the documentation of this file.
1//===- Types.h --------------------------------------------------*- 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_TOOLS_PDLL_AST_TYPES_H_
10#define MLIR_TOOLS_PDLL_AST_TYPES_H_
11
12#include "mlir/Support/LLVM.h"
14#include "llvm/ADT/SmallVectorExtras.h"
15#include <optional>
16
17namespace mlir {
18namespace pdll {
19namespace ods {
20class Operation;
21} // namespace ods
22
23namespace ast {
24class Context;
25
26//===----------------------------------------------------------------------===//
27// Type
28//===----------------------------------------------------------------------===//
29
30class Type {
31public:
32 /// This class represents the internal storage of the Type class.
33 struct Storage;
34
35 /// This class provides several utilities when defining derived type classes.
36 template <typename ImplT, typename BaseT = Type>
37 class TypeBase : public BaseT {
38 public:
40 using ImplTy = ImplT;
41 using BaseT::BaseT;
42
43 /// Provide type casting support.
44 static bool classof(Type type) {
45 return type.getTypeID() == TypeID::get<ImplTy>();
46 }
47 };
48
49 Type(Storage *impl = nullptr) : impl(impl) {}
50
51 bool operator==(const Type &other) const { return impl == other.impl; }
52 bool operator!=(const Type &other) const { return !(*this == other); }
53 explicit operator bool() const { return impl; }
54
55 /// Return the internal storage instance of this type.
56 Storage *getImpl() const { return impl; }
57
58 /// Return the TypeID instance of this type.
59 TypeID getTypeID() const;
60
61 /// Print this type to the given stream.
62 void print(raw_ostream &os) const;
63
64 /// Try to refine this type with the one provided. Given two compatible types,
65 /// this will return a merged type contains as much detail from the two types.
66 /// For example, if refining two operation types and one contains a name,
67 /// while the other doesn't, the refined type contains the name. If the two
68 /// types are incompatible, null is returned.
69 Type refineWith(Type other) const;
70
71protected:
72 /// Return the internal storage instance of this type reinterpreted as the
73 /// given derived storage type.
74 template <typename T>
75 const T *getImplAs() const {
76 return static_cast<const T *>(impl);
77 }
78
79private:
80 Storage *impl;
81};
82
83inline llvm::hash_code hash_value(Type type) {
85}
86
88 type.print(os);
89 return os;
90}
91
92//===----------------------------------------------------------------------===//
93// Type::Storage
94//===----------------------------------------------------------------------===//
95
98
99 /// The type identifier for the derived type class.
101};
102
103namespace detail {
104
105/// A utility CRTP base class that defines many of the necessary utilities for
106/// defining a PDLL AST Type.
107template <typename ConcreteT, typename KeyT = void>
109 using KeyTy = KeyT;
112 : Type::Storage(TypeID::get<ConcreteT>()), key(key) {}
113
114 /// Construct an instance with the given storage allocator.
116 const KeyTy &key) {
117 return new (alloc.allocate<ConcreteT>()) ConcreteT(key);
118 }
119
120 /// Utility methods required by the storage allocator.
121 bool operator==(const KeyTy &key) const { return this->key == key; }
122
123 /// Return the key value of this storage class.
124 const KeyTy &getValue() const { return key; }
125
126protected:
128};
129/// A specialization of the storage base for singleton types.
130template <typename ConcreteT>
131struct TypeStorageBase<ConcreteT, void> : public Type::Storage {
134};
135
136//===----------------------------------------------------------------------===//
137// AttributeTypeStorage
138//===----------------------------------------------------------------------===//
139
140struct AttributeTypeStorage : public TypeStorageBase<AttributeTypeStorage> {};
141
142//===----------------------------------------------------------------------===//
143// ConstraintTypeStorage
144//===----------------------------------------------------------------------===//
145
146struct ConstraintTypeStorage : public TypeStorageBase<ConstraintTypeStorage> {};
147
148//===----------------------------------------------------------------------===//
149// OperationTypeStorage
150//===----------------------------------------------------------------------===//
151
153 : public TypeStorageBase<OperationTypeStorage,
154 std::pair<StringRef, const ods::Operation *>> {
155 using Base::Base;
156
157 static OperationTypeStorage *
159 const std::pair<StringRef, const ods::Operation *> &key) {
161 std::make_pair(alloc.copyInto(key.first), key.second));
162 }
163};
164
165//===----------------------------------------------------------------------===//
166// RangeTypeStorage
167//===----------------------------------------------------------------------===//
168
169struct RangeTypeStorage : public TypeStorageBase<RangeTypeStorage, Type> {
170 using Base::Base;
171};
172
173//===----------------------------------------------------------------------===//
174// RewriteTypeStorage
175//===----------------------------------------------------------------------===//
176
177struct RewriteTypeStorage : public TypeStorageBase<RewriteTypeStorage> {};
178
179//===----------------------------------------------------------------------===//
180// TupleTypeStorage
181//===----------------------------------------------------------------------===//
182
184 : public TypeStorageBase<TupleTypeStorage,
185 std::pair<ArrayRef<Type>, ArrayRef<StringRef>>> {
186 using Base::Base;
187
188 static TupleTypeStorage *
191 SmallVector<StringRef> names = llvm::map_to_vector(
192 key.second, [&](StringRef name) { return alloc.copyInto(name); });
193 return new (alloc.allocate<TupleTypeStorage>())
194 TupleTypeStorage(std::make_pair(alloc.copyInto(key.first),
195 alloc.copyInto(llvm::ArrayRef(names))));
196 }
197};
198
199//===----------------------------------------------------------------------===//
200// TypeTypeStorage
201//===----------------------------------------------------------------------===//
202
203struct TypeTypeStorage : public TypeStorageBase<TypeTypeStorage> {};
204
205//===----------------------------------------------------------------------===//
206// ValueTypeStorage
207//===----------------------------------------------------------------------===//
208
209struct ValueTypeStorage : public TypeStorageBase<ValueTypeStorage> {};
210
211} // namespace detail
212
213//===----------------------------------------------------------------------===//
214// AttributeType
215//===----------------------------------------------------------------------===//
216
217/// This class represents a PDLL type that corresponds to an mlir::Attribute.
218class AttributeType : public Type::TypeBase<detail::AttributeTypeStorage> {
219public:
220 using Base::Base;
221
222 /// Return an instance of the Attribute type.
223 static AttributeType get(Context &context);
224};
225
226//===----------------------------------------------------------------------===//
227// ConstraintType
228//===----------------------------------------------------------------------===//
229
230/// This class represents a PDLL type that corresponds to a constraint. This
231/// type has no MLIR C++ API correspondance.
232class ConstraintType : public Type::TypeBase<detail::ConstraintTypeStorage> {
233public:
234 using Base::Base;
235
236 /// Return an instance of the Constraint type.
237 static ConstraintType get(Context &context);
238};
239
240//===----------------------------------------------------------------------===//
241// OperationType
242//===----------------------------------------------------------------------===//
243
244/// This class represents a PDLL type that corresponds to an mlir::Operation.
245class OperationType : public Type::TypeBase<detail::OperationTypeStorage> {
246public:
247 using Base::Base;
248
249 /// Return an instance of the Operation type with an optional operation name.
250 /// If no name is provided, this type may refer to any operation.
251 static OperationType get(Context &context,
252 std::optional<StringRef> name = std::nullopt,
253 const ods::Operation *odsOp = nullptr);
254
255 /// Return the name of this operation type, or std::nullopt if it doesn't have
256 /// on.
257 std::optional<StringRef> getName() const;
258
259 /// Return the ODS operation that this type refers to, or nullptr if the ODS
260 /// operation is unknown.
261 const ods::Operation *getODSOperation() const;
262};
263
264//===----------------------------------------------------------------------===//
265// RangeType
266//===----------------------------------------------------------------------===//
267
268/// This class represents a PDLL type that corresponds to a range of elements
269/// with a given element type.
270class RangeType : public Type::TypeBase<detail::RangeTypeStorage> {
271public:
272 using Base::Base;
273
274 /// Return an instance of the Range type with the given element type.
275 static RangeType get(Context &context, Type elementType);
276
277 /// Return the element type of this range.
278 Type getElementType() const;
279};
280
281//===----------------------------------------------------------------------===//
282// TypeRangeType
283//===----------------------------------------------------------------------===//
284
285/// This class represents a PDLL type that corresponds to an mlir::TypeRange.
286class TypeRangeType : public RangeType {
287public:
288 using RangeType::RangeType;
289
290 /// Provide type casting support.
291 static bool classof(Type type);
292
293 /// Return an instance of the TypeRange type.
294 static TypeRangeType get(Context &context);
295};
296
297//===----------------------------------------------------------------------===//
298// ValueRangeType
299//===----------------------------------------------------------------------===//
300
301/// This class represents a PDLL type that corresponds to an mlir::ValueRange.
302class ValueRangeType : public RangeType {
303public:
304 using RangeType::RangeType;
305
306 /// Provide type casting support.
307 static bool classof(Type type);
308
309 /// Return an instance of the ValueRange type.
310 static ValueRangeType get(Context &context);
311};
312
313//===----------------------------------------------------------------------===//
314// RewriteType
315//===----------------------------------------------------------------------===//
316
317/// This class represents a PDLL type that corresponds to a rewrite reference.
318/// This type has no MLIR C++ API correspondance.
319class RewriteType : public Type::TypeBase<detail::RewriteTypeStorage> {
320public:
321 using Base::Base;
322
323 /// Return an instance of the Rewrite type.
324 static RewriteType get(Context &context);
325};
326
327//===----------------------------------------------------------------------===//
328// TupleType
329//===----------------------------------------------------------------------===//
330
331/// This class represents a PDLL tuple type, i.e. an ordered set of element
332/// types with optional names.
333class TupleType : public Type::TypeBase<detail::TupleTypeStorage> {
334public:
335 using Base::Base;
336
337 /// Return an instance of the Tuple type.
338 static TupleType get(Context &context, ArrayRef<Type> elementTypes,
339 ArrayRef<StringRef> elementNames);
340 static TupleType get(Context &context, ArrayRef<Type> elementTypes = {});
341
342 /// Return the element types of this tuple.
344
345 /// Return the element names of this tuple.
347
348 /// Return the number of elements within this tuple.
349 size_t size() const { return getElementTypes().size(); }
350
351 /// Return if the tuple has no elements.
352 bool empty() const { return size() == 0; }
353};
354
355//===----------------------------------------------------------------------===//
356// TypeType
357//===----------------------------------------------------------------------===//
358
359/// This class represents a PDLL type that corresponds to an mlir::Type.
360class TypeType : public Type::TypeBase<detail::TypeTypeStorage> {
361public:
362 using Base::Base;
363
364 /// Return an instance of the Type type.
365 static TypeType get(Context &context);
366};
367
368//===----------------------------------------------------------------------===//
369// ValueType
370//===----------------------------------------------------------------------===//
371
372/// This class represents a PDLL type that corresponds to an mlir::Value.
373class ValueType : public Type::TypeBase<detail::ValueTypeStorage> {
374public:
375 using Base::Base;
376
377 /// Return an instance of the Value type.
378 static ValueType get(Context &context);
379};
380
381} // namespace ast
382} // namespace pdll
383} // namespace mlir
384
393
394namespace llvm {
395template <>
396struct DenseMapInfo<mlir::pdll::ast::Type> {
400 static_cast<mlir::pdll::ast::Type::Storage *>(pointer));
401 }
407 static unsigned getHashValue(mlir::pdll::ast::Type val) {
408 return llvm::hash_value(val.getImpl());
409 }
411 return lhs == rhs;
412 }
413};
414
415/// Add support for llvm style casts.
416/// We provide a cast between To and From if From is mlir::pdll::ast::Type or
417/// derives from it
418template <typename To, typename From>
419struct CastInfo<
420 To, From,
421 std::enable_if_t<
422 std::is_same_v<mlir::pdll::ast::Type, std::remove_const_t<From>> ||
423 std::is_base_of_v<mlir::pdll::ast::Type, From>>>
425 DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
426 static inline bool isPossible(mlir::pdll::ast::Type ty) {
427 /// Return a constant true instead of a dynamic true when casting to self or
428 /// up the hierarchy.
429 if constexpr (std::is_base_of_v<To, From>) {
430 return true;
431 } else {
432 return To::classof(ty);
433 };
434 }
435 static inline To doCast(mlir::pdll::ast::Type ty) { return To(ty.getImpl()); }
436};
437} // namespace llvm
438
439#endif // MLIR_TOOLS_PDLL_AST_TYPES_H_
lhs
#define MLIR_DECLARE_EXPLICIT_TYPE_ID(CLASS_NAME)
Definition TypeID.h:321
This class acts as the base storage that all storage classes must derived from.
This is a utility allocator used to allocate memory for instances of derived types.
ArrayRef< T > copyInto(ArrayRef< T > elements)
Copy the specified array of elements into memory managed by our bump pointer allocator.
T * allocate()
Allocate an instance of the provided type.
This class provides an efficient unique identifier for a specific C++ type.
Definition TypeID.h:107
static TypeID get()
Construct a type info object for the given type T.
Definition TypeID.h:245
This class represents a PDLL type that corresponds to an mlir::Attribute.
Definition Types.h:218
static AttributeType get(Context &context)
Return an instance of the Attribute type.
Definition Types.cpp:56
This class represents a PDLL type that corresponds to a constraint.
Definition Types.h:232
static ConstraintType get(Context &context)
Return an instance of the Constraint type.
Definition Types.cpp:64
This class represents the main context of the PDLL AST.
Definition Context.h:25
This class represents a PDLL type that corresponds to an mlir::Operation.
Definition Types.h:245
const ods::Operation * getODSOperation() const
Return the ODS operation that this type refers to, or nullptr if the ODS operation is unknown.
Definition Types.cpp:86
static OperationType get(Context &context, std::optional< StringRef > name=std::nullopt, const ods::Operation *odsOp=nullptr)
Return an instance of the Operation type with an optional operation name.
Definition Types.cpp:72
std::optional< StringRef > getName() const
Return the name of this operation type, or std::nullopt if it doesn't have on.
Definition Types.cpp:80
This class represents a PDLL type that corresponds to a range of elements with a given element type.
Definition Types.h:270
Type getElementType() const
Return the element type of this range.
Definition Types.cpp:99
static RangeType get(Context &context, Type elementType)
Return an instance of the Range type with the given element type.
Definition Types.cpp:94
This class represents a PDLL type that corresponds to a rewrite reference.
Definition Types.h:319
static RewriteType get(Context &context)
Return an instance of the Rewrite type.
Definition Types.cpp:135
This class represents a PDLL tuple type, i.e.
Definition Types.h:333
size_t size() const
Return the number of elements within this tuple.
Definition Types.h:349
ArrayRef< StringRef > getElementNames() const
Return the element names of this tuple.
Definition Types.cpp:158
bool empty() const
Return if the tuple has no elements.
Definition Types.h:352
ArrayRef< Type > getElementTypes() const
Return the element types of this tuple.
Definition Types.cpp:154
static TupleType get(Context &context, ArrayRef< Type > elementTypes, ArrayRef< StringRef > elementNames)
Return an instance of the Tuple type.
Definition Types.cpp:143
This class represents a PDLL type that corresponds to an mlir::TypeRange.
Definition Types.h:286
static TypeRangeType get(Context &context)
Return an instance of the TypeRange type.
Definition Types.cpp:112
static bool classof(Type type)
Provide type casting support.
Definition Types.cpp:107
This class represents a PDLL type that corresponds to an mlir::Type.
Definition Types.h:360
static TypeType get(Context &context)
Return an instance of the Type type.
Definition Types.cpp:166
This class provides several utilities when defining derived type classes.
Definition Types.h:37
TypeBase< ImplT, BaseT > Base
Definition Types.h:39
static bool classof(Type type)
Provide type casting support.
Definition Types.h:44
TypeID getTypeID() const
Return the TypeID instance of this type.
Definition Types.cpp:30
bool operator!=(const Type &other) const
Definition Types.h:52
Storage * getImpl() const
Return the internal storage instance of this type.
Definition Types.h:56
void print(raw_ostream &os) const
Print this type to the given stream.
Type(Storage *impl=nullptr)
Definition Types.h:49
const T * getImplAs() const
Return the internal storage instance of this type reinterpreted as the given derived storage type.
Definition Types.h:75
Type refineWith(Type other) const
Try to refine this type with the one provided.
Definition Types.cpp:32
bool operator==(const Type &other) const
Definition Types.h:51
This class represents a PDLL type that corresponds to an mlir::ValueRange.
Definition Types.h:302
static bool classof(Type type)
Provide type casting support.
Definition Types.cpp:121
static ValueRangeType get(Context &context)
Return an instance of the ValueRange type.
Definition Types.cpp:126
This class represents a PDLL type that corresponds to an mlir::Value.
Definition Types.h:373
static ValueType get(Context &context)
Return an instance of the Value type.
Definition Types.cpp:174
This class provides an ODS representation of a specific operation.
Definition Operation.h:125
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
llvm::hash_code hash_value(Type type)
Definition Types.h:83
raw_ostream & operator<<(raw_ostream &os, Type type)
Definition Types.h:87
Include the generated interface declarations.
llvm::DenseMapInfo< T, Enable > DenseMapInfo
Definition LLVM.h:114
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
static bool isEqual(mlir::pdll::ast::Type lhs, mlir::pdll::ast::Type rhs)
Definition Types.h:410
static unsigned getHashValue(mlir::pdll::ast::Type val)
Definition Types.h:407
static mlir::pdll::ast::Type getTombstoneKey()
Definition Types.h:402
static mlir::pdll::ast::Type getEmptyKey()
Definition Types.h:397
Storage(TypeID typeID)
Definition Types.h:97
TypeID typeID
The type identifier for the derived type class.
Definition Types.h:100
static OperationTypeStorage * construct(StorageUniquer::StorageAllocator &alloc, const std::pair< StringRef, const ods::Operation * > &key)
Definition Types.h:158
static TupleTypeStorage * construct(StorageUniquer::StorageAllocator &alloc, std::pair< ArrayRef< Type >, ArrayRef< StringRef > > key)
Definition Types.h:189
A utility CRTP base class that defines many of the necessary utilities for defining a PDLL AST Type.
Definition Types.h:108
bool operator==(const KeyTy &key) const
Utility methods required by the storage allocator.
Definition Types.h:121
const KeyTy & getValue() const
Return the key value of this storage class.
Definition Types.h:124
static ConcreteT * construct(StorageUniquer::StorageAllocator &alloc, const KeyTy &key)
Construct an instance with the given storage allocator.
Definition Types.h:115
TypeStorageBase< ConcreteT, KeyT > Base
Definition Types.h:110