Brian Silverman | f7bd1c2 | 2015-12-24 16:07:11 -0800 | [diff] [blame^] | 1 | //===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file contains some functions that are useful for math stuff. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_SUPPORT_MATHEXTRAS_H |
| 15 | #define LLVM_SUPPORT_MATHEXTRAS_H |
| 16 | |
| 17 | #include "llvm/Compiler.h" |
| 18 | #include <cstdint> |
| 19 | #include <limits> |
| 20 | |
| 21 | namespace llvm { |
| 22 | /// \brief The behavior an operation has on an input of 0. |
| 23 | enum ZeroBehavior { |
| 24 | /// \brief The returned value is undefined. |
| 25 | ZB_Undefined, |
| 26 | /// \brief The returned value is numeric_limits<T>::max() |
| 27 | ZB_Max, |
| 28 | /// \brief The returned value is numeric_limits<T>::digits |
| 29 | ZB_Width |
| 30 | }; |
| 31 | |
| 32 | namespace detail { |
| 33 | template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter { |
| 34 | static std::size_t count(T Val, ZeroBehavior) { |
| 35 | if (!Val) |
| 36 | return std::numeric_limits<T>::digits; |
| 37 | |
| 38 | // Bisection method. |
| 39 | std::size_t ZeroBits = 0; |
| 40 | for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) { |
| 41 | T Tmp = Val >> Shift; |
| 42 | if (Tmp) |
| 43 | Val = Tmp; |
| 44 | else |
| 45 | ZeroBits |= Shift; |
| 46 | } |
| 47 | return ZeroBits; |
| 48 | } |
| 49 | }; |
| 50 | |
| 51 | #if __GNUC__ >= 4 || _MSC_VER |
| 52 | template <typename T> struct LeadingZerosCounter<T, 4> { |
| 53 | static std::size_t count(T Val, ZeroBehavior ZB) { |
| 54 | if (ZB != ZB_Undefined && Val == 0) |
| 55 | return 32; |
| 56 | |
| 57 | #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) |
| 58 | return __builtin_clz(Val); |
| 59 | #elif _MSC_VER |
| 60 | unsigned long Index; |
| 61 | _BitScanReverse(&Index, Val); |
| 62 | return Index ^ 31; |
| 63 | #endif |
| 64 | } |
| 65 | }; |
| 66 | |
| 67 | #if !defined(_MSC_VER) || defined(_M_X64) |
| 68 | template <typename T> struct LeadingZerosCounter<T, 8> { |
| 69 | static std::size_t count(T Val, ZeroBehavior ZB) { |
| 70 | if (ZB != ZB_Undefined && Val == 0) |
| 71 | return 64; |
| 72 | |
| 73 | #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) |
| 74 | return __builtin_clzll(Val); |
| 75 | #elif _MSC_VER |
| 76 | unsigned long Index; |
| 77 | _BitScanReverse64(&Index, Val); |
| 78 | return Index ^ 63; |
| 79 | #endif |
| 80 | } |
| 81 | }; |
| 82 | #endif |
| 83 | #endif |
| 84 | } // namespace detail |
| 85 | |
| 86 | /// \brief Count number of 0's from the most significant bit to the least |
| 87 | /// stopping at the first 1. |
| 88 | /// |
| 89 | /// Only unsigned integral types are allowed. |
| 90 | /// |
| 91 | /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are |
| 92 | /// valid arguments. |
| 93 | template <typename T> |
| 94 | std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { |
| 95 | static_assert(std::numeric_limits<T>::is_integer && |
| 96 | !std::numeric_limits<T>::is_signed, |
| 97 | "Only unsigned integral types are allowed."); |
| 98 | return detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB); |
| 99 | } |
| 100 | |
| 101 | /// Log2_32 - This function returns the floor log base 2 of the specified value, |
| 102 | /// -1 if the value is zero. (32 bit edition.) |
| 103 | /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 |
| 104 | inline unsigned Log2_32(uint32_t Value) { |
| 105 | return 31 - countLeadingZeros(Value); |
| 106 | } |
| 107 | |
| 108 | /// Log2_64 - This function returns the floor log base 2 of the specified value, |
| 109 | /// -1 if the value is zero. (64 bit edition.) |
| 110 | inline unsigned Log2_64(uint64_t Value) { |
| 111 | return 63 - countLeadingZeros(Value); |
| 112 | } |
| 113 | |
| 114 | /// Log2_32_Ceil - This function returns the ceil log base 2 of the specified |
| 115 | /// value, 32 if the value is zero. (32 bit edition). |
| 116 | /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 |
| 117 | inline unsigned Log2_32_Ceil(uint32_t Value) { |
| 118 | return 32 - countLeadingZeros(Value - 1); |
| 119 | } |
| 120 | |
| 121 | /// Log2_64_Ceil - This function returns the ceil log base 2 of the specified |
| 122 | /// value, 64 if the value is zero. (64 bit edition.) |
| 123 | inline unsigned Log2_64_Ceil(uint64_t Value) { |
| 124 | return 64 - countLeadingZeros(Value - 1); |
| 125 | } |
| 126 | |
| 127 | /// BitsToDouble - This function takes a 64-bit integer and returns the bit |
| 128 | /// equivalent double. |
| 129 | inline double BitsToDouble(uint64_t Bits) { |
| 130 | union { |
| 131 | uint64_t L; |
| 132 | double D; |
| 133 | } T; |
| 134 | T.L = Bits; |
| 135 | return T.D; |
| 136 | } |
| 137 | |
| 138 | /// BitsToFloat - This function takes a 32-bit integer and returns the bit |
| 139 | /// equivalent float. |
| 140 | inline float BitsToFloat(uint32_t Bits) { |
| 141 | union { |
| 142 | uint32_t I; |
| 143 | float F; |
| 144 | } T; |
| 145 | T.I = Bits; |
| 146 | return T.F; |
| 147 | } |
| 148 | |
| 149 | /// DoubleToBits - This function takes a double and returns the bit |
| 150 | /// equivalent 64-bit integer. Note that copying doubles around |
| 151 | /// changes the bits of NaNs on some hosts, notably x86, so this |
| 152 | /// routine cannot be used if these bits are needed. |
| 153 | inline uint64_t DoubleToBits(double Double) { |
| 154 | union { |
| 155 | uint64_t L; |
| 156 | double D; |
| 157 | } T; |
| 158 | T.D = Double; |
| 159 | return T.L; |
| 160 | } |
| 161 | |
| 162 | /// FloatToBits - This function takes a float and returns the bit |
| 163 | /// equivalent 32-bit integer. Note that copying floats around |
| 164 | /// changes the bits of NaNs on some hosts, notably x86, so this |
| 165 | /// routine cannot be used if these bits are needed. |
| 166 | inline uint32_t FloatToBits(float Float) { |
| 167 | union { |
| 168 | uint32_t I; |
| 169 | float F; |
| 170 | } T; |
| 171 | T.F = Float; |
| 172 | return T.I; |
| 173 | } |
| 174 | |
| 175 | /// NextPowerOf2 - Returns the next power of two (in 64-bits) |
| 176 | /// that is strictly greater than A. Returns zero on overflow. |
| 177 | inline uint64_t NextPowerOf2(uint64_t A) { |
| 178 | A |= (A >> 1); |
| 179 | A |= (A >> 2); |
| 180 | A |= (A >> 4); |
| 181 | A |= (A >> 8); |
| 182 | A |= (A >> 16); |
| 183 | A |= (A >> 32); |
| 184 | return A + 1; |
| 185 | } |
| 186 | |
| 187 | } // namespace llvm |
| 188 | |
| 189 | #endif |