14
14
#define LLVM_SUPPORT_MATHEXTRAS_H
15
15
16
16
#include " llvm/ADT/bit.h"
17
- #include " llvm/Support/Compiler.h"
18
17
#include < cassert>
19
18
#include < climits>
20
19
#include < cstdint>
21
20
#include < cstring>
22
21
#include < limits>
23
22
#include < type_traits>
24
23
25
- #ifdef _MSC_VER
26
- // Declare these intrinsics manually rather including intrin.h. It's very
27
- // expensive, and MathExtras.h is popular.
28
- // #include <intrin.h>
29
- extern " C" {
30
- unsigned char _BitScanForward (unsigned long *_Index, unsigned long _Mask);
31
- unsigned char _BitScanForward64 (unsigned long *_Index, unsigned __int64 _Mask);
32
- unsigned char _BitScanReverse (unsigned long *_Index, unsigned long _Mask);
33
- unsigned char _BitScanReverse64 (unsigned long *_Index, unsigned __int64 _Mask);
34
- }
35
- #endif
36
-
37
24
namespace llvm {
38
25
39
26
// / The behavior an operation has on an input of 0.
@@ -80,65 +67,6 @@ constexpr float ef = 2.71828183F, // (0x1.5bf0a8P+1) https://oeis.org/A
80
67
phif = 1 .61803399F ; // (0x1.9e377aP+0) https://oeis.org/A001622
81
68
} // namespace numbers
82
69
83
- namespace detail {
84
- template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
85
- static unsigned count (T Val) {
86
- if (!Val)
87
- return std::numeric_limits<T>::digits;
88
- if (Val & 0x1 )
89
- return 0 ;
90
-
91
- // Bisection method.
92
- unsigned ZeroBits = 0 ;
93
- T Shift = std::numeric_limits<T>::digits >> 1 ;
94
- T Mask = std::numeric_limits<T>::max () >> Shift;
95
- while (Shift) {
96
- if ((Val & Mask) == 0 ) {
97
- Val >>= Shift;
98
- ZeroBits |= Shift;
99
- }
100
- Shift >>= 1 ;
101
- Mask >>= Shift;
102
- }
103
- return ZeroBits;
104
- }
105
- };
106
-
107
- #if defined(__GNUC__) || defined(_MSC_VER)
108
- template <typename T> struct TrailingZerosCounter <T, 4 > {
109
- static unsigned count (T Val) {
110
- if (Val == 0 )
111
- return 32 ;
112
-
113
- #if __has_builtin(__builtin_ctz) || defined(__GNUC__)
114
- return __builtin_ctz (Val);
115
- #elif defined(_MSC_VER)
116
- unsigned long Index;
117
- _BitScanForward (&Index, Val);
118
- return Index;
119
- #endif
120
- }
121
- };
122
-
123
- #if !defined(_MSC_VER) || defined(_M_X64)
124
- template <typename T> struct TrailingZerosCounter <T, 8 > {
125
- static unsigned count (T Val) {
126
- if (Val == 0 )
127
- return 64 ;
128
-
129
- #if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
130
- return __builtin_ctzll (Val);
131
- #elif defined(_MSC_VER)
132
- unsigned long Index;
133
- _BitScanForward64 (&Index, Val);
134
- return Index;
135
- #endif
136
- }
137
- };
138
- #endif
139
- #endif
140
- } // namespace detail
141
-
142
70
// / Count number of 0's from the least significant bit to the most
143
71
// / stopping at the first 1.
144
72
// /
@@ -148,62 +76,8 @@ template <typename T> struct TrailingZerosCounter<T, 8> {
148
76
template <typename T> unsigned countTrailingZeros (T Val) {
149
77
static_assert (std::is_unsigned_v<T>,
150
78
" Only unsigned integral types are allowed." );
151
- return llvm::detail::TrailingZerosCounter<T, sizeof (T)>::count (Val);
152
- }
153
-
154
- namespace detail {
155
- template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
156
- static unsigned count (T Val) {
157
- if (!Val)
158
- return std::numeric_limits<T>::digits;
159
-
160
- // Bisection method.
161
- unsigned ZeroBits = 0 ;
162
- for (T Shift = std::numeric_limits<T>::digits >> 1 ; Shift; Shift >>= 1 ) {
163
- T Tmp = Val >> Shift;
164
- if (Tmp)
165
- Val = Tmp;
166
- else
167
- ZeroBits |= Shift;
168
- }
169
- return ZeroBits;
170
- }
171
- };
172
-
173
- #if defined(__GNUC__) || defined(_MSC_VER)
174
- template <typename T> struct LeadingZerosCounter <T, 4 > {
175
- static unsigned count (T Val) {
176
- if (Val == 0 )
177
- return 32 ;
178
-
179
- #if __has_builtin(__builtin_clz) || defined(__GNUC__)
180
- return __builtin_clz (Val);
181
- #elif defined(_MSC_VER)
182
- unsigned long Index;
183
- _BitScanReverse (&Index, Val);
184
- return Index ^ 31 ;
185
- #endif
186
- }
187
- };
188
-
189
- #if !defined(_MSC_VER) || defined(_M_X64)
190
- template <typename T> struct LeadingZerosCounter <T, 8 > {
191
- static unsigned count (T Val) {
192
- if (Val == 0 )
193
- return 64 ;
194
-
195
- #if __has_builtin(__builtin_clzll) || defined(__GNUC__)
196
- return __builtin_clzll (Val);
197
- #elif defined(_MSC_VER)
198
- unsigned long Index;
199
- _BitScanReverse64 (&Index, Val);
200
- return Index ^ 63 ;
201
- #endif
202
- }
203
- };
204
- #endif
205
- #endif
206
- } // namespace detail
79
+ return llvm::countr_zero (Val);
80
+ }
207
81
208
82
// / Count number of 0's from the most significant bit to the least
209
83
// / stopping at the first 1.
@@ -214,7 +88,7 @@ template <typename T> struct LeadingZerosCounter<T, 8> {
214
88
template <typename T> unsigned countLeadingZeros (T Val) {
215
89
static_assert (std::is_unsigned_v<T>,
216
90
" Only unsigned integral types are allowed." );
217
- return llvm::detail::LeadingZerosCounter<T, sizeof (T)>:: count (Val);
91
+ return llvm::countl_zero (Val);
218
92
}
219
93
220
94
// / Get the index of the first set bit starting from the least
@@ -465,7 +339,7 @@ constexpr inline bool isPowerOf2_64(uint64_t Value) {
465
339
template <typename T> unsigned countLeadingOnes (T Value) {
466
340
static_assert (std::is_unsigned_v<T>,
467
341
" Only unsigned integral types are allowed." );
468
- return countLeadingZeros <T>(~ Value);
342
+ return llvm::countl_one <T>(Value);
469
343
}
470
344
471
345
// / Count the number of ones from the least significant bit to the first
@@ -478,7 +352,7 @@ template <typename T> unsigned countLeadingOnes(T Value) {
478
352
template <typename T> unsigned countTrailingOnes (T Value) {
479
353
static_assert (std::is_unsigned_v<T>,
480
354
" Only unsigned integral types are allowed." );
481
- return countTrailingZeros <T>(~ Value);
355
+ return llvm::countr_one <T>(Value);
482
356
}
483
357
484
358
// / Count the number of set bits in a value.
0 commit comments