14 #ifndef DIALECT_LLVMIR_IR_TYPEDETAIL_H
15 #define DIALECT_LLVMIR_IR_TYPEDETAIL_H
21 #include "llvm/ADT/Bitfields.h"
22 #include "llvm/ADT/PointerIntPair.h"
73 : types(types), name(name), identified(true), packed(false),
77 : types(types), identified(false), packed(packed), opaque(false) {}
83 "'packed' bit is not part of the key for identified structs");
88 "'opaque' bit is meaningless on literal structs");
95 "non-identified struct key cannot have an identifier");
102 "identified struct key cannot have a type list");
109 "requested struct body on a non-identified struct");
118 constexpr
static unsigned kIdentifiedHashFlag = 1;
119 constexpr
static unsigned kPackedHashFlag = 2;
123 flags |= kIdentifiedHashFlag;
127 flags |= kPackedHashFlag;
159 assert(
isIdentified() &&
"requested identifier on a non-identified struct");
160 return StringRef(
static_cast<const char *
>(keyPtr), keySize());
166 assert(!
isIdentified() &&
"requested typelist on an identified struct");
174 "requested struct body on a non-identified struct");
180 return llvm::Bitfield::get<KeyFlagIdentified>(keySizeAndFlags);
185 return isIdentified() ? llvm::Bitfield::get<MutableFlagPacked>(
186 identifiedBodySizeAndFlags)
187 : llvm::Bitfield::get<KeyFlagPacked>(keySizeAndFlags);
194 return llvm::Bitfield::get<MutableFlagOpaque>(identifiedBodySizeAndFlags);
200 return llvm::Bitfield::get<MutableFlagInitialized>(
201 identifiedBodySizeAndFlags);
211 keyPtr =
static_cast<const void *
>(types.data());
212 setKeySize(types.size());
213 llvm::Bitfield::set<KeyFlagPacked>(keySizeAndFlags, key.
isPacked());
218 keyPtr =
static_cast<const void *
>(name.data());
219 setKeySize(name.size());
220 llvm::Bitfield::set<KeyFlagIdentified>(keySizeAndFlags,
true);
224 llvm::Bitfield::set<MutableFlagInitialized>(identifiedBodySizeAndFlags,
226 llvm::Bitfield::set<MutableFlagOpaque>(identifiedBodySizeAndFlags,
251 llvm::Bitfield::set<MutableFlagInitialized>(identifiedBodySizeAndFlags,
253 llvm::Bitfield::set<MutableFlagPacked>(identifiedBodySizeAndFlags, packed);
256 identifiedBodyArray = typesInAllocator.data();
257 setIdentifiedBodySize(typesInAllocator.size());
271 unsigned keySize()
const {
272 return llvm::Bitfield::get<KeySize>(keySizeAndFlags);
276 void setKeySize(
unsigned value) {
277 llvm::Bitfield::set<KeySize>(keySizeAndFlags, value);
281 unsigned identifiedBodySize()
const {
282 return llvm::Bitfield::get<MutableSize>(identifiedBodySizeAndFlags);
285 void setIdentifiedBodySize(
unsigned value) {
286 llvm::Bitfield::set<MutableSize>(identifiedBodySizeAndFlags, value);
293 using KeyFlagIdentified =
294 llvm::Bitfield::Element<bool, 0, 1>;
295 using KeyFlagPacked = llvm::Bitfield::Element<bool, 1, 1>;
297 llvm::Bitfield::Element<unsigned, 2,
298 std::numeric_limits<unsigned>::digits - 2>;
305 using MutableFlagOpaque =
306 llvm::Bitfield::Element<bool, 0, 1>;
307 using MutableFlagPacked =
308 llvm::Bitfield::Element<bool, 1, 1>;
309 using MutableFlagInitialized =
310 llvm::Bitfield::Element<bool, 2, 1>;
312 llvm::Bitfield::Element<unsigned, 3,
313 std::numeric_limits<unsigned>::digits - 3>;
318 const void *keyPtr =
nullptr;
321 const Type *identifiedBodyArray =
nullptr;
325 unsigned keySizeAndFlags = 0;
329 unsigned identifiedBodySizeAndFlags = 0;
368 using KeyTy = std::tuple<Type, unsigned>;
This class is used by AttrTypeSubElementHandler instances to process sub element replacements.
ArrayRef< T > take_front(unsigned n)
Take the first N replacements as an ArrayRef, dropping them from this replacement list.
This class provides support for representing a failure result, or a valid value of type T.
Construction/uniquing key class for LLVM dialect structure storage.
Key(StringRef name, bool opaque, ArrayRef< Type > types=std::nullopt)
Constructs a key for an identified struct.
bool isIdentified() const
Checks a specific property of the struct.
llvm::hash_code hashValue() const
Returns the hash value of the key.
StringRef getIdentifier() const
Returns the identifier of a key for identified structs.
bool operator==(const Key &other) const
Compares two keys.
ArrayRef< Type > getIdentifiedStructBody() const
Returns the list of type contained in an identified struct.
Key copyIntoAllocator(TypeStorageAllocator &allocator) const
Copies dynamically-sized components of the key into the given allocator.
ArrayRef< Type > getTypeList() const
Returns the list of type contained in the key of a literal struct.
Key(ArrayRef< Type > types, bool packed)
Constructs a key for a literal struct.
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.
Base storage class appearing in a Type.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
static void walk(const LLVM::detail::LLVMStructTypeStorage::Key ¶m, AttrTypeImmediateSubElementWalker &walker)
static FailureOr< LLVM::detail::LLVMStructTypeStorage::Key > replace(const LLVM::detail::LLVMStructTypeStorage::Key ¶m, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
This class provides support for interacting with the SubElementInterfaces for different types of para...
Type storage for LLVM structure types.
ArrayRef< Type > getTypeList() const
Returns the list of types (partially) identifying a literal struct.
StringRef getIdentifier() const
Returns the string identifier of an identified struct.
ArrayRef< Type > getIdentifiedStructBody() const
Returns the list of types contained in an identified struct.
LogicalResult mutate(TypeStorageAllocator &allocator, ArrayRef< Type > body, bool packed)
Sets the body of an identified struct.
static LLVMStructTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
static llvm::hash_code hashKey(const KeyTy &key)
Key getAsKey() const
Returns the key for the current storage.
bool operator==(const KeyTy &other) const
Hook into the type uniquing infrastructure.
LLVMStructTypeStorage(const KeyTy &key)
Constructs the storage from the given key.
bool isIdentified() const
Checks whether the struct is identified.
bool isInitialized() const
Checks whether an identified struct has been explicitly initialized either by setting its body or by ...
bool isOpaque() const
Checks whether a struct is marked as intentionally opaque (an uninitialized struct is also considered...
bool isPacked() const
Checks whether the struct is packed (both literal and identified structs).
Common storage used for LLVM dialect types that need an element type and a number: arrays,...
std::tuple< Type, unsigned > KeyTy
static LLVMTypeAndSizeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
bool operator==(const KeyTy &key) const
LLVMTypeAndSizeStorage(const KeyTy &key)
This class represents an efficient way to signal success or failure.