15#ifndef LLVM_ADT_POINTERUNION_H
16#define LLVM_ADT_POINTERUNION_H
54 for (
size_t I = 1;
I <
sizeof...(PTs); ++
I)
55 if (Bits[
I] < Bits[
I - 1])
69template <
typename... PTs>
71 constexpr size_t N =
sizeof...(PTs);
72 constexpr uintptr_t TagMask = (uintptr_t(1) <<
bitsRequired(
N)) - 1;
73 std::array<TagEntry, N> Result = {};
74 for (
size_t I = 0;
I <
N; ++
I) {
75 Result[
I].Value = uintptr_t(
I);
76 Result[
I].Mask = TagMask;
90template <
typename... PTs>
91constexpr std::optional<std::array<TagEntry,
sizeof...(PTs)>>
93 constexpr size_t N =
sizeof...(PTs);
94 std::array<TagEntry, N> Result = {};
96 uintptr_t EscapePrefix = 0;
104 int TierBits = Bits[
I];
105 if (TierBits < PrevBits)
107 int NewBits = TierBits - PrevBits;
109 while (TierEnd <
N && Bits[TierEnd] == TierBits)
111 bool IsLastTier = (TierEnd ==
N);
112 size_t TypesInTier = TierEnd -
I;
114 IsLastTier ? (size_t(1) << NewBits) : ((size_t(1) << NewBits) - 1);
115 if (TypesInTier > Capacity)
117 for (
size_t J = 0; J < TypesInTier; ++J) {
118 Result[
I + J].Value = EscapePrefix | (uintptr_t(J) << PrevBits);
119 Result[
I + J].Mask = (uintptr_t(1) << TierBits) - 1;
121 uintptr_t EscapeCode = (uintptr_t(1) << NewBits) - 1;
122 EscapePrefix |= EscapeCode << PrevBits;
132template <
typename Derived,
int Idx,
typename... Types>
140 template <
typename To,
typename From,
typename Enable>
141 friend struct ::llvm::CastInfo;
142 template <
typename>
friend struct ::llvm::PointerLikeTypeTraits;
145template <
typename Derived,
int Idx,
typename Type,
typename... Types>
156 using Base::operator=;
158 this->Val = Derived::encode(V);
159 return static_cast<Derived &
>(*this);
189template <
typename... PTs>
193 static_assert(
sizeof...(PTs) > 0,
"PointerUnion must have at least one type");
195 "PointerUnion alternative types cannot be repeated");
200 template <
typename, int,
typename...>
202 template <
typename To,
typename From,
typename Enable>
friend struct CastInfo;
209 static constexpr bool useFixedWidthTags() {
213 static constexpr int minLowBitsAvailable() {
217 static constexpr int tagBits() {
224 static constexpr int tagShift() {
225 return useFixedWidthTags() ? (minLowBitsAvailable() - tagBits()) : 0;
228 using TagTable = std::array<pointer_union_detail::TagEntry,
sizeof...(PTs)>;
231 static constexpr TagTable getTagTable() {
232 if constexpr (useFixedWidthTags()) {
237 "Variable-width PointerUnion types must be in non-decreasing "
238 "NumLowBitsAvailable order");
239 constexpr auto Table =
241 static_assert(Table.has_value(),
242 "Too many types for the available low bits");
250 template <
size_t... Is>
251 static constexpr bool isNullVariableImpl(uintptr_t V,
252 std::index_sequence<Is...>) {
253 constexpr TagTable Table = getTagTable();
254 static_assert(tagShift() == 0,
255 "isNullVariableImpl assumes tag starts at bit 0");
256 return ((V == Table[Is].
Value) || ...);
259 template <
typename T>
static uintptr_t encode(
T V) {
260 constexpr TagTable Table = getTagTable();
261 constexpr int Shift = tagShift();
262 constexpr size_t Idx = FirstIndexOfType<
T, PTs...>::value;
263 static_assert(Table[0].Value == 0,
264 "First type must have tag value 0 for getAddrOfPtr1");
265 uintptr_t PtrInt =
reinterpret_cast<uintptr_t
>(
267 assert((PtrInt & (Table[Idx].Mask << Shift)) == 0 &&
268 "Pointer low bits collide with tag");
269 return PtrInt | (Table[Idx].Value << Shift);
276 using Base::operator=;
280 this->Val = uintptr_t(0);
287 if constexpr (useFixedWidthTags()) {
288 return (
static_cast<uintptr_t
>(this->Val.asInt()) >>
289 minLowBitsAvailable()) == 0;
291 return isNullVariableImpl(
static_cast<uintptr_t
>(this->Val.asInt()),
292 std::index_sequence_for<PTs...>{});
302 template <
typename T> [[deprecated(
"Use isa instead")]]
bool is()
const {
309 template <
typename T> [[deprecated(
"Use cast instead")]]
T get()
const {
330 "First type must have tag value 0 for getAddrOfPtr1");
335 reinterpret_cast<void *
>(this->Val.asInt()) &&
336 "Can't get the address because PointerLikeTypeTraits changes the ptr");
337 return const_cast<First *
>(
338 reinterpret_cast<const First *
>(this->Val.getPointerAddress()));
342 return reinterpret_cast<void *
>(this->Val.asInt());
347 V.Val =
reinterpret_cast<intptr_t
>(VP);
365template <
typename To,
typename... PTs>
368 CastInfo<To, PointerUnion<PTs...>>> {
374 constexpr int Shift = From::tagShift();
376 auto V =
reinterpret_cast<uintptr_t
>(
F.getOpaqueValue());
377 constexpr uintptr_t TagMask = Table[Idx].Mask << Shift;
378 constexpr uintptr_t TagValue = Table[Idx].Value << Shift;
379 return (V & TagMask) == TagValue;
386 constexpr int Shift = From::tagShift();
388 constexpr uintptr_t PtrMask = ~(uintptr_t(Table[Idx].Mask) << Shift);
389 void *Ptr =
reinterpret_cast<void *
>(
390 reinterpret_cast<uintptr_t
>(
F.getOpaqueValue()) & PtrMask);
397template <
typename To,
typename... PTs>
400 CastInfo<To, PointerUnion<PTs...>>> {
412 return P.getOpaqueValue();
432 return Union(FirstInfo::getTombstoneKey());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines DenseMapInfo traits for DenseMap.
This file defines the PointerIntPair class.
A discriminated union of two or more pointer types, with the discriminator in the low bits of the poi...
bool isNull() const
Test if the pointer held in the union is null, regardless of which type it is.
friend bool operator==(PointerUnion lhs, PointerUnion rhs)
friend bool operator!=(PointerUnion lhs, PointerUnion rhs)
friend bool operator<(PointerUnion lhs, PointerUnion rhs)
T get() const
Returns the value of the specified pointer type.
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwise returns null.
First const * getAddrOfPtr1() const
If the union is set to the first pointer type get an address pointing to it.
bool is() const
Test if the Union currently holds the type matching T.
friend class pointer_union_detail::PointerUnionMembers
void * getOpaqueValue() const
friend struct PointerLikeTypeTraits
PointerUnion(std::nullptr_t)
const PointerUnion & operator=(std::nullptr_t)
Assignment from nullptr clears the union, resetting to the first type.
First * getAddrOfPtr1()
If the union is set to the first pointer type get an address pointing to it.
static PointerUnion getFromOpaqueValue(void *VP)
The instances of the Type class are immutable: once they are created, they are never changed.
Derived & operator=(Type V)
PointerUnionMembers(Type V)
PointerUnionMembers()=default
detail::PunnedPointer< void * > Val
CRTP base that generates non-template constructors and assignment operators for each type in the unio...
constexpr int bitsRequired(unsigned NumValues)
Determine the number of bits required to store values in [0, NumValues).
constexpr bool typesInNonDecreasingBitOrder()
True if types are in non-decreasing NumLowBitsAvailable order.
constexpr std::array< TagEntry, sizeof...(PTs)> computeFixedTags()
Compute fixed-width tag table (all types have enough bits for the tag).
constexpr int lowBitsAvailable()
constexpr bool useFixedWidthTags()
True if all types have enough low bits for a fixed-width tag.
constexpr std::optional< std::array< TagEntry, sizeof...(PTs)> > computeExtendedTags()
Compute variable-width tag table, or return std::nullopt if the types don't fit.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
std::tuple_element_t< I, std::tuple< Ts... > > TypeAtIndex
Find the type at a given index in a list of types.
constexpr int bit_width_constexpr(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
static bool isPossible(From &F)
static To doCast(From &F)
PointerUnion< PTs... > From
This struct provides a method for customizing the way a cast is performed.
static bool isPossible(const From &f)
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
PointerUnion< PTs... > Union
static Union getEmptyKey()
static unsigned getHashValue(const Union &UnionVal)
static Union getTombstoneKey()
static bool isEqual(const Union &LHS, const Union &RHS)
DenseMapInfo< TypeAtIndex< 0, PTs... > > FirstInfo
An information struct used to provide DenseMap with the various necessary components for a given valu...
Find the first index where a type appears in a list of types.
PointerUnion< PTs... > Union
static constexpr int NumLowBitsAvailable
static Union getFromVoidPointer(void *P)
static void * getAsVoidPointer(const Union &P)
A traits type that is used to handle pointer types and things that are just wrappers for pointers as ...
Determine if all types in Ts are distinct.
Tag descriptor for one type in the union.