[PATCH] D77038: Fix bug in BitVector and SmallBitVector DenseMap hashing

Brad Moody via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 19:03:35 PDT 2020


bmoody updated this revision to Diff 257585.
bmoody retitled this revision from "Fix bug in BitVector DenseMap hashing" to "Fix bug in BitVector and SmallBitVector DenseMap hashing".
bmoody edited the summary of this revision.
bmoody added a reviewer: aganea.
bmoody added a comment.

Include fix for SmallBitVector hashing


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77038/new/

https://reviews.llvm.org/D77038

Files:
  llvm/include/llvm/ADT/BitVector.h
  llvm/include/llvm/ADT/SmallBitVector.h
  llvm/unittests/ADT/BitVectorTest.cpp


Index: llvm/unittests/ADT/BitVectorTest.cpp
===================================================================
--- llvm/unittests/ADT/BitVectorTest.cpp
+++ llvm/unittests/ADT/BitVectorTest.cpp
@@ -1229,4 +1229,34 @@
   EXPECT_EQ(true, Set.erase(A));
   EXPECT_EQ(0U, Set.size());
 }
+
+/// Test that capacity doesn't affect hashing.
+TYPED_TEST(BitVectorTest, DenseMapHashing) {
+  using DMI = DenseMapInfo<TypeParam>;
+  {
+    TypeParam A;
+    A.resize(200);
+    A.set(100);
+
+    TypeParam B;
+    B.resize(200);
+    B.set(100);
+    B.reserve(1000);
+
+    EXPECT_EQ(DMI::getHashValue(A), DMI::getHashValue(B));
+  }
+  {
+    TypeParam A;
+    A.resize(20);
+    A.set(10);
+
+    TypeParam B;
+    B.resize(20);
+    B.set(10);
+    B.reserve(1000);
+
+    EXPECT_EQ(DMI::getHashValue(A), DMI::getHashValue(B));
+  }
+}
+
 } // namespace
Index: llvm/include/llvm/ADT/SmallBitVector.h
===================================================================
--- llvm/include/llvm/ADT/SmallBitVector.h
+++ llvm/include/llvm/ADT/SmallBitVector.h
@@ -668,8 +668,18 @@
   }
   bool isInvalid() const { return X == (uintptr_t)-1; }
 
-  ArrayRef<uintptr_t> getData() const {
-    return isSmall() ? makeArrayRef(X) : getPointer()->getData();
+  unsigned getDenseMapHashValue() const {
+    using HashType = std::pair<size_type, ArrayRef<uintptr_t>>;
+    HashType H;
+    H.first = size();
+    uintptr_t Word;
+    if (isSmall()) {
+      Word = getSmallBits();
+      H.second = ArrayRef<uintptr_t>(Word);
+    } else {
+      H.second = getPointer()->getData();
+    }
+    return DenseMapInfo<HashType>::getHashValue(H);
   }
 
 private:
@@ -717,8 +727,7 @@
     return V;
   }
   static unsigned getHashValue(const SmallBitVector &V) {
-    return DenseMapInfo<std::pair<unsigned, ArrayRef<uintptr_t>>>::getHashValue(
-        std::make_pair(V.size(), V.getData()));
+    return V.getDenseMapHashValue();
   }
   static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS) {
     if (LHS.isInvalid() || RHS.isInvalid())
Index: llvm/include/llvm/ADT/BitVector.h
===================================================================
--- llvm/include/llvm/ADT/BitVector.h
+++ llvm/include/llvm/ADT/BitVector.h
@@ -759,7 +759,9 @@
   }
   bool isInvalid() const { return Size == (unsigned)-1; }
 
-  ArrayRef<BitWord> getData() const { return Bits; }
+  ArrayRef<BitWord> getData() const {
+    return Bits.take_front(NumBitWords(size()));
+  }
 
   //===--------------------------------------------------------------------===//
   // Portable bit mask operations.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77038.257585.patch
Type: text/x-patch
Size: 2578 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200415/722ee403/attachment.bin>


More information about the llvm-commits mailing list