https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/146595
>From 8bfa43c61c47c978ddcba509f22cf0a605b83fa0 Mon Sep 17 00:00:00 2001 From: Nikita Popov <npo...@redhat.com> Date: Tue, 1 Jul 2025 13:51:43 +0200 Subject: [PATCH 1/2] [DenseMap] Do not align pointer sentinel values (NFC) DenseMapInfo for pointers currently uses empty/tombstone values that are aligned (by assuming a very conservative alignment). However, this means that we have to work with large immediates. This patch proposed to use the values -1 and -2 instead, without caring about pointer alignment. This puts us into unspecified territory from the perspective of the C standard, but it is Clang's explicit position that raw pointers do not carry alignment guarantees (only accesses do). We already have lots of places that do variations on `reinterpret_cast<T*>(-1)` and assume that to work, so I'm not sure it's worthwhile to be strictly standards conforming in this single place. --- llvm/include/llvm/ADT/DenseMapInfo.h | 25 ++++--------------------- llvm/include/llvm/ADT/PointerUnion.h | 14 ++++++++++---- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h index 07c37e353a40b..b371611e7d948 100644 --- a/llvm/include/llvm/ADT/DenseMapInfo.h +++ b/llvm/include/llvm/ADT/DenseMapInfo.h @@ -56,30 +56,13 @@ struct DenseMapInfo { //static bool isEqual(const T &LHS, const T &RHS); }; -// Provide DenseMapInfo for all pointers. Come up with sentinel pointer values -// that are aligned to alignof(T) bytes, but try to avoid requiring T to be -// complete. This allows clients to instantiate DenseMap<T*, ...> with forward -// declared key types. Assume that no pointer key type requires more than 4096 -// bytes of alignment. -template<typename T> -struct DenseMapInfo<T*> { - // The following should hold, but it would require T to be complete: - // static_assert(alignof(T) <= (1 << Log2MaxAlign), - // "DenseMap does not support pointer keys requiring more than " - // "Log2MaxAlign bits of alignment"); - static constexpr uintptr_t Log2MaxAlign = 12; - +template <typename T> struct DenseMapInfo<T *> { static inline T* getEmptyKey() { - uintptr_t Val = static_cast<uintptr_t>(-1); - Val <<= Log2MaxAlign; - return reinterpret_cast<T*>(Val); + // We assume that raw pointers do not carry alignment requirements. + return reinterpret_cast<T *>(-1); } - static inline T* getTombstoneKey() { - uintptr_t Val = static_cast<uintptr_t>(-2); - Val <<= Log2MaxAlign; - return reinterpret_cast<T*>(Val); - } + static inline T *getTombstoneKey() { return reinterpret_cast<T *>(-2); } static unsigned getHashValue(const T *PtrVal) { return (unsigned((uintptr_t)PtrVal) >> 4) ^ diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h index cdbd76d7f505b..86248a2cf836f 100644 --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h @@ -286,13 +286,19 @@ struct PointerLikeTypeTraits<PointerUnion<PTs...>> { // Teach DenseMap how to use PointerUnions as keys. template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> { using Union = PointerUnion<PTs...>; - using FirstInfo = - DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>; + using FirstTypeTraits = PointerLikeTypeTraits< + typename pointer_union_detail::GetFirstType<PTs...>::type>; - static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } + static inline Union getEmptyKey() { + uintptr_t Val = static_cast<uintptr_t>(-1); + Val <<= FirstTypeTraits::NumLowBitsAvailable; + return FirstTypeTraits::getFromVoidPointer(reinterpret_cast<void *>(Val)); + } static inline Union getTombstoneKey() { - return Union(FirstInfo::getTombstoneKey()); + uintptr_t Val = static_cast<uintptr_t>(-2); + Val <<= FirstTypeTraits::NumLowBitsAvailable; + return FirstTypeTraits::getFromVoidPointer(reinterpret_cast<void *>(Val)); } static unsigned getHashValue(const Union &UnionVal) { >From b4509bde24a256425af6946e59564f883f891b2f Mon Sep 17 00:00:00 2001 From: Nikita Popov <npo...@redhat.com> Date: Wed, 2 Jul 2025 09:53:39 +0200 Subject: [PATCH 2/2] Update DenseMapInfo for LValueBase --- clang/lib/AST/APValue.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index c641ff6b99bab..acba55742a967 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -187,14 +187,14 @@ APValue::LValueBase::operator bool () const { clang::APValue::LValueBase llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() { clang::APValue::LValueBase B; - B.Ptr = DenseMapInfo<const ValueDecl*>::getEmptyKey(); + B.Ptr = DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(); return B; } clang::APValue::LValueBase llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() { clang::APValue::LValueBase B; - B.Ptr = DenseMapInfo<const ValueDecl*>::getTombstoneKey(); + B.Ptr = DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(); return B; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits