From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 11 Jul 2023 22:56:09 -0700 Subject: [PATCH 30/30] Use C++20 header --- llvm/include/llvm/ADT/bit.h | 256 ------------------------- llvm/include/llvm/Support/MathExtras.h | 37 ++-- 2 files changed, 19 insertions(+), 274 deletions(-) diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h index d93023d88b4efe962f425d0b8fe98fc25394f1fe..0a4a3634820efbc0a8ca675e3ad7c98469260d0b 100644 --- a/llvm/include/llvm/ADT/bit.h +++ b/llvm/include/llvm/ADT/bit.h @@ -27,18 +27,6 @@ #include // for _byteswap_{ushort,ulong,uint64} #endif -#ifdef _MSC_VER -// Declare these intrinsics manually rather including intrin.h. It's very -// expensive, and bit.h is popular via MathExtras.h. -// #include -extern "C" { -unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); -unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); -unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); -unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); -} -#endif - namespace llvm { // This implementation of bit_cast is different from the C++20 one in two ways: @@ -106,250 +94,6 @@ template >> } } -template >> -[[nodiscard]] constexpr inline bool has_single_bit(T Value) noexcept { - return (Value != 0) && ((Value & (Value - 1)) == 0); -} - -namespace detail { -template struct TrailingZerosCounter { - static unsigned count(T Val) { - if (!Val) - return std::numeric_limits::digits; - if (Val & 0x1) - return 0; - - // Bisection method. - unsigned ZeroBits = 0; - T Shift = std::numeric_limits::digits >> 1; - T Mask = std::numeric_limits::max() >> Shift; - while (Shift) { - if ((Val & Mask) == 0) { - Val >>= Shift; - ZeroBits |= Shift; - } - Shift >>= 1; - Mask >>= Shift; - } - return ZeroBits; - } -}; - -#if defined(__GNUC__) || defined(_MSC_VER) -template struct TrailingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 32; - -#if __has_builtin(__builtin_ctz) || defined(__GNUC__) - return __builtin_ctz(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanForward(&Index, Val); - return Index; -#endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct TrailingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 64; - -#if __has_builtin(__builtin_ctzll) || defined(__GNUC__) - return __builtin_ctzll(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanForward64(&Index, Val); - return Index; -#endif - } -}; -#endif -#endif -} // namespace detail - -/// Count number of 0's from the least significant bit to the most -/// stopping at the first 1. -/// -/// Only unsigned integral types are allowed. -/// -/// Returns std::numeric_limits::digits on an input of 0. -template [[nodiscard]] int countr_zero(T Val) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - return llvm::detail::TrailingZerosCounter::count(Val); -} - -namespace detail { -template struct LeadingZerosCounter { - static unsigned count(T Val) { - if (!Val) - return std::numeric_limits::digits; - - // Bisection method. - unsigned ZeroBits = 0; - for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { - T Tmp = Val >> Shift; - if (Tmp) - Val = Tmp; - else - ZeroBits |= Shift; - } - return ZeroBits; - } -}; - -#if defined(__GNUC__) || defined(_MSC_VER) -template struct LeadingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 32; - -#if __has_builtin(__builtin_clz) || defined(__GNUC__) - return __builtin_clz(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanReverse(&Index, Val); - return Index ^ 31; -#endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct LeadingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 64; - -#if __has_builtin(__builtin_clzll) || defined(__GNUC__) - return __builtin_clzll(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanReverse64(&Index, Val); - return Index ^ 63; -#endif - } -}; -#endif -#endif -} // namespace detail - -/// Count number of 0's from the most significant bit to the least -/// stopping at the first 1. -/// -/// Only unsigned integral types are allowed. -/// -/// Returns std::numeric_limits::digits on an input of 0. -template [[nodiscard]] int countl_zero(T Val) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - return llvm::detail::LeadingZerosCounter::count(Val); -} - -/// Count the number of ones from the most significant bit to the first -/// zero bit. -/// -/// Ex. countl_one(0xFF0FFF00) == 8. -/// Only unsigned integral types are allowed. -/// -/// Returns std::numeric_limits::digits on an input of all ones. -template [[nodiscard]] int countl_one(T Value) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - return llvm::countl_zero(~Value); -} - -/// Count the number of ones from the least significant bit to the first -/// zero bit. -/// -/// Ex. countr_one(0x00FF00FF) == 8. -/// Only unsigned integral types are allowed. -/// -/// Returns std::numeric_limits::digits on an input of all ones. -template [[nodiscard]] int countr_one(T Value) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - return llvm::countr_zero(~Value); -} - -/// Returns the number of bits needed to represent Value if Value is nonzero. -/// Returns 0 otherwise. -/// -/// Ex. bit_width(5) == 3. -template [[nodiscard]] int bit_width(T Value) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - return std::numeric_limits::digits - llvm::countl_zero(Value); -} - -/// Returns the largest integral power of two no greater than Value if Value is -/// nonzero. Returns 0 otherwise. -/// -/// Ex. bit_floor(5) == 4. -template [[nodiscard]] T bit_floor(T Value) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - if (!Value) - return 0; - return T(1) << (llvm::bit_width(Value) - 1); -} - -/// Returns the smallest integral power of two no smaller than Value if Value is -/// nonzero. Returns 0 otherwise. -/// -/// Ex. bit_ceil(5) == 8. -/// -/// The return value is undefined if the input is larger than the largest power -/// of two representable in T. -template [[nodiscard]] T bit_ceil(T Value) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - if (Value < 2) - return 1; - return T(1) << llvm::bit_width(Value - 1u); -} - -namespace detail { -template struct PopulationCounter { - static int count(T Value) { - // Generic version, forward to 32 bits. - static_assert(SizeOfT <= 4, "Not implemented!"); -#if defined(__GNUC__) - return (int)__builtin_popcount(Value); -#else - uint32_t v = Value; - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); -#endif - } -}; - -template struct PopulationCounter { - static int count(T Value) { -#if defined(__GNUC__) - return (int)__builtin_popcountll(Value); -#else - uint64_t v = Value; - v = v - ((v >> 1) & 0x5555555555555555ULL); - v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); - v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; - return int((uint64_t)(v * 0x0101010101010101ULL) >> 56); -#endif - } -}; -} // namespace detail - -/// Count the number of set bits in a value. -/// Ex. popcount(0xF000F000) = 8 -/// Returns 0 if the word is zero. -template >> -[[nodiscard]] inline int popcount(T Value) noexcept { - return detail::PopulationCounter::count(Value); -} - } // namespace llvm #endif diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index fe9c5136f9f2f687577a0b1ecce69262568a9c3c..c269839c309e92d92ff8835127dcd2dfc0dd2c23 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h @@ -15,6 +15,7 @@ #include "llvm/ADT/bit.h" #include "llvm/Support/Compiler.h" +#include #include #include #include @@ -41,7 +42,7 @@ enum ZeroBehavior { template unsigned countTrailingZeros(T Val) { static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return llvm::countr_zero(Val); + return std::countr_zero(Val); } /// Count number of 0's from the most significant bit to the least @@ -53,7 +54,7 @@ template unsigned countTrailingZeros(T Val) { template unsigned countLeadingZeros(T Val) { static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return llvm::countl_zero(Val); + return std::countl_zero(Val); } /// Get the index of the first set bit starting from the least @@ -66,7 +67,7 @@ template T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return (std::numeric_limits::max)(); - return llvm::countr_zero(Val); + return std::countr_zero(Val); } /// Create a bitmask with the N right-most bits set to 1, and all other @@ -108,7 +109,7 @@ template T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { // Use ^ instead of - because both gcc and llvm can remove the associated ^ // in the __builtin_clz intrinsic on x86. - return llvm::countl_zero(Val) ^ (std::numeric_limits::digits - 1); + return std::countl_zero(Val) ^ (std::numeric_limits::digits - 1); } /// Macro compressed bit reversal table for 256 bits. @@ -295,12 +296,12 @@ constexpr inline bool isShiftedMask_64(uint64_t Value) { /// Return true if the argument is a power of two > 0. /// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.) constexpr inline bool isPowerOf2_32(uint32_t Value) { - return llvm::has_single_bit(Value); + return std::has_single_bit(Value); } /// Return true if the argument is a power of two > 0 (64 bit edition.) constexpr inline bool isPowerOf2_64(uint64_t Value) { - return llvm::has_single_bit(Value); + return std::has_single_bit(Value); } /// Count the number of ones from the most significant bit to the first @@ -313,7 +314,7 @@ constexpr inline bool isPowerOf2_64(uint64_t Value) { template unsigned countLeadingOnes(T Value) { static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return llvm::countl_one(Value); + return std::countl_one(Value); } /// Count the number of ones from the least significant bit to the first @@ -326,7 +327,7 @@ template unsigned countLeadingOnes(T Value) { template unsigned countTrailingOnes(T Value) { static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return llvm::countr_one(Value); + return std::countr_one(Value); } /// Count the number of set bits in a value. @@ -336,7 +337,7 @@ template inline unsigned countPopulation(T Value) { static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return (unsigned)llvm::popcount(Value); + return (unsigned)std::popcount(Value); } /// Return true if the argument contains a non-empty sequence of ones with the @@ -348,8 +349,8 @@ inline bool isShiftedMask_32(uint32_t Value, unsigned &MaskIdx, unsigned &MaskLen) { if (!isShiftedMask_32(Value)) return false; - MaskIdx = llvm::countr_zero(Value); - MaskLen = llvm::popcount(Value); + MaskIdx = std::countr_zero(Value); + MaskLen = std::popcount(Value); return true; } @@ -361,8 +362,8 @@ inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, unsigned &MaskLen) { if (!isShiftedMask_64(Value)) return false; - MaskIdx = llvm::countr_zero(Value); - MaskLen = llvm::popcount(Value); + MaskIdx = std::countr_zero(Value); + MaskLen = std::popcount(Value); return true; } @@ -380,26 +381,26 @@ template <> constexpr inline size_t CTLog2<1>() { return 0; } /// (32 bit edition.) /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 inline unsigned Log2_32(uint32_t Value) { - return static_cast(31 - llvm::countl_zero(Value)); + return static_cast(31 - std::countl_zero(Value)); } /// Return the floor log base 2 of the specified value, -1 if the value is zero. /// (64 bit edition.) inline unsigned Log2_64(uint64_t Value) { - return static_cast(63 - llvm::countl_zero(Value)); + return static_cast(63 - std::countl_zero(Value)); } /// Return the ceil log base 2 of the specified value, 32 if the value is zero. /// (32 bit edition). /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 inline unsigned Log2_32_Ceil(uint32_t Value) { - return static_cast(32 - llvm::countl_zero(Value - 1)); + return static_cast(32 - std::countl_zero(Value - 1)); } /// Return the ceil log base 2 of the specified value, 64 if the value is zero. /// (64 bit edition.) inline unsigned Log2_64_Ceil(uint64_t Value) { - return static_cast(64 - llvm::countl_zero(Value - 1)); + return static_cast(64 - std::countl_zero(Value - 1)); } /// This function takes a 64-bit integer and returns the bit equivalent double. @@ -456,7 +457,7 @@ constexpr inline uint64_t NextPowerOf2(uint64_t A) { /// Returns the power of two which is less than or equal to the given value. /// Essentially, it is a floor operation across the domain of powers of two. inline uint64_t PowerOf2Floor(uint64_t A) { - return llvm::bit_floor(A); + return std::bit_floor(A); } /// Returns the power of two which is greater than or equal to the given value.