mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Semiwrap / meson / robotpy define `NDEBUG` when building their software in all modes, while `allwplib` only does it when building debug. This causes the size of `DenseMap` to differ between the shared libraries built here, and the extension modules built in `mostrobotpy`, causing segfaults when you try to execute code that uses `DenseMap`. This is not a problem with the robotpy code in `allwpilib`, because bazel uses the exact same compiler flags when building the shared libraries and pybind11 extensions.
444 lines
14 KiB
Diff
444 lines
14 KiB
Diff
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 27/35] Use C++20 <bit> header
|
|
|
|
---
|
|
llvm/include/llvm/ADT/DenseMap.h | 3 +-
|
|
llvm/include/llvm/ADT/bit.h | 313 -------------------------
|
|
llvm/include/llvm/Support/MathExtras.h | 21 +-
|
|
3 files changed, 13 insertions(+), 324 deletions(-)
|
|
|
|
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
|
|
index 69ce7982d732887642c7f46163b753ee17be9b30..927a9c72ec939d268ae7463f7113f051cc92cf3f 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>
|
|
@@ -906,7 +907,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/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 <cstdlib> // for _byteswap_{ushort,ulong,uint64}
|
|
#endif
|
|
|
|
-#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
|
|
- defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \
|
|
- defined(__OpenBSD__) || defined(__DragonFly__)
|
|
-#include <endian.h>
|
|
-#elif defined(_AIX)
|
|
-#include <sys/machine.h>
|
|
-#elif defined(__sun)
|
|
-/* Solaris provides _BIG_ENDIAN/_LITTLE_ENDIAN selector in sys/types.h */
|
|
-#include <sys/types.h>
|
|
-#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 <machine/endian.h>
|
|
-#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 <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 {
|
|
|
|
enum class endianness {
|
|
@@ -142,281 +104,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 acd16bb0e6cf73f565d44d654c34057d9b97dd95..5191831247ff668f22b6015d5b135fd9701afdd2 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>
|
|
@@ -262,12 +263,12 @@ constexpr 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 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 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
|
|
@@ -279,8 +280,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;
|
|
}
|
|
|
|
@@ -292,8 +293,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;
|
|
}
|
|
|
|
@@ -311,26 +312,26 @@ template <> constexpr 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
|