13#ifndef MLIR_IR_ATTRIBUTESUPPORT_H
14#define MLIR_IR_ATTRIBUTESUPPORT_H
19#include "llvm/ADT/PointerIntPair.h"
20#include "llvm/ADT/Twine.h"
29class AbstractAttribute {
43 static std::optional<std::reference_wrapper<const AbstractAttribute>>
50 return AbstractAttribute(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
51 T::getWalkImmediateSubElementsFn(),
52 T::getReplaceImmediateSubElementsFn(),
53 T::getTypeID(), T::name);
65 TypeID typeID, StringRef name) {
66 return AbstractAttribute(dialect, std::move(interfaceMap),
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>
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;
163class AttributeUniquer;
164class DistinctAttributeUniquer;
172 friend StorageUniquer;
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>
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();
LogicalResult initialize(unsigned origNumLoops, ArrayRef< ReassociationIndices > foldedIterationDims)
This class contains all of the static information common to all instances of a registered Attribute.
llvm::unique_function< bool(TypeID) const > HasTraitFn
function_ref< void( Attribute, function_ref< void(Attribute)>, function_ref< void(Type)>)> WalkImmediateSubElementsFn
static AbstractAttribute get(Dialect &dialect)
This method is used by Dialect objects when they register the list of attributes they contain.
function_ref< Attribute(Attribute, ArrayRef< Attribute >, ArrayRef< Type >)> ReplaceImmediateSubElementsFn
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.
Dialect & getDialect() const
Return the dialect this attribute was registered to.
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.
T::Concept * getInterface() const
Returns an instance of the concept object for the given interface if it was registered to this attrib...
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.
StringRef getName() const
Return the unique name representing the type.
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.
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.
Storage * get(function_ref< void(Storage *)> initFn, TypeID id, Args &&...args)
Gets a uniqued instance of 'Storage'.
bool isSingletonStorageInitialized(TypeID id)
Test if there is a singleton storage uniquer initialized for the provided TypeID.
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.
static TypeID get()
Construct a type info object for the given type T.
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)
Get an uniqued instance of a singleton attribute T.
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 > registerAttribute(MLIRContext *ctx, TypeID typeID)
Register a parametric attribute instance T with the uniquer.
static T get(MLIRContext *ctx, Args &&...args)
Get an uniqued instance of an attribute T.
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 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 singleton 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...
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
decltype(auto) unwrapForCustomParse(FailureOr< T > &failureOr)
Include the generated interface declarations.
StorageUniquer::StorageAllocator AttributeStorageAllocator
llvm::function_ref< Fn > function_ref
AttributeStorage DefaultAttributeStorage
Default storage type for attributes that require no additional initialization or storage.