9#ifndef LLVM_ADT_POINTERSUMTYPE_H
10#define LLVM_ADT_POINTERSUMTYPE_H
25template <uintptr_t
N,
typename PointerArgT,
26 typename TraitsArgT = PointerLikeTypeTraits<PointerArgT>>
35template <
typename TagT,
typename... MemberTs>
struct PointerSumTypeHelper;
86 StorageT() :
Value(0) {}
90 typename HelperT::template Lookup<HelperT::MinTag>::PointerT MinTagPointer;
100 void set(
typename HelperT::template Lookup<N>::PointerT Pointer) {
101 void *V = HelperT::template Lookup<N>::TraitsT::getAsVoidPointer(Pointer);
103 "Pointer is insufficiently aligned to store the discriminant!");
104 Storage.Value =
reinterpret_cast<uintptr_t
>(V) |
N;
110 create(
typename HelperT::template Lookup<N>::PointerT Pointer) {
112 Result.set<
N>(Pointer);
117 void clear() { set<HelperT::MinTag>(
nullptr); }
123 template <TagT N>
bool is()
const {
return N ==
getTag(); }
125 template <TagT N>
typename HelperT::template Lookup<N>::PointerT
get()
const {
127 return HelperT::template Lookup<N>::TraitsT::getFromVoidPointer(
P);
131 typename HelperT::template Lookup<N>::PointerT
cast()
const {
132 assert(is<N>() &&
"This instance has a different active member.");
133 return HelperT::template Lookup<N>::TraitsT::getFromVoidPointer(
140 typename HelperT::template Lookup<HelperT::MinTag>::PointerT
const *
148 typename HelperT::template Lookup<HelperT::MinTag>::PointerT *
151 assert(is<HelperT::MinTag>() &&
"The active tag is not zero!");
153 auto InitialPtr = get<HelperT::MinTag>();
157 Storage.MinTagPointer = InitialPtr;
160 assert(InitialPtr == get<HelperT::MinTag>() &&
161 "Switching to typed storage changed the pointer returned!");
163 return &Storage.MinTagPointer;
166 explicit operator bool()
const {
191 return bit_cast<uintptr_t>(Storage);
205template <
typename TagT,
typename... MemberTs>
212 template <TagT N,
typename Po
interT,
typename TraitsT>
231 template <uintptr_t V, uintptr_t... Vs>
232 struct Min : std::integral_constant<
233 uintptr_t, (V < Min<Vs...>::value ? V : Min<Vs...>::value)> {
235 template <uintptr_t V>
236 struct Min<V> : std::integral_constant<uintptr_t, V> {};
237 enum { NumTagBits = Min<MemberTs::TraitsT::NumLowBitsAvailable...>::value };
240 constexpr static TagT MinTag =
241 static_cast<TagT>(Min<MemberTs::Tag...>::value);
243 PointerMask = static_cast<uint64_t>(-1) << NumTagBits,
244 TagMask = ~PointerMask
249 template <typename MemberT, typename... InnerMemberTs>
250 struct Checker : Checker<InnerMemberTs...> {
251 static_assert(MemberT::Tag < (1 << NumTagBits),
252 "This discriminant value requires too many bits!");
254 template <typename MemberT> struct Checker<MemberT> : std::true_type {
255 static_assert(MemberT::Tag < (1 << NumTagBits),
256 "This discriminant value requires too many bits!");
258 static_assert(Checker<MemberTs...>::value,
259 "Each member must pass the checker.");
265template <typename TagT, typename... MemberTs>
266struct DenseMapInfo<PointerSumType<TagT, MemberTs...>> {
267 using SumType = PointerSumType<TagT, MemberTs...>;
268 using HelperT = detail::PointerSumTypeHelper<TagT, MemberTs...>;
269 enum { SomeTag = HelperT::MinTag };
271 typename HelperT::template Lookup<HelperT::MinTag>::PointerT;
272 using SomePointerInfo = DenseMapInfo<SomePointerT>;
274 static inline SumType getEmptyKey() {
275 return SumType::template create<SomeTag>(SomePointerInfo::getEmptyKey());
278 static inline SumType getTombstoneKey() {
279 return SumType::template create<SomeTag>(
280 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) {
This file defines DenseMapInfo traits for DenseMap.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the C++20 <bit> header.
A sum type over pointer-like types.
bool operator<=(const PointerSumType &R) const
HelperT::template Lookup< N >::PointerT cast() const
bool operator==(const PointerSumType &R) const
bool operator>=(const PointerSumType &R) const
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
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...
void clear()
Clear the value to null with the min tag 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...
uintptr_t getOpaqueValue() const
HelperT::template Lookup< N >::PointerT get() const
bool operator>(const PointerSumType &R) const
bool operator<(const PointerSumType &R) const
constexpr PointerSumType()=default
void * getVoidPtr() const
void set(typename HelperT::template Lookup< N >::PointerT Pointer)
A typed setter to a given tagged member of the sum type.
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
A compile time pair of an integer tag and the pointer-like type which it indexes within a sum type.
typename MemberT::PointerT PointerT
The Nth member's pointer type.
decltype(LookupOverload< N >(static_cast< PointerSumTypeHelper * >(nullptr))) MemberT
A helper template for implementing PointerSumType.
static void LookupOverload(...)
static constexpr TagT MinTag
static PointerSumTypeMember< N, PointerT, TraitsT > LookupOverload(PointerSumTypeMember< N, PointerT, TraitsT > *)