[useful] Drop bespoke BitCount implementation (#37083)

use `absl::popcount` instead

Built on #37082 which should be merged first

Closes #37083

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/37083 from ctiller:less-bespoke-2 317a4545f0
PiperOrigin-RevId: 652870573
pull/37229/head
Craig Tiller 5 months ago committed by Copybara-Service
parent 853f32ec0c
commit 1204e7983b
  1. 2
      src/core/lib/gprpp/bitset.h
  2. 51
      src/core/util/useful.h
  3. 7
      test/core/util/useful_test.cc

@ -138,7 +138,7 @@ class BitSet {
uint32_t count() const {
uint32_t count = 0;
for (size_t i = 0; i < kUnits; i++) {
count += BitCount(units_[i]);
count += absl::popcount(units_[i]);
}
return count;
}

@ -57,53 +57,6 @@ bool GetBit(T i, size_t n) {
return (i & (T(1) << n)) != 0;
}
namespace useful_detail {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t HexdigitBitcount(
uint32_t x) {
return (x - ((x >> 1) & 0x77777777) - ((x >> 2) & 0x33333333) -
((x >> 3) & 0x11111111));
}
} // namespace useful_detail
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint32_t i) {
return (((useful_detail::HexdigitBitcount(i) +
(useful_detail::HexdigitBitcount(i) >> 4)) &
0x0f0f0f0f) %
255);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint64_t i) {
return BitCount(static_cast<uint32_t>(i)) +
BitCount(static_cast<uint32_t>(i >> 32));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint16_t i) {
return BitCount(static_cast<uint32_t>(i));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint8_t i) {
return BitCount(static_cast<uint32_t>(i));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int64_t i) {
return BitCount(static_cast<uint64_t>(i));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int32_t i) {
return BitCount(static_cast<uint32_t>(i));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int16_t i) {
return BitCount(static_cast<uint16_t>(i));
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int8_t i) {
return BitCount(static_cast<uint8_t>(i));
}
#if GRPC_HAS_BUILTIN(__builtin_ctz)
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint32_t i) {
@ -119,12 +72,12 @@ GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint32_t i) {
DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
return BitCount((i & -i) - 1);
return absl::popcount((i & -i) - 1);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint64_t i) {
DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
return BitCount((i & -i) - 1);
return absl::popcount((i & -i) - 1);
}
#endif

@ -48,18 +48,11 @@ TEST(UsefulTest, ArraySize) {
TEST(UsefulTest, BitOps) {
uint32_t bitset = 0;
EXPECT_EQ(BitCount((1u << 31) - 1), 31);
EXPECT_EQ(BitCount(1u << 3), 1);
EXPECT_EQ(BitCount(0), 0);
EXPECT_EQ(SetBit(&bitset, 3), 8);
EXPECT_EQ(BitCount(bitset), 1);
EXPECT_EQ(GetBit(bitset, 3), 1);
EXPECT_EQ(SetBit(&bitset, 1), 10);
EXPECT_EQ(BitCount(bitset), 2);
EXPECT_EQ(ClearBit(&bitset, 3), 2);
EXPECT_EQ(BitCount(bitset), 1);
EXPECT_EQ(GetBit(bitset, 3), 0);
EXPECT_EQ(BitCount(std::numeric_limits<uint64_t>::max()), 64);
}
TEST(UsefulTest, SaturatingAdd) {

Loading…
Cancel
Save