From: Lang Hames Date: Thu, 16 May 2019 18:29:34 +0000 (+0000) Subject: [ORC] Change handling for SymbolStringPtr tombstones and empty keys. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=558b52b517b8c989dc2d7fffb5c580fa45aece34;p=llvm [ORC] Change handling for SymbolStringPtr tombstones and empty keys. SymbolStringPtr used to use nullptr as its empty value and (since it performed ref-count operations on any non-nullptr) a pointer to a special pool-entry instance as its tombstone. This commit changes the scheme to use two invalid pointer values as the empty and tombstone values, and broadens the ref-count guard to prevent ref-counting operations from being performed on these pointers. This should improve the performance of SymbolStringPtrs used in DenseMaps/DenseSets, as ref counting operations will no longer be performed on the tombstone. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360925 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h index 8c638e3f541..c354f6c3559 100644 --- a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h +++ b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h @@ -51,21 +51,19 @@ class SymbolStringPtr { friend class SymbolStringPool; friend struct DenseMapInfo; - static SymbolStringPool::PoolMapEntry Tombstone; - public: SymbolStringPtr() = default; SymbolStringPtr(const SymbolStringPtr &Other) : S(Other.S) { - if (S) + if (isRealPoolEntry(S)) ++S->getValue(); } SymbolStringPtr& operator=(const SymbolStringPtr &Other) { - if (S) + if (isRealPoolEntry(S)) --S->getValue(); S = Other.S; - if (S) + if (isRealPoolEntry(S)) ++S->getValue(); return *this; } @@ -75,7 +73,7 @@ public: } SymbolStringPtr& operator=(SymbolStringPtr &&Other) { - if (S) + if (isRealPoolEntry(S)) --S->getValue(); S = nullptr; std::swap(S, Other.S); @@ -83,7 +81,7 @@ public: } ~SymbolStringPtr() { - if (S) + if (isRealPoolEntry(S)) --S->getValue(); } @@ -105,14 +103,41 @@ public: } private: + using PoolEntryPtr = SymbolStringPool::PoolMapEntry *; SymbolStringPtr(SymbolStringPool::PoolMapEntry *S) : S(S) { - if (S) + if (isRealPoolEntry(S)) ++S->getValue(); } - SymbolStringPool::PoolMapEntry *S = nullptr; + // Returns false for null, empty, and tombstone values, true otherwise. + bool isRealPoolEntry(PoolEntryPtr P) { + return ((reinterpret_cast(P) - 1) & InvalidPtrMask) != + InvalidPtrMask; + } + + static SymbolStringPtr getEmptyVal() { + return SymbolStringPtr(reinterpret_cast(EmptyBitPattern)); + } + + static SymbolStringPtr getTombstoneVal() { + return SymbolStringPtr(reinterpret_cast(TombstoneBitPattern)); + } + + constexpr static uintptr_t EmptyBitPattern = + std::numeric_limits::max() + << PointerLikeTypeTraits::NumLowBitsAvailable; + + constexpr static uintptr_t TombstoneBitPattern = + (std::numeric_limits::max() - 1) + << PointerLikeTypeTraits::NumLowBitsAvailable; + + constexpr static uintptr_t InvalidPtrMask = + (std::numeric_limits::max() - 3) + << PointerLikeTypeTraits::NumLowBitsAvailable; + + PoolEntryPtr S = nullptr; }; inline SymbolStringPool::~SymbolStringPool() { @@ -150,15 +175,15 @@ template <> struct DenseMapInfo { static orc::SymbolStringPtr getEmptyKey() { - return orc::SymbolStringPtr(); + return orc::SymbolStringPtr::getEmptyVal(); } static orc::SymbolStringPtr getTombstoneKey() { - return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone); + return orc::SymbolStringPtr::getTombstoneVal(); } static unsigned getHashValue(const orc::SymbolStringPtr &V) { - return DenseMapInfo::getHashValue(V.S); + return DenseMapInfo::getHashValue(V.S); } static bool isEqual(const orc::SymbolStringPtr &LHS, diff --git a/lib/ExecutionEngine/Orc/Core.cpp b/lib/ExecutionEngine/Orc/Core.cpp index 674b44501ac..bbc5a3e8dab 100644 --- a/lib/ExecutionEngine/Orc/Core.cpp +++ b/lib/ExecutionEngine/Orc/Core.cpp @@ -133,8 +133,6 @@ struct PrintSymbolMapElemsMatchingCLOpts { namespace llvm { namespace orc { -SymbolStringPool::PoolMapEntry SymbolStringPtr::Tombstone(0); - char FailedToMaterialize::ID = 0; char SymbolsNotFound::ID = 0; char SymbolsCouldNotBeRemoved::ID = 0;