10 #ifndef LLVM_ADT_POINTERSUMTYPE_H 11 #define LLVM_ADT_POINTERSUMTYPE_H 18 #include <type_traits> 26 template <uintptr_t
N,
typename PointerArgT,
27 typename TraitsArgT = PointerLikeTypeTraits<PointerArgT>>
87 StorageT() :
Value(0) {}
91 typename HelperT::template Lookup<HelperT::MinTag>::PointerT MinTagPointer;
101 void set(
typename HelperT::template Lookup<N>::PointerT Pointer) {
102 void *V = HelperT::template Lookup<N>::TraitsT::getAsVoidPointer(Pointer);
103 assert((reinterpret_cast<uintptr_t>(V) & HelperT::TagMask) == 0 &&
104 "Pointer is insufficiently aligned to store the discriminant!");
105 Storage.Value =
reinterpret_cast<uintptr_t
>(V) | N;
111 create(
typename HelperT::template Lookup<N>::PointerT Pointer) {
113 Result.
set<N>(Pointer);
118 void clear() { set<HelperT::MinTag>(
nullptr); }
121 return static_cast<TagT
>(getOpaqueValue() & HelperT::TagMask);
124 template <TagT N>
bool is()
const {
return N ==
getTag(); }
126 template <TagT N>
typename HelperT::template Lookup<N>::PointerT
get()
const {
127 void *
P = is<N>() ? getVoidPtr() :
nullptr;
128 return HelperT::template Lookup<N>::TraitsT::getFromVoidPointer(P);
132 typename HelperT::template Lookup<N>::PointerT
cast()
const {
133 assert(is<N>() &&
"This instance has a different active member.");
134 return HelperT::template Lookup<N>::TraitsT::getFromVoidPointer(
141 typename HelperT::template Lookup<HelperT::MinTag>::PointerT
const *
143 return const_cast<PointerSumType *
>(
this)->getAddrOfZeroTagPointer();
149 typename HelperT::template Lookup<HelperT::MinTag>::PointerT *
151 static_assert(HelperT::MinTag == 0,
"Non-zero minimum tag value!");
152 assert(is<HelperT::MinTag>() &&
"The active tag is not zero!");
154 auto InitialPtr = get<HelperT::MinTag>();
158 Storage.MinTagPointer = InitialPtr;
161 assert(InitialPtr == get<HelperT::MinTag>() &&
162 "Switching to typed storage changed the pointer returned!");
164 return &Storage.MinTagPointer;
167 explicit operator bool()
const {
168 return getOpaqueValue() & HelperT::PointerMask;
192 return bit_cast<uintptr_t>(Storage);
197 return reinterpret_cast<void *
>(getOpaqueValue() & HelperT::PointerMask);
206 template <
typename TagT,
typename...
MemberTs>
207 struct PointerSumTypeHelper :
MemberTs... {
213 template <TagT N,
typename Po
interT,
typename TraitsT>
216 template <TagT N>
static void LookupOverload(...);
220 LookupOverload<N>(static_cast<PointerSumTypeHelper *>(
nullptr)));
232 template <uintptr_t V, uintptr_t... Vs>
233 struct Min : std::integral_constant<
234 uintptr_t, (V < Min<Vs...>::value ? V : Min<Vs...>::value)> {
236 template <uintptr_t V>
237 struct Min<V> : std::integral_constant<uintptr_t, V> {};
238 enum { NumTagBits = Min<MemberTs::TraitsT::NumLowBitsAvailable...>::value };
241 constexpr static TagT MinTag =
242 static_cast<TagT>(Min<MemberTs::Tag...>::value);
244 PointerMask = static_cast<uint64_t>(-1) << NumTagBits,
245 TagMask = ~PointerMask
250 template <typename MemberT, typename... InnerMemberTs>
251 struct Checker : Checker<InnerMemberTs...> {
252 static_assert(MemberT::Tag < (1 << NumTagBits),
253 "This discriminant value requires too many bits!");
255 template <typename MemberT> struct Checker<MemberT> : std::true_type {
256 static_assert(MemberT::Tag < (1 << NumTagBits),
257 "This discriminant value requires too many bits!");
259 static_assert(Checker<MemberTs...>::value,
260 "Each member must pass the checker.");
266 template <typename TagT, typename... MemberTs>
267 struct DenseMapInfo<PointerSumType<TagT, MemberTs...>> {
268 using SumType = PointerSumType<TagT, MemberTs...>;
269 using HelperT = detail::PointerSumTypeHelper<TagT, MemberTs...>;
270 enum { SomeTag = HelperT::MinTag };
272 typename HelperT::template Lookup<HelperT::MinTag>::PointerT;
273 using SomePointerInfo = DenseMapInfo<SomePointerT>;
275 static inline SumType getEmptyKey() {
276 return SumType::create<SomeTag>(SomePointerInfo::getEmptyKey());
279 static inline SumType getTombstoneKey() {
280 return SumType::create<SomeTag>(SomePointerInfo::getTombstoneKey());
283 static unsigned getHashValue(const SumType &Arg) {
284 uintptr_t OpaqueValue = Arg.getOpaqueValue();
285 return DenseMapInfo<uintptr_t>::getHashValue(OpaqueValue);
288 static bool isEqual(const SumType &LHS, const SumType &RHS) {
bool operator==(const PointerSumType &R) const
This class represents lattice values for constants.
A compile time pair of an integer tag and the pointer-like type which it indexes within a sum type...
HelperT::template Lookup< HelperT::MinTag >::PointerT * getAddrOfZeroTagPointer()
If the tag is zero and the pointer's value isn't changed when being stored, get the address of the st...
bool operator>(const PointerSumType &R) const
void clear()
Clear the value to null with the min tag type.
typename MemberT::TraitsT TraitsT
The Nth member's traits type.
HelperT::template Lookup< HelperT::MinTag >::PointerT const * getAddrOfZeroTagPointer() const
If the tag is zero and the pointer's value isn't changed when being stored, get the address of the st...
void set(typename HelperT::template Lookup< N >::PointerT Pointer)
A typed setter to a given tagged member of the sum type.
uintptr_t getOpaqueValue() const
decltype(LookupOverload< N >(static_cast< PointerSumTypeHelper * >(nullptr))) MemberT
static PointerSumType create(typename HelperT::template Lookup< N >::PointerT Pointer)
A typed constructor for a specific tagged member of the sum type.
bool operator>=(const PointerSumType &R) const
bool operator<=(const PointerSumType &R) const
HelperT::template Lookup< N >::PointerT cast() const
void * getVoidPtr() const
bool operator!=(const PointerSumType &R) const
static Optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)
A sum type over pointer-like types.
To bit_cast(const From &from) noexcept
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
A helper template for implementing PointerSumType.
bool operator<(const PointerSumType &R) const
typename MemberT::PointerT PointerT
The Nth member's pointer type.