13 #ifndef MLIR_IR_TYPESUPPORT_H
14 #define MLIR_IR_TYPESUPPORT_H
18 #include "llvm/ADT/Twine.h"
44 static std::optional<std::reference_wrapper<const AbstractType>>
51 return AbstractType(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
52 T::getWalkImmediateSubElementsFn(),
53 T::getReplaceImmediateSubElementsFn(), T::getTypeID(),
66 TypeID typeID, StringRef name) {
68 walkImmediateSubElementsFn,
69 replaceImmediateSubElementsFn, typeID, name);
80 return interfaceMap.
lookup<T>();
85 return interfaceMap.
contains(interfaceID);
89 template <
template <
typename T>
class Trait>
91 return hasTraitFn(TypeID::get<Trait>());
117 TypeID typeID, StringRef name)
118 : dialect(dialect), interfaceMap(std::move(interfaceMap)),
120 walkImmediateSubElementsFn(walkImmediateSubElementsFn),
121 replaceImmediateSubElementsFn(replaceImmediateSubElementsFn),
122 typeID(typeID), name(name) {}
125 template <
typename ConcreteT,
typename BaseT,
typename StorageT,
126 typename UniquerT,
template <
typename T>
class... Traits>
154 const StringRef name;
173 assert(abstractType &&
"Malformed type storage object.");
174 return *abstractType;
189 AbstractType *abstractType{
nullptr};
212 template <
typename T,
typename... Args>
215 std::forward<Args>(args)...);
221 template <
typename T,
typename... Args>
222 static std::enable_if_t<
223 !std::is_same<typename T::ImplType, TypeStorage>::value, T>
227 llvm::report_fatal_error(
228 llvm::Twine(
"can't create type '") + llvm::getTypeName<T>() +
229 "' because storage uniquer isn't initialized: the dialect was likely "
230 "not loaded, or the type wasn't added with addTypes<...>() "
231 "in the Dialect::initialize() method.");
237 typeID, std::forward<Args>(args)...);
242 template <
typename T>
243 static std::enable_if_t<
244 std::is_same<typename T::ImplType, TypeStorage>::value, T>
248 llvm::report_fatal_error(
249 llvm::Twine(
"can't create type '") + llvm::getTypeName<T>() +
250 "' because storage uniquer isn't initialized: the dialect was likely "
251 "not loaded, or the type wasn't added with addTypes<...>() "
252 "in the Dialect::initialize() method.");
259 template <
typename T,
typename... Args>
262 assert(
impl &&
"cannot mutate null type");
264 std::forward<Args>(args)...);
268 template <
typename T>
270 registerType<T>(ctx, T::getTypeID());
276 template <
typename T>
277 static std::enable_if_t<
278 !std::is_same<typename T::ImplType, TypeStorage>::value>
286 template <
typename T>
287 static std::enable_if_t<
288 std::is_same<typename T::ImplType, TypeStorage>::value>
This class contains all of the static information common to all instances of a registered Type.
Dialect & getDialect() const
Return the dialect this type was registered to.
Type replaceImmediateSubElements(Type type, ArrayRef< Attribute > replAttrs, ArrayRef< Type > replTypes) const
Replace the immediate sub-elements of the given type.
function_ref< void(Type, function_ref< void(Attribute)>, function_ref< void(Type)>)> WalkImmediateSubElementsFn
static AbstractType get(Dialect &dialect)
This method is used by Dialect objects when they register the list of types they contain.
static const AbstractType & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract type in the MLIRContext and return a reference to it.
bool hasInterface(TypeID interfaceID) const
Returns true if the type has the interface with the given ID.
void walkImmediateSubElements(Type type, function_ref< void(Attribute)> walkAttrsFn, function_ref< void(Type)> walkTypesFn) const
Walk the immediate sub-elements of the given type.
T::Concept * getInterface() const
Returns an instance of the concept object for the given interface if it was registered to this type,...
TypeID getTypeID() const
Return the unique identifier representing the concrete type class.
bool hasTrait() const
Returns true if the type has a particular trait.
llvm::unique_function< bool(TypeID) const > HasTraitFn
bool hasTrait(TypeID traitID) const
Returns true if the type has a particular trait.
StringRef getName() const
Return the unique name representing the type.
function_ref< Type(Type, ArrayRef< Attribute >, ArrayRef< Type >)> ReplaceImmediateSubElementsFn
static AbstractType get(Dialect &dialect, detail::InterfaceMap &&interfaceMap, HasTraitFn &&hasTrait, WalkImmediateSubElementsFn walkImmediateSubElementsFn, ReplaceImmediateSubElementsFn replaceImmediateSubElementsFn, TypeID typeID, StringRef name)
This method is used by Dialect objects to register types with custom TypeIDs.
Attributes are known-constant values of operations.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
MLIRContext is the top-level object for a collection of MLIR operations.
StorageUniquer & getTypeUniquer()
Returns the storage uniquer used for constructing type storage instances.
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.
A utility class to get or create instances of "storage classes".
LogicalResult mutate(TypeID id, Storage *storage, Args &&...args)
Changes the mutable component of 'storage' by forwarding the trailing arguments to the 'mutate' funct...
void registerSingletonStorageType(TypeID id, function_ref< void(Storage *)> initFn)
Register a new singleton storage class, this is necessary to get the singletone instance.
bool isSingletonStorageInitialized(TypeID id)
Test if there is a singleton storage uniquer initialized for the provided TypeID.
Storage * get(function_ref< void(Storage *)> initFn, TypeID id, Args &&...args)
Gets a uniqued instance of 'Storage'.
bool isParametricStorageInitialized(TypeID id)
Test if there is a parametric storage uniquer initialized for the provided TypeID.
void registerParametricStorageType(TypeID id)
Register a new parametric storage class, this is necessary to create instances of this class type.
This class provides an efficient unique identifier for a specific C++ type.
Base storage class appearing in a Type.
TypeStorage()
This constructor is used by derived classes as part of the TypeUniquer.
const AbstractType & getAbstractType()
Return the abstract type descriptor for this type.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class provides an efficient mapping between a given Interface type, and a particular implementat...
bool contains(TypeID interfaceID) const
Returns true if the interface map contains an interface for the given id.
T::Concept * lookup() const
Returns an instance of the concept object for the given interface if it was registered to this map,...
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
Include the generated interface declarations.
A utility class to get, or create, unique instances of types within an MLIRContext.
static T get(MLIRContext *ctx, Args &&...args)
Get an uniqued instance of a type T.
static std::enable_if_t< std::is_same< typename T::ImplType, TypeStorage >::value > registerType(MLIRContext *ctx, TypeID typeID)
Register a singleton type instance T with the uniquer.
static std::enable_if_t< !std::is_same< typename T::ImplType, TypeStorage >::value > registerType(MLIRContext *ctx, TypeID typeID)
Register a parametric type instance T with the uniquer.
static LogicalResult mutate(MLIRContext *ctx, typename T::ImplType *impl, Args &&...args)
Change the mutable component of the given type instance in the provided context.
static std::enable_if_t< std::is_same< typename T::ImplType, TypeStorage >::value, T > getWithTypeID(MLIRContext *ctx, TypeID typeID)
Get an uniqued instance of a singleton type T.
static std::enable_if_t< !std::is_same< typename T::ImplType, TypeStorage >::value, T > getWithTypeID(MLIRContext *ctx, TypeID typeID, Args &&...args)
Get an uniqued instance of a parametric type T.
static void registerType(MLIRContext *ctx)
Register a type instance T with the uniquer.