13 #ifndef MLIR_IR_ATTRIBUTESUPPORT_H
14 #define MLIR_IR_ATTRIBUTESUPPORT_H
19 #include "llvm/ADT/PointerIntPair.h"
20 #include "llvm/ADT/Twine.h"
43 static std::optional<std::reference_wrapper<const AbstractAttribute>>
51 T::getWalkImmediateSubElementsFn(),
52 T::getReplaceImmediateSubElementsFn(),
53 T::getTypeID(), T::name);
65 TypeID typeID, StringRef name) {
67 std::move(
hasTrait), walkImmediateSubElementsFn,
68 replaceImmediateSubElementsFn, typeID, name);
79 return interfaceMap.
lookup<T>();
85 return interfaceMap.
contains(interfaceID);
89 template <
template <
typename T>
class Trait>
91 return hasTraitFn(TypeID::get<Trait>());
118 TypeID typeID, StringRef name)
119 : dialect(dialect), interfaceMap(std::move(interfaceMap)),
120 hasTraitFn(std::move(hasTraitFn)),
121 walkImmediateSubElementsFn(walkImmediateSubElementsFn),
122 replaceImmediateSubElementsFn(replaceImmediateSubElementsFn),
123 typeID(typeID), name(name) {}
126 template <
typename ConcreteT,
typename BaseT,
typename StorageT,
127 typename UniquerT,
template <
typename T>
class... Traits>
155 const StringRef name;
163 class AttributeUniquer;
164 class DistinctAttributeUniquer;
177 assert(abstractAttribute &&
"Malformed attribute storage object.");
178 return *abstractAttribute;
185 abstractAttribute = &abstractAttr;
218 template <
typename T,
typename... Args>
221 std::forward<Args>(args)...);
227 template <
typename T,
typename... Args>
228 static std::enable_if_t<
229 !std::is_same<typename T::ImplType, AttributeStorage>::value, T>
233 llvm::report_fatal_error(
234 llvm::Twine(
"can't create Attribute '") + llvm::getTypeName<T>() +
235 "' because storage uniquer isn't initialized: the dialect was likely "
236 "not loaded, or the attribute wasn't added with addAttributes<...>() "
237 "in the Dialect::initialize() method.");
241 initializeAttributeStorage(storage, ctx, typeID);
245 static_cast<typename T::ImplType *
>(storage)->initialize(ctx);
247 typeID, std::forward<Args>(args)...);
252 template <
typename T>
253 static std::enable_if_t<
254 std::is_same<typename T::ImplType, AttributeStorage>::value, T>
258 llvm::report_fatal_error(
259 llvm::Twine(
"can't create Attribute '") + llvm::getTypeName<T>() +
260 "' because storage uniquer isn't initialized: the dialect was likely "
261 "not loaded, or the attribute wasn't added with addAttributes<...>() "
262 "in the Dialect::initialize() method.");
267 template <
typename T,
typename... Args>
270 assert(
impl &&
"cannot mutate null attribute");
272 std::forward<Args>(args)...);
276 template <
typename T>
278 registerAttribute<T>(ctx, T::getTypeID());
284 template <
typename T>
285 static std::enable_if_t<
286 !std::is_same<typename T::ImplType, AttributeStorage>::value>
294 template <
typename T>
295 static std::enable_if_t<
296 std::is_same<typename T::ImplType, AttributeStorage>::value>
301 initializeAttributeStorage(storage, ctx, typeID);
317 if constexpr (std::is_default_constructible_v<T>)
318 return failureOr.emplace();
This class contains all of the static information common to all instances of a registered Attribute.
function_ref< Attribute(Attribute, ArrayRef< Attribute >, ArrayRef< Type >)> ReplaceImmediateSubElementsFn
llvm::unique_function< bool(TypeID) const > HasTraitFn
T::Concept * getInterface() const
Returns an instance of the concept object for the given interface if it was registered to this attrib...
static AbstractAttribute get(Dialect &dialect)
This method is used by Dialect objects when they register the list of attributes they contain.
static const AbstractAttribute & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract attribute in the MLIRContext and return a reference to it.
TypeID getTypeID() const
Return the unique identifier representing the concrete attribute class.
static AbstractAttribute 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 attributes with custom TypeIDs.
bool hasTrait() const
Returns true if the attribute has a particular trait.
void walkImmediateSubElements(Attribute attr, function_ref< void(Attribute)> walkAttrsFn, function_ref< void(Type)> walkTypesFn) const
Walk the immediate sub-elements of this attribute.
bool hasTrait(TypeID traitID) const
Returns true if the attribute has a particular trait.
Attribute replaceImmediateSubElements(Attribute attr, ArrayRef< Attribute > replAttrs, ArrayRef< Type > replTypes) const
Replace the immediate sub-elements of this attribute.
function_ref< void(Attribute, function_ref< void(Attribute)>, function_ref< void(Type)>)> WalkImmediateSubElementsFn
StringRef getName() const
Return the unique name representing the type.
Dialect & getDialect() const
Return the dialect this attribute was registered to.
bool hasInterface(TypeID interfaceID) const
Returns true if the attribute has the interface with the given ID registered.
Base storage class appearing in an attribute.
void initializeAbstractAttribute(const AbstractAttribute &abstractAttr)
Set the abstract attribute for this storage instance.
const AbstractAttribute & getAbstractAttribute() const
Return the abstract descriptor for this attribute.
void initialize(MLIRContext *context)
Default initialization for attribute storage classes that require no additional initialization.
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 & getAttributeUniquer()
Returns the storage uniquer used for constructing attribute 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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
static std::enable_if_t< !std::is_same< typename T::ImplType, AttributeStorage >::value, T > getWithTypeID(MLIRContext *ctx, TypeID typeID, Args &&...args)
Get an uniqued instance of a parametric attribute T.
static std::enable_if_t< std::is_same< typename T::ImplType, AttributeStorage >::value > registerAttribute(MLIRContext *ctx, TypeID typeID)
Register a singleton attribute instance T with the uniquer.
static void registerAttribute(MLIRContext *ctx)
Register an attribute instance T with the uniquer.
static std::enable_if_t< std::is_same< typename T::ImplType, AttributeStorage >::value, T > getWithTypeID(MLIRContext *ctx, TypeID typeID)
Get an uniqued instance of a singleton attribute T.
static T get(MLIRContext *ctx, Args &&...args)
Get an uniqued instance of an attribute T.
static LogicalResult mutate(MLIRContext *ctx, typename T::ImplType *impl, Args &&...args)
static std::enable_if_t< !std::is_same< typename T::ImplType, AttributeStorage >::value > registerAttribute(MLIRContext *ctx, TypeID typeID)
Register a parametric attribute instance T with the uniquer.
A specialized attribute uniquer for distinct attributes that always allocates since the distinct attr...
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.
decltype(auto) unwrapForCustomParse(FailureOr< T > &failureOr)
Include the generated interface declarations.