13 #ifndef ATTRIBUTEDETAIL_H_
14 #define ATTRIBUTEDETAIL_H_
22 #include "llvm/ADT/APFloat.h"
23 #include "llvm/Support/Allocator.h"
36 if (ComplexType comp = llvm::dyn_cast<ComplexType>(eltType))
39 return IndexType::kInternalStorageBitWidth;
93 bool isBoolData = ty.getElementType().isInteger(1);
103 size_t numElements = ty.getNumElements();
104 assert(numElements != 1 &&
"splat of 1 element should already be detected");
113 assert(((
data.size() / storageSize) == numElements) &&
114 "data does not hold expected number of elements");
117 auto firstElt =
data.take_front(storageSize);
122 for (
size_t i = storageSize, e =
data.size(); i != e; i += storageSize)
123 if (memcmp(
data.data(), &
data[i], storageSize))
124 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
127 return KeyTy(ty, firstElt, hashVal,
true);
132 size_t numElements) {
134 bool splatValue = splatData.front() & 1;
142 size_t numOddElements = numElements % CHAR_BIT;
143 if (splatValue && numOddElements != 0) {
145 char lastElt = splatData.back();
146 if (lastElt != llvm::maskTrailingOnes<unsigned char>(numOddElements))
150 if (splatData.size() == 1)
152 splatData = splatData.drop_back();
156 char mask = splatValue ? ~0 : 0;
157 return llvm::all_of(splatData, [mask](
char c) {
return c == mask; })
181 char *rawData =
reinterpret_cast<char *
>(
183 std::memcpy(rawData,
data.data(),
data.size());
252 assert(ty.getNumElements() != 1 &&
253 "splat of 1 element should already be detected");
256 const auto &firstElt =
data.front();
261 for (
size_t i = 1, e =
data.size(); i != e; i++)
262 if (firstElt !=
data[i])
263 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
266 return KeyTy(ty,
data.take_front(), hashVal,
true);
289 size_t dataSize =
sizeof(StringRef) * numEntries;
290 for (
int i = 0; i < numEntries; i++)
291 dataSize +=
data[i].size();
293 char *rawData =
reinterpret_cast<char *
>(
294 allocator.
allocate(dataSize,
alignof(uint64_t)));
299 reinterpret_cast<StringRef *
>(rawData), numEntries);
300 auto *stringData = rawData + numEntries *
sizeof(StringRef);
302 for (
int i = 0; i < numEntries; i++) {
304 mutableCopy[i] = StringRef(stringData,
data[i].size());
305 stringData +=
data[i].size();
327 using KeyTy = std::pair<StringRef, Type>;
329 return value == key.first &&
type == key.second;
380 template <
typename T,
typename... Args>
382 static_assert(std::is_same_v<typename T::ImplType, DistinctAttrStorage>,
383 "expects a distinct attribute storage");
385 context, std::forward<Args>(args)...);
409 std::scoped_lock<std::mutex> guard(allocatorMutex);
417 llvm::BumpPtrAllocator allocator;
420 std::mutex 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.
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.
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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
An allocator for distinct attribute storage instances.
DistinctAttributeAllocator(const DistinctAttributeAllocator &)=delete
DistinctAttributeAllocator()=default
DistinctAttributeAllocator & operator=(const DistinctAttributeAllocator &)=delete
DistinctAttributeAllocator(DistinctAttributeAllocator &&)=delete
DistinctAttrStorage * allocate(Attribute referencedAttr)
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.
static TypeID getTypeID()
Return a unique identifier for the concrete type.
size_t getDenseElementBitWidth(Type eltType)
Return the bit width which DenseElementsAttr should use for this type.
llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator)
Divides the known min value of the numerator by the denominator and rounds the result up to the next ...
llvm::hash_code hash_value(const StructType::MemberDecorationInfo &memberDecorationInfo)
Include the generated interface declarations.
An attribute representing a reference to a dense vector or tensor object.
DenseElementsAttributeStorage(ShapedType type, bool isSplat)
llvm::hash_code hashCode
The computed hash code for the storage data.
bool isSplat
A boolean that indicates if this data is a splat or not.
KeyTy(ShapedType type, ArrayRef< char > data, llvm::hash_code hashCode, bool isSplat=false)
ArrayRef< char > data
The raw buffer for the data storage.
ShapedType type
The type of the dense elements.
An attribute representing a reference to a dense vector or tensor object.
bool operator==(const KeyTy &key) const
Compare this storage instance with the provided key.
static KeyTy getKey(ShapedType ty, ArrayRef< char > data, bool isKnownSplat)
Construct a key from a shaped type, raw data buffer, and a flag that signals if the data is already k...
static const char kSplatTrue
The values used to denote a boolean splat value.
static llvm::hash_code hashKey(const KeyTy &key)
Hash the key for the storage.
static DenseIntOrFPElementsAttrStorage * construct(AttributeStorageAllocator &allocator, KeyTy key)
Construct a new storage instance.
static const char kSplatFalse
DenseIntOrFPElementsAttrStorage(ShapedType ty, ArrayRef< char > data, bool isSplat=false)
static KeyTy getKeyForSplatBoolData(ShapedType type, bool splatValue)
Return a key to use for a boolean splat of the given value.
static KeyTy getKeyForBoolData(ShapedType ty, ArrayRef< char > data, size_t numElements)
Construct a key with a set of boolean data.
KeyTy(ShapedType type, ArrayRef< StringRef > data, llvm::hash_code hashCode, bool isSplat=false)
ShapedType type
The type of the dense elements.
bool isSplat
A boolean that indicates if this data is a splat or not.
ArrayRef< StringRef > data
The raw buffer for the data storage.
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.
static DenseStringElementsAttrStorage * construct(AttributeStorageAllocator &allocator, KeyTy key)
Construct a new storage instance.
ArrayRef< StringRef > data
static KeyTy getKey(ShapedType ty, ArrayRef< StringRef > data, bool isKnownSplat)
Construct a key from a shaped type, StringRef data buffer, and a flag that signals if the data is alr...
bool operator==(const KeyTy &key) const
Compare this storage instance with the provided key.
DenseStringElementsAttrStorage(ShapedType ty, ArrayRef< StringRef > data, bool isSplat=false)
static llvm::hash_code hashKey(const KeyTy &key)
Hash the key for the storage.
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)
static StringAttrStorage * construct(AttributeStorageAllocator &allocator, const KeyTy &key)
Define a construction method for creating a new instance of this storage.
StringAttrStorage(StringRef value, Type type)
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.