[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
This commit is contained in:
Lang Hames
2019-05-16 18:29:34 +00:00
parent bcb375a2bf
commit 558b52b517
2 changed files with 37 additions and 14 deletions
@@ -51,21 +51,19 @@ class SymbolStringPtr {
friend class SymbolStringPool;
friend struct DenseMapInfo<SymbolStringPtr>;
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<uintptr_t>(P) - 1) & InvalidPtrMask) !=
InvalidPtrMask;
}
static SymbolStringPtr getEmptyVal() {
return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(EmptyBitPattern));
}
static SymbolStringPtr getTombstoneVal() {
return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(TombstoneBitPattern));
}
constexpr static uintptr_t EmptyBitPattern =
std::numeric_limits<uintptr_t>::max()
<< PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
constexpr static uintptr_t TombstoneBitPattern =
(std::numeric_limits<uintptr_t>::max() - 1)
<< PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
constexpr static uintptr_t InvalidPtrMask =
(std::numeric_limits<uintptr_t>::max() - 3)
<< PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
PoolEntryPtr S = nullptr;
};
inline SymbolStringPool::~SymbolStringPool() {
@@ -150,15 +175,15 @@ template <>
struct DenseMapInfo<orc::SymbolStringPtr> {
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<const void *>::getHashValue(V.S);
return DenseMapInfo<orc::SymbolStringPtr::PoolEntryPtr>::getHashValue(V.S);
}
static bool isEqual(const orc::SymbolStringPtr &LHS,
-2
View File
@@ -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;