blob: fad61d3e39a4fe696204456fdad98bc21569430c [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tyler Veness <calcmogul@gmail.com>
Date: Tue, 11 Jul 2023 22:56:09 -0700
Subject: [PATCH 29/31] Use C++20 <bit> header
---
llvm/include/llvm/ADT/DenseMap.h | 3 +-
llvm/include/llvm/ADT/Hashing.h | 35 +--
llvm/include/llvm/ADT/bit.h | 287 -------------------------
llvm/include/llvm/Support/MathExtras.h | 21 +-
4 files changed, 31 insertions(+), 315 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 <algorithm>
+#include <bit>
#include <cassert>
#include <cstddef>
#include <cstring>
@@ -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 781bdb7416392e3f60a1ac3a38fbcf5324b5395f..28934add722f518ae1e9cb9c4a23d2212a47cbdf 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 <algorithm>
+#include <bit>
#include <cassert>
#include <cstring>
#include <optional>
@@ -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<uint64_t>(a - b, 43) +
- llvm::rotr<uint64_t>(c ^ seed, 30) + d,
- a + llvm::rotr<uint64_t>(b ^ k3, 20) - c + len + seed);
+ return hash_16_bytes(std::rotr<uint64_t>(a - b, 43) +
+ std::rotr<uint64_t>(c ^ seed, 30) + d,
+ a + std::rotr<uint64_t>(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<uint64_t>(a + z, 52);
- uint64_t c = llvm::rotr<uint64_t>(a, 37);
+ uint64_t b = std::rotr<uint64_t>(a + z, 52);
+ uint64_t c = std::rotr<uint64_t>(a, 37);
a += fetch64(s + 8);
- c += llvm::rotr<uint64_t>(a, 7);
+ c += std::rotr<uint64_t>(a, 7);
a += fetch64(s + 16);
uint64_t vf = a + z;
- uint64_t vs = b + llvm::rotr<uint64_t>(a, 31) + c;
+ uint64_t vs = b + std::rotr<uint64_t>(a, 31) + c;
a = fetch64(s + 16) + fetch64(s + len - 32);
z = fetch64(s + len - 8);
- b = llvm::rotr<uint64_t>(a + z, 52);
- c = llvm::rotr<uint64_t>(a, 37);
+ b = std::rotr<uint64_t>(a + z, 52);
+ c = std::rotr<uint64_t>(a, 37);
a += fetch64(s + len - 24);
- c += llvm::rotr<uint64_t>(a, 7);
+ c += std::rotr<uint64_t>(a, 7);
a += fetch64(s + len - 16);
uint64_t wf = a + z;
- uint64_t ws = b + llvm::rotr<uint64_t>(a, 31) + c;
+ uint64_t ws = b + std::rotr<uint64_t>(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<uint64_t>(seed ^ k1, 49),
+ std::rotr<uint64_t>(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<uint64_t>(b + a + c, 21);
+ b = std::rotr<uint64_t>(b + a + c, 21);
uint64_t d = a;
a += fetch64(s + 8) + fetch64(s + 16);
- b += llvm::rotr<uint64_t>(a, 44) + d;
+ b += std::rotr<uint64_t>(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<uint64_t>(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
- h1 = llvm::rotr<uint64_t>(h1 + h4 + fetch64(s + 48), 42) * k1;
+ h0 = std::rotr<uint64_t>(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
+ h1 = std::rotr<uint64_t>(h1 + h4 + fetch64(s + 48), 42) * k1;
h0 ^= h6;
h1 += h3 + fetch64(s + 40);
- h2 = llvm::rotr<uint64_t>(h2 + h5, 33) * k1;
+ h2 = std::rotr<uint64_t>(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 2840c5f608d3ea896e1867dd4710685da9572f2d..0a4a3634820efbc0a8ca675e3ad7c98469260d0b 100644
--- a/llvm/include/llvm/ADT/bit.h
+++ b/llvm/include/llvm/ADT/bit.h
@@ -27,18 +27,6 @@
#include <cstdlib> // 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 <intrin.h>
-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,281 +94,6 @@ template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
}
}
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
-[[nodiscard]] constexpr inline bool has_single_bit(T Value) noexcept {
- return (Value != 0) && ((Value & (Value - 1)) == 0);
-}
-
-namespace detail {
-template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
- static unsigned count(T Val) {
- if (!Val)
- return std::numeric_limits<T>::digits;
- if (Val & 0x1)
- return 0;
-
- // Bisection method.
- unsigned ZeroBits = 0;
- T Shift = std::numeric_limits<T>::digits >> 1;
- T Mask = std::numeric_limits<T>::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 <typename T> struct TrailingZerosCounter<T, 4> {
- 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 <typename T> struct TrailingZerosCounter<T, 8> {
- 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<T>::digits on an input of 0.
-template <typename T> [[nodiscard]] int countr_zero(T Val) {
- static_assert(std::is_unsigned_v<T>,
- "Only unsigned integral types are allowed.");
- return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val);
-}
-
-namespace detail {
-template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
- static unsigned count(T Val) {
- if (!Val)
- return std::numeric_limits<T>::digits;
-
- // Bisection method.
- unsigned ZeroBits = 0;
- for (T Shift = std::numeric_limits<T>::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 <typename T> struct LeadingZerosCounter<T, 4> {
- 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 <typename T> struct LeadingZerosCounter<T, 8> {
- 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<T>::digits on an input of 0.
-template <typename T> [[nodiscard]] int countl_zero(T Val) {
- static_assert(std::is_unsigned_v<T>,
- "Only unsigned integral types are allowed.");
- return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::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<T>::digits on an input of all ones.
-template <typename T> [[nodiscard]] int countl_one(T Value) {
- static_assert(std::is_unsigned_v<T>,
- "Only unsigned integral types are allowed.");
- return llvm::countl_zero<T>(~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<T>::digits on an input of all ones.
-template <typename T> [[nodiscard]] int countr_one(T Value) {
- static_assert(std::is_unsigned_v<T>,
- "Only unsigned integral types are allowed.");
- return llvm::countr_zero<T>(~Value);
-}
-
-/// Returns the number of bits needed to represent Value if Value is nonzero.
-/// Returns 0 otherwise.
-///
-/// Ex. bit_width(5) == 3.
-template <typename T> [[nodiscard]] int bit_width(T Value) {
- static_assert(std::is_unsigned_v<T>,
- "Only unsigned integral types are allowed.");
- return std::numeric_limits<T>::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 <typename T> [[nodiscard]] T bit_floor(T Value) {
- static_assert(std::is_unsigned_v<T>,
- "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 <typename T> [[nodiscard]] T bit_ceil(T Value) {
- static_assert(std::is_unsigned_v<T>,
- "Only unsigned integral types are allowed.");
- if (Value < 2)
- return 1;
- return T(1) << llvm::bit_width<T>(Value - 1u);
-}
-
-namespace detail {
-template <typename T, std::size_t SizeOfT> 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 <typename T> struct PopulationCounter<T, 8> {
- 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 <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
-[[nodiscard]] inline int popcount(T Value) noexcept {
- return detail::PopulationCounter<T, sizeof(T)>::count(Value);
-}
-
-// Forward-declare rotr so that rotl can use it.
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
-[[nodiscard]] constexpr T rotr(T V, int R);
-
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
-[[nodiscard]] constexpr T rotl(T V, int R) {
- unsigned N = std::numeric_limits<T>::digits;
-
- R = R % N;
- if (!R)
- return V;
-
- if (R < 0)
- return llvm::rotr(V, -R);
-
- return (V << R) | (V >> (N - R));
-}
-
-template <typename T, typename> [[nodiscard]] constexpr T rotr(T V, int R) {
- unsigned N = std::numeric_limits<T>::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 b82d9883c41008dcbbd933709c6e854ad74c5b58..5f034b694989d8ef24e0b249abd12a5c20146b97 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 <bit>
#include <cassert>
#include <climits>
#include <cstdint>
@@ -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<unsigned>(31 - llvm::countl_zero(Value));
+ return static_cast<unsigned>(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<unsigned>(63 - llvm::countl_zero(Value));
+ return static_cast<unsigned>(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<unsigned>(32 - llvm::countl_zero(Value - 1));
+ return static_cast<unsigned>(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<unsigned>(64 - llvm::countl_zero(Value - 1));
+ return static_cast<unsigned>(64 - std::countl_zero(Value - 1));
}
/// A and B are either alignments or offsets. Return the minimum alignment that