From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 11 Jul 2023 22:56:09 -0700 Subject: [PATCH 28/36] Use C++20 header --- llvm/include/llvm/ADT/DenseMap.h | 3 +- llvm/include/llvm/ADT/Hashing.h | 35 +-- llvm/include/llvm/ADT/bit.h | 313 ------------------------- llvm/include/llvm/Support/MathExtras.h | 21 +- 4 files changed, 31 insertions(+), 341 deletions(-) diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h index e9bd3bfa4a6fe0fa26ff20069bbadc816c8baa65..93b50c9e53af4ea3af5fd0329a8a03bdce659e9d 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h @@ -23,6 +23,7 @@ #include "llvm/Support/ReverseIteration.h" #include "llvm/Support/type_traits.h" #include +#include #include #include #include @@ -933,7 +934,7 @@ class SmallDenseMap public: explicit SmallDenseMap(unsigned NumInitBuckets = 0) { if (NumInitBuckets > InlineBuckets) - NumInitBuckets = llvm::bit_ceil(NumInitBuckets); + NumInitBuckets = std::bit_ceil(NumInitBuckets); init(NumInitBuckets); } diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h index 08d6edb14eb3cd51405329aae61b9782266a2590..e84d53e6bf2f741be562b9d66bf0bdfe4a79f936 100644 --- a/llvm/include/llvm/ADT/Hashing.h +++ b/llvm/include/llvm/ADT/Hashing.h @@ -49,6 +49,7 @@ #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/type_traits.h" #include +#include #include #include #include @@ -224,30 +225,30 @@ inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) { uint64_t b = fetch64(s + 8); uint64_t c = fetch64(s + len - 8) * k2; uint64_t d = fetch64(s + len - 16) * k0; - return hash_16_bytes(llvm::rotr(a - b, 43) + - llvm::rotr(c ^ seed, 30) + d, - a + llvm::rotr(b ^ k3, 20) - c + len + seed); + return hash_16_bytes(std::rotr(a - b, 43) + + std::rotr(c ^ seed, 30) + d, + a + std::rotr(b ^ k3, 20) - c + len + seed); } inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) { uint64_t z = fetch64(s + 24); uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0; - uint64_t b = llvm::rotr(a + z, 52); - uint64_t c = llvm::rotr(a, 37); + uint64_t b = std::rotr(a + z, 52); + uint64_t c = std::rotr(a, 37); a += fetch64(s + 8); - c += llvm::rotr(a, 7); + c += std::rotr(a, 7); a += fetch64(s + 16); uint64_t vf = a + z; - uint64_t vs = b + llvm::rotr(a, 31) + c; + uint64_t vs = b + std::rotr(a, 31) + c; a = fetch64(s + 16) + fetch64(s + len - 32); z = fetch64(s + len - 8); - b = llvm::rotr(a + z, 52); - c = llvm::rotr(a, 37); + b = std::rotr(a + z, 52); + c = std::rotr(a, 37); a += fetch64(s + len - 24); - c += llvm::rotr(a, 7); + c += std::rotr(a, 7); a += fetch64(s + len - 16); uint64_t wf = a + z; - uint64_t ws = b + llvm::rotr(a, 31) + c; + uint64_t ws = b + std::rotr(a, 31) + c; uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0); return shift_mix((seed ^ (r * k0)) + vs) * k2; } @@ -280,7 +281,7 @@ struct hash_state { hash_state state = {0, seed, hash_16_bytes(seed, k1), - llvm::rotr(seed ^ k1, 49), + std::rotr(seed ^ k1, 49), seed * k1, shift_mix(seed), 0}; @@ -294,10 +295,10 @@ struct hash_state { static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) { a += fetch64(s); uint64_t c = fetch64(s + 24); - b = llvm::rotr(b + a + c, 21); + b = std::rotr(b + a + c, 21); uint64_t d = a; a += fetch64(s + 8) + fetch64(s + 16); - b += llvm::rotr(a, 44) + d; + b += std::rotr(a, 44) + d; a += c; } @@ -305,11 +306,11 @@ struct hash_state { /// We mix all 64 bytes even when the chunk length is smaller, but we /// record the actual length. void mix(const char *s) { - h0 = llvm::rotr(h0 + h1 + h3 + fetch64(s + 8), 37) * k1; - h1 = llvm::rotr(h1 + h4 + fetch64(s + 48), 42) * k1; + h0 = std::rotr(h0 + h1 + h3 + fetch64(s + 8), 37) * k1; + h1 = std::rotr(h1 + h4 + fetch64(s + 48), 42) * k1; h0 ^= h6; h1 += h3 + fetch64(s + 40); - h2 = llvm::rotr(h2 + h5, 33) * k1; + h2 = std::rotr(h2 + h5, 33) * k1; h3 = h4 * k1; h4 = h0 + h5; mix_32_bytes(s, h3, h4); diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade593b522a08 100644 --- a/llvm/include/llvm/ADT/bit.h +++ b/llvm/include/llvm/ADT/bit.h @@ -27,44 +27,6 @@ #include // for _byteswap_{ushort,ulong,uint64} #endif -#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ - defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \ - defined(__OpenBSD__) || defined(__DragonFly__) -#include -#elif defined(_AIX) -#include -#elif defined(__sun) -/* Solaris provides _BIG_ENDIAN/_LITTLE_ENDIAN selector in sys/types.h */ -#include -#define BIG_ENDIAN 4321 -#define LITTLE_ENDIAN 1234 -#if defined(_BIG_ENDIAN) -#define BYTE_ORDER BIG_ENDIAN -#else -#define BYTE_ORDER LITTLE_ENDIAN -#endif -#elif defined(__MVS__) -#define BIG_ENDIAN 4321 -#define LITTLE_ENDIAN 1234 -#define BYTE_ORDER BIG_ENDIAN -#else -#if !defined(BYTE_ORDER) && !defined(_WIN32) -#include -#endif -#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 { enum class endianness { @@ -142,281 +104,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 1 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); -} - -// Forward-declare rotr so that rotl can use it. -template >> -[[nodiscard]] constexpr T rotr(T V, int R); - -template >> -[[nodiscard]] constexpr T rotl(T V, int R) { - unsigned N = std::numeric_limits::digits; - - R = R % N; - if (!R) - return V; - - if (R < 0) - return llvm::rotr(V, -R); - - return (V << R) | (V >> (N - R)); -} - -template [[nodiscard]] constexpr T rotr(T V, int R) { - unsigned N = std::numeric_limits::digits; - - R = R % N; - if (!R) - return V; - - if (R < 0) - return llvm::rotl(V, -R); - - return (V >> R) | (V << (N - R)); -} - } // namespace llvm #endif diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index daa79d99578e934ca001d1de5d2772ff961b8fc3..f66e64b601d01f17dc6c7a4e568cc4eb1d9bb985 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 @@ -235,12 +236,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); } /// Return true if the argument contains a non-empty sequence of ones with the @@ -252,8 +253,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; } @@ -265,8 +266,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; } @@ -284,26 +285,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)); } /// A and B are either alignments or offsets. Return the minimum alignment that