[dawn] Use `std::countl_zero()` in C++20
This patch always uses the function `std::countl_zero()` (counting
the number of consecutive zeros starting from the most significant
bit) instead of the equivalent ones that are platform-dependent
(e.g. `_BitScanForward()` on Windows, `__builtin_clz()` in GCC).
This patch also removes `dawn::ScanReverse()` as it is no longer
used right now.
Bug: 343500108
Change-Id: Ia96b81d9d9d495f17f87bb08c36e27f9ad0f3a39
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/240674
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/common/Math.cpp b/src/dawn/common/Math.cpp
index 0b24a26..f9d86b7 100644
--- a/src/dawn/common/Math.cpp
+++ b/src/dawn/common/Math.cpp
@@ -28,6 +28,7 @@
#include "dawn/common/Math.h"
#include <algorithm>
+#include <bit>
#include <cmath>
#include <limits>
@@ -37,39 +38,12 @@
uint32_t Log2(uint32_t value) {
DAWN_ASSERT(value != 0);
-#if DAWN_COMPILER_IS(MSVC)
- // NOLINTNEXTLINE(runtime/int)
- unsigned long firstBitIndex = 0ul;
- unsigned char ret = _BitScanReverse(&firstBitIndex, value);
- DAWN_ASSERT(ret != 0);
- return firstBitIndex;
-#else
- return 31 - static_cast<uint32_t>(__builtin_clz(value));
-#endif
+ return 31 - std::countl_zero(value);
}
uint32_t Log2(uint64_t value) {
DAWN_ASSERT(value != 0);
-#if DAWN_COMPILER_IS(MSVC)
-#if DAWN_PLATFORM_IS(64_BIT)
- // NOLINTNEXTLINE(runtime/int)
- unsigned long firstBitIndex = 0ul;
- unsigned char ret = _BitScanReverse64(&firstBitIndex, value);
- DAWN_ASSERT(ret != 0);
- return firstBitIndex;
-#else // DAWN_PLATFORM_IS(64_BIT)
- // NOLINTNEXTLINE(runtime/int)
- unsigned long firstBitIndex = 0ul;
- if (_BitScanReverse(&firstBitIndex, value >> 32)) {
- return firstBitIndex + 32;
- }
- unsigned char ret = _BitScanReverse(&firstBitIndex, value & 0xFFFFFFFF);
- DAWN_ASSERT(ret != 0);
- return firstBitIndex;
-#endif // DAWN_PLATFORM_IS(64_BIT)
-#else // DAWN_COMPILER_IS(MSVC)
- return 63 - static_cast<uint32_t>(__builtin_clzll(value));
-#endif // DAWN_COMPILER_IS(MSVC)
+ return 63 - std::countl_zero(value);
}
uint64_t NextPowerOfTwo(uint64_t n) {
diff --git a/src/dawn/common/Math.h b/src/dawn/common/Math.h
index 6a055d8..8766e7e 100644
--- a/src/dawn/common/Math.h
+++ b/src/dawn/common/Math.h
@@ -168,68 +168,6 @@
return Max(first, Max(rest...));
}
-// The following functions are defined in the header so they may be inlined.
-#if DAWN_COMPILER_IS(MSVC)
-// Return the index of the most significant bit set. Indexing is such that bit 0 is the least
-// significant bit.
-inline uint32_t ScanReverse(uint32_t bits) {
- DAWN_ASSERT(bits != 0u);
- // NOLINTNEXTLINE(runtime/int)
- unsigned long lastBitIndex = 0ul;
- uint8_t ret = _BitScanReverse(&lastBitIndex, bits);
- DAWN_ASSERT(ret != 0u);
- return lastBitIndex;
-}
-
-inline uint32_t ScanReverse(uint64_t bits) {
- DAWN_ASSERT(bits != 0u);
- // NOLINTNEXTLINE(runtime/int)
- unsigned long lastBitIndex = 0ul;
-#if DAWN_PLATFORM_IS(64_BIT)
- uint8_t ret = _BitScanReverse64(&lastBitIndex, bits);
-#else
- uint8_t ret;
- if (static_cast<uint32_t>(bits >> 32) == 0) {
- ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits));
- } else {
- ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits >> 32));
- lastBitIndex += 32ul;
- }
-#endif // DAWN_PLATFORM_IS(64_BIT)
- DAWN_ASSERT(ret != 0u);
- return lastBitIndex;
-}
-#else // DAWN_COMPILER_IS(MSVC)
-
-inline uint32_t ScanReverse(uint32_t bits) {
- DAWN_ASSERT(bits != 0u);
- return static_cast<uint32_t>((sizeof(uint32_t) * CHAR_BIT) - 1 - __builtin_clz(bits));
-}
-
-inline uint32_t ScanReverse(uint64_t bits) {
- DAWN_ASSERT(bits != 0u);
-#if DAWN_PLATFORM_IS(64_BIT)
- return static_cast<uint32_t>((sizeof(uint64_t) * CHAR_BIT) - 1 - __builtin_clzll(bits));
-#else
- if (static_cast<uint32_t>(bits >> 32) == 0) {
- return (sizeof(uint32_t) * CHAR_BIT) - 1 - __builtin_clz(static_cast<uint32_t>(bits));
- } else {
- return (sizeof(uint32_t) * CHAR_BIT) - 1 -
- __builtin_clz(static_cast<uint32_t>(bits >> 32)) + 32;
- }
-#endif // DAWN_PLATFORM_IS(64_BIT)
-}
-
-#endif // !DAWN_COMPILER_IS(MSVC)
-
-inline uint32_t ScanReverse(uint8_t bits) {
- return ScanReverse(static_cast<uint32_t>(bits));
-}
-
-inline uint32_t ScanReverse(uint16_t bits) {
- return ScanReverse(static_cast<uint32_t>(bits));
-}
-
} // namespace dawn
#endif // SRC_DAWN_COMMON_MATH_H_
diff --git a/src/dawn/common/ityp_bitset.h b/src/dawn/common/ityp_bitset.h
index 190cc38..5371bc6 100644
--- a/src/dawn/common/ityp_bitset.h
+++ b/src/dawn/common/ityp_bitset.h
@@ -259,47 +259,16 @@
template <typename Index, size_t N>
Index GetHighestBitIndexPlusOne(const ityp::bitset<Index, N>& bitset) {
using I = UnderlyingType<Index>;
-#if DAWN_COMPILER_IS(MSVC)
- if constexpr (N > 32) {
-#if DAWN_PLATFORM_IS(64_BIT)
- // NOLINTNEXTLINE(runtime/int)
- unsigned long firstBitIndex = 0ul;
- unsigned char ret = _BitScanReverse64(&firstBitIndex, bitset.to_ullong());
- if (ret == 0) {
- return Index(static_cast<I>(0));
- }
- return Index(static_cast<I>(firstBitIndex + 1));
-#else // DAWN_PLATFORM_IS(64_BIT)
- if (bitset.none()) {
- return Index(static_cast<I>(0));
- }
- for (size_t i = 0u; i < N; i++) {
- if (bitset.test(Index(static_cast<I>(N - 1 - i)))) {
- return Index(static_cast<I>(N - i));
- }
- }
- DAWN_UNREACHABLE();
-#endif // DAWN_PLATFORM_IS(64_BIT)
- } else {
- // NOLINTNEXTLINE(runtime/int)
- unsigned long firstBitIndex = 0ul;
- unsigned char ret = _BitScanReverse(&firstBitIndex, bitset.to_ulong());
- if (ret == 0) {
- return Index(static_cast<I>(0));
- }
- return Index(static_cast<I>(firstBitIndex + 1));
- }
-#else // DAWN_COMPILER_IS(MSVC)
if (bitset.none()) {
return Index(static_cast<I>(0));
}
if constexpr (N > 32) {
return Index(
- static_cast<I>(64 - static_cast<uint32_t>(__builtin_clzll(bitset.to_ullong()))));
+ static_cast<I>(64 - std::countl_zero(static_cast<uint64_t>(bitset.to_ullong()))));
} else {
- return Index(static_cast<I>(32 - static_cast<uint32_t>(__builtin_clz(bitset.to_ulong()))));
+ return Index(
+ static_cast<I>(32 - std::countl_zero(static_cast<uint32_t>(bitset.to_ulong()))));
}
-#endif // DAWN_COMPILER_IS(MSVC)
}
} // namespace dawn
diff --git a/src/dawn/tests/unittests/MathTests.cpp b/src/dawn/tests/unittests/MathTests.cpp
index 12a3dca..79c3a7d 100644
--- a/src/dawn/tests/unittests/MathTests.cpp
+++ b/src/dawn/tests/unittests/MathTests.cpp
@@ -53,49 +53,6 @@
namespace dawn {
namespace {
-// Tests for ScanReverse
-TEST(Math, ScanReverse) {
- // 8-bit
- // Test extrema
- ASSERT_EQ(ScanReverse(uint8_t(1)), 0u);
- ASSERT_EQ(ScanReverse(uint8_t(0x80)), 7u);
-
- // Test with more than one bit set.
- ASSERT_EQ(ScanReverse(uint8_t(64)), 6u);
- ASSERT_EQ(ScanReverse(uint8_t(64 + 32)), 6u);
- ASSERT_EQ(ScanReverse(uint8_t(128 + 64 + 32)), 7u);
-
- // 16-bit
- // Test extrema
- ASSERT_EQ(ScanReverse(uint16_t(1)), 0u);
- ASSERT_EQ(ScanReverse(uint16_t(0x8000)), 15u);
-
- // Test with more than one bit set.
- ASSERT_EQ(ScanReverse(uint16_t(256)), 8u);
- ASSERT_EQ(ScanReverse(uint16_t(256 + 32)), 8u);
- ASSERT_EQ(ScanReverse(uint16_t(1024u + 256 + 32)), 10u);
-
- // 32-bit
- // Test extrema
- ASSERT_EQ(ScanReverse(1u), 0u);
- ASSERT_EQ(ScanReverse(0x80000000u), 31u);
-
- // Test with more than one bit set.
- ASSERT_EQ(ScanReverse(256u), 8u);
- ASSERT_EQ(ScanReverse(256u + 32u), 8u);
- ASSERT_EQ(ScanReverse(1024u + 256u + 32u), 10u);
-
- // 64-bit
- // Test extrema
- ASSERT_EQ(ScanReverse(uint64_t(1)), 0u);
- ASSERT_EQ(ScanReverse(uint64_t(0x8000000000000000ull)), 63u);
-
- // Test with more than one bit set.
- ASSERT_EQ(ScanReverse(uint64_t(256ull)), 8u);
- ASSERT_EQ(ScanReverse(uint64_t(256ull + 32ull)), 8u);
- ASSERT_EQ(ScanReverse(uint64_t(0x800000000ull + 256ull + 32ull)), 35u);
-}
-
// Tests for Log2
TEST(Math, Log2) {
// Test extrema