13#ifndef ATTRIBUTEDETAIL_H_
14#define ATTRIBUTEDETAIL_H_
23#include "llvm/ADT/APFloat.h"
24#include "llvm/Support/Allocator.h"
25#include "llvm/Support/RWMutex.h"
37 if (
auto denseEltType = llvm::dyn_cast<DenseElementType>(eltType))
38 return denseEltType.getDenseElementBitSize();
39 llvm_unreachable(
"unsupported element type");
82 size_t storageSize = llvm::divideCeil(elementWidth, CHAR_BIT);
85 if (
data.size() == storageSize)
88 assert(((
data.size() / storageSize) ==
89 static_cast<size_t>(ty.getNumElements())) &&
90 "data does not hold expected number of elements");
93 auto firstElt =
data.take_front(storageSize);
94 auto hashVal = llvm::hash_value(firstElt);
98 for (
size_t i = storageSize, e =
data.size(); i != e; i += storageSize)
99 if (memcmp(
data.data(), &
data[i], storageSize))
100 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
103 return KeyTy(ty, firstElt, hashVal);
118 char *rawData =
reinterpret_cast<char *
>(
120 std::memcpy(rawData,
data.data(),
data.size());
168 if (
data.size() == 1)
172 const auto &firstElt =
data.front();
173 auto hashVal = llvm::hash_value(firstElt);
177 for (
size_t i = 1, e =
data.size(); i != e; ++i)
178 if (firstElt !=
data[i])
179 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
182 return KeyTy(ty,
data.take_front(), hashVal);
201 size_t numEntries =
data.size();
205 size_t dataSize =
sizeof(StringRef) * numEntries;
206 for (
size_t i = 0; i < numEntries; ++i)
207 dataSize +=
data[i].size();
209 char *rawData =
reinterpret_cast<char *
>(
210 allocator.
allocate(dataSize,
alignof(uint64_t)));
215 reinterpret_cast<StringRef *
>(rawData), numEntries);
216 auto *stringData = rawData + numEntries *
sizeof(StringRef);
218 for (
size_t i = 0; i < numEntries; ++i) {
220 mutableCopy[i] = StringRef(stringData,
data[i].size());
221 stringData +=
data[i].size();
243 using KeyTy = std::pair<StringRef, Type>;
245 return value == key.first &&
type == key.second;
296 template <
typename T,
typename... Args>
298 static_assert(std::is_same_v<typename T::ImplType, DistinctAttrStorage>,
299 "expects a distinct attribute storage");
301 context, std::forward<Args>(args)...);
325 llvm::sys::SmartScopedWriter<true> guard(allocatorMutex);
326 llvm::BumpPtrAllocator &alloc =
327 transientAllocator ? *transientAllocator : allocator;
333 assert(!transientAllocator &&
334 "distinct attribute allocator is already in a transient scope");
335 transientAllocator = std::make_unique<llvm::BumpPtrAllocator>();
344 llvm::BumpPtrAllocator allocator;
347 std::unique_ptr<llvm::BumpPtrAllocator> transientAllocator;
351 mutable llvm::sys::SmartRWMutex<true> allocatorMutex;
static void copy(Location loc, Value dst, Value src, Value size, OpBuilder &builder)
Copies the given number of bytes from src to dst pointers.
static const AbstractAttribute & lookup(TypeID typeID, MLIRContext *context)
Look up the specified abstract attribute in the MLIRContext and return a reference to it.
Base storage class appearing in an attribute.
void initializeAbstractAttribute(const AbstractAttribute &abstractAttr)
Set the abstract attribute for this storage instance.
Attributes are known-constant values of operations.
TypeID getTypeID()
Return a unique identifier for the concrete attribute type.
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.
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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
void beginTransientScope()
DistinctAttrStorage * allocate(Attribute referencedAttr)
bool isInTransientScope() const
DistinctAttributeAllocator(const DistinctAttributeAllocator &)=delete
DistinctAttributeAllocator()=default
DistinctAttributeAllocator & operator=(const DistinctAttributeAllocator &)=delete
DistinctAttributeAllocator(DistinctAttributeAllocator &&)=delete
A specialized attribute uniquer for distinct attributes that always allocates since the distinct attr...
static T get(MLIRContext *context, Args &&...args)
Creates a distinct attribute storage.
size_t getDenseElementBitWidth(Type eltType)
Return the bit width which DenseElementsAttr should use for this type.
Include the generated interface declarations.
llvm::DenseMapInfo< T, Enable > DenseMapInfo
StorageUniquer::StorageAllocator AttributeStorageAllocator
DenseElementsAttributeStorage(ShapedType type)
ShapedType type
The type of the dense elements.
ArrayRef< StringRef > data
The raw buffer for the data storage.
KeyTy(ShapedType type, ArrayRef< StringRef > data, llvm::hash_code hashCode)
llvm::hash_code hashCode
The computed hash code for the storage data.
An attribute representing a reference to a dense vector or tensor object containing strings.
ArrayRef< StringRef > data
bool operator==(const KeyTy &key) const
Compare this storage instance with the provided key.
static KeyTy getKey(ShapedType ty, ArrayRef< StringRef > data)
Construct a key from a shaped type and StringRef data buffer.
DenseStringElementsAttrStorage(ShapedType ty, ArrayRef< StringRef > data)
static DenseStringElementsAttrStorage * construct(AttributeStorageAllocator &allocator, KeyTy key)
Construct a new storage instance.
static llvm::hash_code hashKey(const KeyTy &key)
Hash the key for the storage.
KeyTy(ShapedType type, ArrayRef< char > data, llvm::hash_code hashCode)
ArrayRef< char > data
The raw buffer for the data storage.
ShapedType type
The type of the dense elements.
llvm::hash_code hashCode
The computed hash code for the storage data.
An attribute representing a reference to a dense vector or tensor object.
DenseTypedElementsAttrStorage(ShapedType ty, ArrayRef< char > data)
bool operator==(const KeyTy &key) const
Compare this storage instance with the provided key.
static DenseTypedElementsAttrStorage * construct(AttributeStorageAllocator &allocator, KeyTy key)
Construct a new storage instance.
static llvm::hash_code hashKey(const KeyTy &key)
Hash the key for the storage.
static KeyTy getKey(ShapedType ty, ArrayRef< char > data)
Construct a key from a shaped type and raw data buffer.
An attribute to store a distinct reference to another attribute.
DistinctAttrStorage(Attribute referencedAttr)
Attribute referencedAttr
The referenced attribute.
KeyTy getAsKey() const
Returns the referenced attribute as key.
Type type
The type of the string.
StringRef value
The raw string value.
bool operator==(const KeyTy &key) const
::llvm::hash_code hashKey(const KeyTy &key)
StringAttrStorage(StringRef value, Type type)
static StringAttrStorage * construct(AttributeStorageAllocator &allocator, const KeyTy &key)
Define a construction method for creating a new instance of this storage.
Dialect * referencedDialect
If the string value contains a dialect namespace prefix (e.g.
std::pair< StringRef, Type > KeyTy
The hash key is a tuple of the parameter types.
void initialize(MLIRContext *context)
Initialize the storage given an MLIRContext.