Skip to content

Conversation

@kazutakahirata
Copy link
Contributor

This patch removes getEmptyKey, getTombstoneKey, and getHashValue from
DenseMapBase. These forwarder methods do not really encapsulate
KeyInfoT. Many of their callers already mention KeyInfoT::isEqual for
example.

An existing static_assert is moved to another method. Note that it
must live in a method for type completeness reasons.

This patch removes getEmptyKey, getTombstoneKey, and getHashValue from
DenseMapBase.  These forwarder methods do not really encapsulate
KeyInfoT.  Many of their callers already mention KeyInfoT::isEqual for
example.

An existing static_assert is moved to another method.  Note that it
must live in a method for type completeness reasons.
@llvmbot
Copy link
Member

llvmbot commented Oct 25, 2025

@llvm/pr-subscribers-llvm-adt

Author: Kazu Hirata (kazutakahirata)

Changes

This patch removes getEmptyKey, getTombstoneKey, and getHashValue from
DenseMapBase. These forwarder methods do not really encapsulate
KeyInfoT. Many of their callers already mention KeyInfoT::isEqual for
example.

An existing static_assert is moved to another method. Note that it
must live in a method for type completeness reasons.


Full diff: https://github.com/llvm/llvm-project/pull/165102.diff

1 Files Affected:

  • (modified) llvm/include/llvm/ADT/DenseMap.h (+23-33)
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index baa91f3a5f533..f2ebe045c8503 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -130,13 +130,13 @@ class DenseMapBase : public DebugEpochBase {
       return;
     }
 
-    const KeyT EmptyKey = getEmptyKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
     if constexpr (std::is_trivially_destructible_v<ValueT>) {
       // Use a simpler loop when values don't need destruction.
       for (BucketT &B : buckets())
         B.getFirst() = EmptyKey;
     } else {
-      const KeyT TombstoneKey = getTombstoneKey();
+      const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
       unsigned NumEntries = getNumEntries();
       for (BucketT &B : buckets()) {
         if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey)) {
@@ -314,7 +314,7 @@ class DenseMapBase : public DebugEpochBase {
       return false; // not in map.
 
     TheBucket->getSecond().~ValueT();
-    TheBucket->getFirst() = getTombstoneKey();
+    TheBucket->getFirst() = KeyInfoT::getTombstoneKey();
     decrementNumEntries();
     incrementNumTombstones();
     return true;
@@ -322,7 +322,7 @@ class DenseMapBase : public DebugEpochBase {
   void erase(iterator I) {
     BucketT *TheBucket = &*I;
     TheBucket->getSecond().~ValueT();
-    TheBucket->getFirst() = getTombstoneKey();
+    TheBucket->getFirst() = KeyInfoT::getTombstoneKey();
     decrementNumEntries();
     incrementNumTombstones();
   }
@@ -362,7 +362,8 @@ class DenseMapBase : public DebugEpochBase {
     if (getNumBuckets() == 0) // Nothing to do.
       return;
 
-    const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+    const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
     for (BucketT &B : buckets()) {
       if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) &&
           !KeyInfoT::isEqual(B.getFirst(), TombstoneKey))
@@ -372,12 +373,14 @@ class DenseMapBase : public DebugEpochBase {
   }
 
   void initEmpty() {
+    static_assert(std::is_base_of_v<DenseMapBase, DerivedT>,
+                  "Must pass the derived type to this template!");
     setNumEntries(0);
     setNumTombstones(0);
 
     assert((getNumBuckets() & (getNumBuckets() - 1)) == 0 &&
            "# initial buckets must be a power of two!");
-    const KeyT EmptyKey = getEmptyKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
     for (BucketT &B : buckets())
       ::new (&B.getFirst()) KeyT(EmptyKey);
   }
@@ -397,8 +400,8 @@ class DenseMapBase : public DebugEpochBase {
     initEmpty();
 
     // Insert all the old elements.
-    const KeyT EmptyKey = getEmptyKey();
-    const KeyT TombstoneKey = getTombstoneKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+    const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
     for (BucketT &B : OldBuckets) {
       if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) &&
           !KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) {
@@ -435,8 +438,8 @@ class DenseMapBase : public DebugEpochBase {
       memcpy(reinterpret_cast<void *>(Buckets), OtherBuckets,
              NumBuckets * sizeof(BucketT));
     } else {
-      const KeyT EmptyKey = getEmptyKey();
-      const KeyT TombstoneKey = getTombstoneKey();
+      const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+      const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
       for (size_t I = 0; I < NumBuckets; ++I) {
         ::new (&Buckets[I].getFirst()) KeyT(OtherBuckets[I].getFirst());
         if (!KeyInfoT::isEqual(Buckets[I].getFirst(), EmptyKey) &&
@@ -446,19 +449,6 @@ class DenseMapBase : public DebugEpochBase {
     }
   }
 
-  template <typename LookupKeyT>
-  static unsigned getHashValue(const LookupKeyT &Val) {
-    return KeyInfoT::getHashValue(Val);
-  }
-
-  static const KeyT getEmptyKey() {
-    static_assert(std::is_base_of_v<DenseMapBase, DerivedT>,
-                  "Must pass the derived type to this template!");
-    return KeyInfoT::getEmptyKey();
-  }
-
-  static const KeyT getTombstoneKey() { return KeyInfoT::getTombstoneKey(); }
-
 private:
   DerivedT &derived() { return *static_cast<DerivedT *>(this); }
   const DerivedT &derived() const {
@@ -566,7 +556,7 @@ class DenseMapBase : public DebugEpochBase {
     incrementNumEntries();
 
     // If we are writing over a tombstone, remember this.
-    const KeyT EmptyKey = getEmptyKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
     if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey))
       decrementNumTombstones();
 
@@ -580,8 +570,8 @@ class DenseMapBase : public DebugEpochBase {
     if (NumBuckets == 0)
       return nullptr;
 
-    const KeyT EmptyKey = getEmptyKey();
-    unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1);
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+    unsigned BucketNo = KeyInfoT::getHashValue(Val) & (NumBuckets - 1);
     unsigned ProbeAmt = 1;
     while (true) {
       const BucketT *Bucket = BucketsPtr + BucketNo;
@@ -618,13 +608,13 @@ class DenseMapBase : public DebugEpochBase {
 
     // FoundTombstone - Keep track of whether we find a tombstone while probing.
     BucketT *FoundTombstone = nullptr;
-    const KeyT EmptyKey = getEmptyKey();
-    const KeyT TombstoneKey = getTombstoneKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+    const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
     assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
            !KeyInfoT::isEqual(Val, TombstoneKey) &&
            "Empty/Tombstone value shouldn't be inserted into map!");
 
-    unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1);
+    unsigned BucketNo = KeyInfoT::getHashValue(Val) & (NumBuckets - 1);
     unsigned ProbeAmt = 1;
     while (true) {
       BucketT *ThisBucket = BucketsPtr + BucketNo;
@@ -934,8 +924,8 @@ class SmallDenseMap
     NumEntries = TmpNumEntries;
     std::swap(NumTombstones, RHS.NumTombstones);
 
-    const KeyT EmptyKey = this->getEmptyKey();
-    const KeyT TombstoneKey = this->getTombstoneKey();
+    const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+    const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
     if (Small && RHS.Small) {
       // If we're swapping inline bucket arrays, we have to cope with some of
       // the tricky bits of DenseMap's storage system: the buckets are not
@@ -1135,8 +1125,8 @@ class SmallDenseMap
 
       // Loop over the buckets, moving non-empty, non-tombstones into the
       // temporary storage. Have the loop move the TmpEnd forward as it goes.
-      const KeyT EmptyKey = this->getEmptyKey();
-      const KeyT TombstoneKey = this->getTombstoneKey();
+      const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+      const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
       for (BucketT &B : inlineBuckets()) {
         if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) &&
             !KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) {

@kazutakahirata kazutakahirata merged commit e490920 into llvm:main Oct 25, 2025
12 checks passed
@kazutakahirata kazutakahirata deleted the cleanup_20251025_ADT_DenseMap_getHashValue branch October 25, 2025 17:05
dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
This patch removes getEmptyKey, getTombstoneKey, and getHashValue from
DenseMapBase.  These forwarder methods do not really encapsulate
KeyInfoT.  Many of their callers already mention KeyInfoT::isEqual for
example.

An existing static_assert is moved to another method.  Note that it
must live in a method for type completeness reasons.
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
This patch removes getEmptyKey, getTombstoneKey, and getHashValue from
DenseMapBase.  These forwarder methods do not really encapsulate
KeyInfoT.  Many of their callers already mention KeyInfoT::isEqual for
example.

An existing static_assert is moved to another method.  Note that it
must live in a method for type completeness reasons.
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
This patch removes getEmptyKey, getTombstoneKey, and getHashValue from
DenseMapBase.  These forwarder methods do not really encapsulate
KeyInfoT.  Many of their callers already mention KeyInfoT::isEqual for
example.

An existing static_assert is moved to another method.  Note that it
must live in a method for type completeness reasons.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants