Index: llvm/include/llvm/Support/MathExtras.h =================================================================== --- llvm/include/llvm/Support/MathExtras.h +++ llvm/include/llvm/Support/MathExtras.h @@ -88,7 +88,7 @@ namespace detail { template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior) { + static constexpr unsigned count(T Val, ZeroBehavior) { if (!Val) return std::numeric_limits::digits; if (Val & 0x1) @@ -112,7 +112,7 @@ #if defined(__GNUC__) || defined(_MSC_VER) template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { + static constexpr unsigned count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; @@ -128,7 +128,7 @@ #if !defined(_MSC_VER) || defined(_M_X64) template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { + static constexpr unsigned count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; @@ -153,7 +153,7 @@ /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. template -unsigned countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { +constexpr unsigned countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); @@ -162,7 +162,7 @@ namespace detail { template struct LeadingZerosCounter { - static unsigned count(T Val, ZeroBehavior) { + static constexpr unsigned count(T Val, ZeroBehavior) { if (!Val) return std::numeric_limits::digits; @@ -181,7 +181,7 @@ #if defined(__GNUC__) || defined(_MSC_VER) template struct LeadingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { + static constexpr unsigned count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; @@ -197,7 +197,7 @@ #if !defined(_MSC_VER) || defined(_M_X64) template struct LeadingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { + static constexpr unsigned count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; @@ -222,7 +222,7 @@ /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. template -unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { +constexpr unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); @@ -236,7 +236,8 @@ /// /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are /// valid arguments. -template T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { +template +constexpr T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return std::numeric_limits::max(); @@ -277,7 +278,7 @@ /// /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are /// valid arguments. -template T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { +template constexpr T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return std::numeric_limits::max(); @@ -294,15 +295,14 @@ #define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64 #define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16) #define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4) - R6(0), R6(2), R6(1), R6(3) + R6(0), R6(2), R6(1), R6(3) #undef R2 #undef R4 #undef R6 }; /// Reverse the bits in \p Val. -template -T reverseBits(T Val) { +template T reverseBits(T Val) { unsigned char in[sizeof(Val)]; unsigned char out[sizeof(Val)]; std::memcpy(in, &Val, sizeof(Val)); @@ -313,29 +313,25 @@ } #if __has_builtin(__builtin_bitreverse8) -template<> -inline uint8_t reverseBits(uint8_t Val) { +template <> inline uint8_t reverseBits(uint8_t Val) { return __builtin_bitreverse8(Val); } #endif #if __has_builtin(__builtin_bitreverse16) -template<> -inline uint16_t reverseBits(uint16_t Val) { +template <> inline uint16_t reverseBits(uint16_t Val) { return __builtin_bitreverse16(Val); } #endif #if __has_builtin(__builtin_bitreverse32) -template<> -inline uint32_t reverseBits(uint32_t Val) { +template <> inline uint32_t reverseBits(uint32_t Val) { return __builtin_bitreverse32(Val); } #endif #if __has_builtin(__builtin_bitreverse64) -template<> -inline uint64_t reverseBits(uint64_t Val) { +template <> inline uint64_t reverseBits(uint64_t Val) { return __builtin_bitreverse64(Val); } #endif @@ -356,12 +352,13 @@ /// Make a 64-bit integer from a high / low pair of 32-bit integers. constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) { - return ((uint64_t)High << 32) | (uint64_t)Low; + return (static_cast(High) << 32) | static_cast(Low); } /// Checks if an integer fits into the given bit width. template constexpr inline bool isInt(int64_t x) { - return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1))); + return N >= 64 || + (-(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1))); } // Template specializations to get better code for common cases. template <> constexpr inline bool isInt<8>(int64_t x) { @@ -452,12 +449,12 @@ } /// Checks if an unsigned integer fits into the given (dynamic) bit width. -inline bool isUIntN(unsigned N, uint64_t x) { +constexpr inline bool isUIntN(unsigned N, uint64_t x) { return N >= 64 || x <= maxUIntN(N); } /// Checks if an signed integer fits into the given (dynamic) bit width. -inline bool isIntN(unsigned N, int64_t x) { +constexpr inline bool isIntN(unsigned N, int64_t x) { return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N)); } @@ -506,7 +503,7 @@ /// \param ZB the behavior on an input of all ones. Only ZB_Width and /// ZB_Undefined are valid arguments. template -unsigned countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { +constexpr unsigned countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); @@ -522,7 +519,7 @@ /// \param ZB the behavior on an input of all ones. Only ZB_Width and /// ZB_Undefined are valid arguments. template -unsigned countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) { +constexpr unsigned countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); @@ -531,7 +528,7 @@ namespace detail { template struct PopulationCounter { - static unsigned count(T Value) { + static constexpr unsigned count(T Value) { // Generic version, forward to 32 bits. static_assert(SizeOfT <= 4, "Not implemented!"); #if defined(__GNUC__) @@ -546,7 +543,7 @@ }; template struct PopulationCounter { - static unsigned count(T Value) { + static constexpr unsigned count(T Value) { #if defined(__GNUC__) return __builtin_popcountll(Value); #else @@ -563,8 +560,7 @@ /// Count the number of set bits in a value. /// Ex. countPopulation(0xF000F000) = 8 /// Returns 0 if the word is zero. -template -inline unsigned countPopulation(T Value) { +template constexpr inline unsigned countPopulation(T Value) { static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); @@ -593,32 +589,31 @@ /// Return the floor log base 2 of the specified value, -1 if the value is zero. /// (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) { +constexpr inline unsigned Log2_32(uint32_t Value) { return 31 - countLeadingZeros(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) { +constexpr inline unsigned Log2_64(uint64_t Value) { return 63 - countLeadingZeros(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) { +constexpr inline unsigned Log2_32_Ceil(uint32_t Value) { return 32 - countLeadingZeros(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) { +constexpr inline unsigned Log2_64_Ceil(uint64_t Value) { return 64 - countLeadingZeros(Value - 1); } /// Return the greatest common divisor of the values using Euclid's algorithm. -template -inline T greatestCommonDivisor(T A, T B) { +template constexpr inline T greatestCommonDivisor(T A, T B) { while (B) { T Tmp = B; B = A % B; @@ -627,7 +622,7 @@ return A; } -inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { +constexpr inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { return greatestCommonDivisor(A, B); } @@ -680,7 +675,7 @@ /// Returns the next power of two (in 64-bits) that is strictly greater than A. /// Returns zero on overflow. -inline uint64_t NextPowerOf2(uint64_t A) { +constexpr inline uint64_t NextPowerOf2(uint64_t A) { A |= (A >> 1); A |= (A >> 2); A |= (A >> 4); @@ -692,14 +687,15 @@ /// 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) { - if (!A) return 0; +constexpr inline uint64_t PowerOf2Floor(uint64_t A) { + if (!A) + return 0; return 1ull << (63 - countLeadingZeros(A, ZB_Undefined)); } /// Returns the power of two which is greater than or equal to the given value. /// Essentially, it is a ceil operation across the domain of powers of two. -inline uint64_t PowerOf2Ceil(uint64_t A) { +constexpr inline uint64_t PowerOf2Ceil(uint64_t A) { if (!A) return 0; return NextPowerOf2(A - 1); @@ -744,7 +740,8 @@ } /// Returns the integer nearest(Numerator / Denominator). -inline uint64_t divideNearest(uint64_t Numerator, uint64_t Denominator) { +constexpr inline uint64_t divideNearest(uint64_t Numerator, + uint64_t Denominator) { return (Numerator + (Denominator / 2)) / Denominator; } @@ -791,7 +788,8 @@ /// Subtract two unsigned integers, X and Y, of type T and return the absolute /// value of the result. template -std::enable_if_t::value, T> AbsoluteDifference(T X, T Y) { +constexpr std::enable_if_t::value, T> +AbsoluteDifference(T X, T Y) { return X > Y ? (X - Y) : (Y - X); } @@ -877,7 +875,6 @@ /// Use this rather than HUGE_VALF; the latter causes warnings on MSVC. extern const float huge_valf; - /// Add two signed integers, computing the two's complement truncated result, /// returning true if overflow occured. template @@ -957,6 +954,6 @@ return UX > (static_cast(std::numeric_limits::max())) / UY; } -} // End llvm namespace +} // namespace llvm #endif Index: llvm/lib/Support/MathExtras.cpp =================================================================== --- llvm/lib/Support/MathExtras.cpp +++ llvm/lib/Support/MathExtras.cpp @@ -15,17 +15,17 @@ #ifdef _MSC_VER #include #else -#include +#include #endif namespace llvm { #if defined(_MSC_VER) - // Visual Studio defines the HUGE_VAL class of macros using purposeful - // constant arithmetic overflow, which it then warns on when encountered. - const float huge_valf = std::numeric_limits::infinity(); +// Visual Studio defines the HUGE_VAL class of macros using purposeful +// constant arithmetic overflow, which it then warns on when encountered. +constexpr float huge_valf = std::numeric_limits::infinity(); #else - const float huge_valf = HUGE_VALF; +constexpr float huge_valf = HUGE_VALF; #endif } // namespace llvm