13 #ifndef ATTRIBUTEDETAIL_H_
14 #define ATTRIBUTEDETAIL_H_
24 #include "llvm/ADT/APFloat.h"
25 #include "llvm/ADT/PointerIntPair.h"
26 #include "llvm/Support/TrailingObjects.h"
38 if (ComplexType comp = llvm::dyn_cast<ComplexType>(eltType))
41 return IndexType::kInternalStorageBitWidth;
95 bool isBoolData = ty.getElementType().isInteger(1);
105 size_t numElements = ty.getNumElements();
106 assert(numElements != 1 &&
"splat of 1 element should already be detected");
115 assert(((
data.size() / storageSize) == numElements) &&
116 "data does not hold expected number of elements");
119 auto firstElt =
data.take_front(storageSize);
124 for (
size_t i = storageSize, e =
data.size(); i != e; i += storageSize)
125 if (memcmp(
data.data(), &
data[i], storageSize))
126 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
129 return KeyTy(ty, firstElt, hashVal,
true);
134 size_t numElements) {
136 bool splatValue = splatData.front() & 1;
144 size_t numOddElements = numElements % CHAR_BIT;
145 if (splatValue && numOddElements != 0) {
147 char lastElt = splatData.back();
148 if (lastElt != llvm::maskTrailingOnes<unsigned char>(numOddElements))
152 if (splatData.size() == 1)
154 splatData = splatData.drop_back();
158 char mask = splatValue ? ~0 : 0;
159 return llvm::all_of(splatData, [mask](
char c) {
return c == mask; })
183 char *rawData =
reinterpret_cast<char *
>(
185 std::memcpy(rawData,
data.data(),
data.size());
254 assert(ty.getNumElements() != 1 &&
255 "splat of 1 element should already be detected");
258 const auto &firstElt =
data.front();
263 for (
size_t i = 1, e =
data.size(); i != e; i++)
264 if (firstElt !=
data[i])
265 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
268 return KeyTy(ty,
data.take_front(), hashVal,
true);
291 size_t dataSize =
sizeof(StringRef) * numEntries;
292 for (
int i = 0; i < numEntries; i++)
293 dataSize +=
data[i].size();
295 char *rawData =
reinterpret_cast<char *
>(
296 allocator.
allocate(dataSize,
alignof(uint64_t)));
301 reinterpret_cast<StringRef *
>(rawData), numEntries);
302 auto *stringData = rawData + numEntries *
sizeof(StringRef);
304 for (
int i = 0; i < numEntries; i++) {
306 mutableCopy[i] = StringRef(stringData,
data[i].size());
307 stringData +=
data[i].size();
329 using KeyTy = std::pair<StringRef, Type>;
331 return value == key.first &&
type == key.second;
382 template <
typename T,
typename... Args>
384 static_assert(std::is_same_v<typename T::ImplType, DistinctAttrStorage>,
385 "expects a distinct attribute storage");
387 context, std::forward<Args>(args)...);
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.
ValueT & get()
Return an instance of the value type for the current thread.
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)
Allocates a distinct attribute storage using a thread local bump pointer allocator to enable synchron...
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 ...
inline ::llvm::hash_code hash_value(const PolynomialBase< D, T > &arg)
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.