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"
39 if (ComplexType comp = llvm::dyn_cast<ComplexType>(eltType))
42 return IndexType::kInternalStorageBitWidth;
96 bool isBoolData = ty.getElementType().isInteger(1);
106 size_t numElements = ty.getNumElements();
107 assert(numElements != 1 &&
"splat of 1 element should already be detected");
116 assert(((
data.size() / storageSize) == numElements) &&
117 "data does not hold expected number of elements");
120 auto firstElt =
data.take_front(storageSize);
125 for (
size_t i = storageSize, e =
data.size(); i != e; i += storageSize)
126 if (memcmp(
data.data(), &
data[i], storageSize))
127 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
130 return KeyTy(ty, firstElt, hashVal,
true);
135 size_t numElements) {
137 bool splatValue = splatData.front() & 1;
145 size_t numOddElements = numElements % CHAR_BIT;
146 if (splatValue && numOddElements != 0) {
148 char lastElt = splatData.back();
149 if (lastElt != llvm::maskTrailingOnes<unsigned char>(numOddElements))
153 if (splatData.size() == 1)
155 splatData = splatData.drop_back();
159 char mask = splatValue ? ~0 : 0;
160 return llvm::all_of(splatData, [mask](
char c) {
return c == mask; })
184 char *rawData =
reinterpret_cast<char *
>(
186 std::memcpy(rawData,
data.data(),
data.size());
255 assert(ty.getNumElements() != 1 &&
256 "splat of 1 element should already be detected");
259 const auto &firstElt =
data.front();
264 for (
size_t i = 1, e =
data.size(); i != e; i++)
265 if (firstElt !=
data[i])
266 return KeyTy(ty,
data, llvm::hash_combine(hashVal,
data.drop_front(i)));
269 return KeyTy(ty,
data.take_front(), hashVal,
true);
292 size_t dataSize =
sizeof(StringRef) * numEntries;
293 for (
int i = 0; i < numEntries; i++)
294 dataSize +=
data[i].size();
296 char *rawData =
reinterpret_cast<char *
>(
297 allocator.
allocate(dataSize,
alignof(uint64_t)));
302 reinterpret_cast<StringRef *
>(rawData), numEntries);
303 auto *stringData = rawData + numEntries *
sizeof(StringRef);
305 for (
int i = 0; i < numEntries; i++) {
307 mutableCopy[i] = StringRef(stringData,
data[i].size());
308 stringData +=
data[i].size();
330 using KeyTy = std::pair<StringRef, Type>;
332 return value == key.first &&
type == key.second;
383 template <
typename T,
typename... Args>
385 static_assert(std::is_same_v<typename T::ImplType, DistinctAttrStorage>,
386 "expects a distinct attribute storage");
388 context, std::forward<Args>(args)...);
406 : threadingIsEnabled(threadingIsEnabled), useThreadLocalAllocator(true) {};
416 if (!useThreadLocalAllocator && threadingIsEnabled) {
417 std::scoped_lock<std::mutex> lock(allocatorMutex);
418 return allocateImpl(referencedAttr);
420 return allocateImpl(referencedAttr);
426 threadingIsEnabled = !disable;
434 useThreadLocalAllocator = !disable;
447 llvm::BumpPtrAllocator &getAllocatorInUse() {
448 if (useThreadLocalAllocator)
449 return allocatorCache.
get();
453 ThreadLocalCache<llvm::BumpPtrAllocator> allocatorCache;
454 llvm::BumpPtrAllocator allocator;
455 std::mutex allocatorMutex;
457 bool threadingIsEnabled : 1;
458 bool useThreadLocalAllocator : 1;
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 & 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...
void disableMultiThreading(bool disable=true)
Sets a flag that stores if multithreading is enabled.
DistinctAttributeAllocator(bool threadingIsEnabled)
void disableThreadLocalStorage(bool disable=true)
Sets a flag to disable using thread local bump pointer allocators and use a single thread-safe alloca...
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.