forked from OSchip/llvm-project
[SmallPtrSet] Introduce a find primitive and rewrite count/erase in terms of it
This was originally motivated by a compile time problem I've since figured out how to solve differently, but the cleanup seemed useful. We had the same logic - which essentially implemented find - in several places. By commoning them out, I can implement find and allow erase to be inlined at the call sites if profitable. Differential Revision: https://reviews.llvm.org/D28183 llvm-svn: 290779
This commit is contained in:
parent
97cf837b46
commit
0ef5d288b4
|
@ -162,22 +162,38 @@ protected:
|
|||
/// return true, otherwise return false. This is hidden from the client so
|
||||
/// that the derived class can check that the right type of pointer is passed
|
||||
/// in.
|
||||
bool erase_imp(const void * Ptr);
|
||||
bool erase_imp(const void * Ptr) {
|
||||
const void *const *P = find_imp(Ptr);
|
||||
if (P == EndPointer())
|
||||
return false;
|
||||
|
||||
const void ** Loc = const_cast<const void **>(P);
|
||||
assert(*Loc == Ptr && "broken find!");
|
||||
*Loc = getTombstoneMarker();
|
||||
NumTombstones++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool count_imp(const void * Ptr) const {
|
||||
/// Returns the raw pointer needed to construct an iterator. If element not
|
||||
/// found, this will be EndPointer. Otherwise, it will be a pointer to the
|
||||
/// slot which stores Ptr;
|
||||
const void *const * find_imp(const void * Ptr) const {
|
||||
if (isSmall()) {
|
||||
// Linear search for the item.
|
||||
for (const void *const *APtr = SmallArray,
|
||||
*const *E = SmallArray + NumNonEmpty; APtr != E; ++APtr)
|
||||
if (*APtr == Ptr)
|
||||
return true;
|
||||
return false;
|
||||
return APtr;
|
||||
return EndPointer();
|
||||
}
|
||||
|
||||
// Big set case.
|
||||
return *FindBucketFor(Ptr) == Ptr;
|
||||
auto *Bucket = FindBucketFor(Ptr);
|
||||
if (*Bucket == Ptr)
|
||||
return Bucket;
|
||||
return EndPointer();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
bool isSmall() const { return CurArray == SmallArray; }
|
||||
|
||||
|
@ -362,7 +378,11 @@ public:
|
|||
|
||||
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
|
||||
size_type count(PtrType Ptr) const {
|
||||
return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
|
||||
return find(Ptr) != endPtr() ? 1 : 0;
|
||||
}
|
||||
iterator find(PtrType Ptr) const {
|
||||
auto *P = find_imp(PtrTraits::getAsVoidPointer(Ptr));
|
||||
return iterator(P, EndPointer());
|
||||
}
|
||||
|
||||
template <typename IterT>
|
||||
|
|
|
@ -61,31 +61,6 @@ SmallPtrSetImplBase::insert_imp_big(const void *Ptr) {
|
|||
return std::make_pair(Bucket, true);
|
||||
}
|
||||
|
||||
bool SmallPtrSetImplBase::erase_imp(const void * Ptr) {
|
||||
if (isSmall()) {
|
||||
// Check to see if it is in the set.
|
||||
for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty; APtr != E;
|
||||
++APtr)
|
||||
if (*APtr == Ptr) {
|
||||
// If it is in the set, replace this element.
|
||||
*APtr = getTombstoneMarker();
|
||||
++NumTombstones;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Okay, we know we have space. Find a hash bucket.
|
||||
void **Bucket = const_cast<void**>(FindBucketFor(Ptr));
|
||||
if (*Bucket != Ptr) return false; // Not in the set?
|
||||
|
||||
// Set this as a tombstone.
|
||||
*Bucket = getTombstoneMarker();
|
||||
++NumTombstones;
|
||||
return true;
|
||||
}
|
||||
|
||||
const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const {
|
||||
unsigned Bucket = DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize-1);
|
||||
unsigned ArraySize = CurArraySize;
|
||||
|
|
Loading…
Reference in New Issue