ADT: Add constructor from uint64_t array for Bitset#162703
Conversation
|
@llvm/pr-subscribers-llvm-adt Author: Matt Arsenault (arsenm) ChangesAvoids exposing the implementation detail of uintptr_t to This is a replacement of b738f63 Full diff: https://github.com/llvm/llvm-project/pull/162703.diff 3 Files Affected:
diff --git a/llvm/include/llvm/ADT/Bitset.h b/llvm/include/llvm/ADT/Bitset.h
index b1e539e39aff7..b64648f9bccc4 100644
--- a/llvm/include/llvm/ADT/Bitset.h
+++ b/llvm/include/llvm/ADT/Bitset.h
@@ -45,7 +45,18 @@ class Bitset {
StorageType Bits{};
protected:
- constexpr Bitset(const StorageType &B) : Bits{B} {}
+ constexpr Bitset(const std::array<uint64_t, (NumBits + 63) / 64> &B) {
+ if (sizeof(BitWord) == sizeof(uint64_t)) {
+ for (size_t I = 0; I != B.size(); ++I)
+ Bits[I] = B[I];
+ } else {
+ for (size_t I = 0; I != B.size(); ++I) {
+ uint64_t Elt = B[I];
+ Bits[2 * I] = static_cast<uint32_t>(Elt);
+ Bits[2 * I + 1] = static_cast<uint32_t>(Elt >> 32);
+ }
+ }
+ }
public:
constexpr Bitset() = default;
diff --git a/llvm/unittests/ADT/BitsetTest.cpp b/llvm/unittests/ADT/BitsetTest.cpp
new file mode 100644
index 0000000000000..8877397b30c53
--- /dev/null
+++ b/llvm/unittests/ADT/BitsetTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/Support/BitsetTest.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Bitset.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+template <unsigned NumBits>
+class TestBitsetUInt64Array : public Bitset<NumBits> {
+ static constexpr unsigned NumElts = (NumBits + 63) / 64;
+
+public:
+ TestBitsetUInt64Array(const std::array<uint64_t, NumElts> &B)
+ : Bitset<NumBits>(B) {}
+
+ bool verifyValue(const std::array<uint64_t, NumElts> &B) const {
+ for (unsigned I = 0; I != NumBits; ++I) {
+ bool ReferenceVal =
+ (B[(I / 64)] & (static_cast<uint64_t>(1) << (I % 64))) != 0;
+ if (ReferenceVal != this->test(I))
+ return false;
+ }
+
+ return true;
+ }
+};
+
+TEST(BitsetTest, Construction) {
+ std::array<uint64_t, 2> TestVals = {0x123456789abcdef3, 0x1337d3a0b22c24};
+ TestBitsetUInt64Array<96> Test(TestVals);
+ EXPECT_TRUE(Test.verifyValue(TestVals));
+
+ TestBitsetUInt64Array<65> Test1(TestVals);
+ EXPECT_TRUE(Test1.verifyValue(TestVals));
+}
+} // namespace
diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt
index dafd73518aedb..848ccba696e76 100644
--- a/llvm/unittests/ADT/CMakeLists.txt
+++ b/llvm/unittests/ADT/CMakeLists.txt
@@ -12,6 +12,7 @@ add_llvm_unittest(ADTTests
BitFieldsTest.cpp
BitmaskEnumTest.cpp
BitTest.cpp
+ BitsetTest.cpp
BitVectorTest.cpp
BreadthFirstIteratorTest.cpp
BumpPtrListTest.cpp
|
Avoids exposing the implementation detail of uintptr_t to the constructor. This is a replacement of b738f63 which avoids needing tablegen to know the underlying storage type.
| Bits[I] = B[I]; | ||
| } else { | ||
| for (size_t I = 0; I != B.size(); ++I) { | ||
| uint64_t Elt = B[I]; |
There was a problem hiding this comment.
Should we static assert that sizeof(BitWord) == sizeof(uint32_t);?
There was a problem hiding this comment.
It's already static_asserted above, I guess I could move the assertion down
e89ba3c to
af2ebac
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/116/builds/19521 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/76/builds/13133 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/39/builds/8202 Here is the relevant piece of the build log for the reference |
…162814) When the underlying storage element is 32-bit, we may only need half of the last value in the uint64_t array. I've adjusted the constructor to account for that. For example, if you construct a 65 bit bitset you will need both 32-bit halves of the first array value but only the bottom half of the second value. The storage will only have 3 elements, so attempting to assign the top 32-bits into the storage will fail. This happened on our buildbot: https://lab.llvm.org/buildbot/#/builders/154/builds/22555 (though the traceback is not useful) Then added tests for < 32 bit sizes, and assertions for the number of elements we decide to use. Given that the only member of BitSet is a std::array, I think the size will be consistent across systems. Tested on 32 and 64-bit Arm machines. Follow up to #162703.
Avoids exposing the implementation detail of uintptr_t to the constructor. This is a replacement of b738f63 which avoids needing tablegen to know the underlying storage type.
…lvm#162814) When the underlying storage element is 32-bit, we may only need half of the last value in the uint64_t array. I've adjusted the constructor to account for that. For example, if you construct a 65 bit bitset you will need both 32-bit halves of the first array value but only the bottom half of the second value. The storage will only have 3 elements, so attempting to assign the top 32-bits into the storage will fail. This happened on our buildbot: https://lab.llvm.org/buildbot/#/builders/154/builds/22555 (though the traceback is not useful) Then added tests for < 32 bit sizes, and assertions for the number of elements we decide to use. Given that the only member of BitSet is a std::array, I think the size will be consistent across systems. Tested on 32 and 64-bit Arm machines. Follow up to llvm#162703.

Avoids exposing the implementation detail of uintptr_t to
the constructor.
This is a replacement of b738f63
which avoids needing tablegen to know the underlying storage type.