replace compiler-specific code with new C++20 bit manipulation libcalls
MODIFY
ir/instr.cpp
ir/instr.cpp
#include "smt/solver.h"
#include "util/compiler.h"
#include <functional>
+#include <numeric>
#include <sstream>
using namespace smt;

MODIFY
ir/type.cpp
ir/type.cpp
#include "util/compiler.h"
#include <array>
#include <cassert>
+#include <numeric>
#include <sstream>
using namespace smt;

MODIFY
smt/expr.cpp
smt/expr.cpp
#include "smt/ctx.h"
#include "util/compiler.h"
#include <algorithm>
+#include <bit>
#include <cassert>
#include <climits>
#include <limits>
@@ -516,7 +517,7 @@ unsigned expr::min_leading_zeros() const {
if (isConcat(a, b)) {
return a.min_leading_zeros();
} else if (isUInt(n)) {
- return num_leading_zeros(n) - (64 - bits());
+ return countl_zero(n) - (64 - bits());
}
return 0;
}
@@ -1094,8 +1095,8 @@ expr expr::operator&(const expr &rhs) const {
if (!a.isUInt(n) || n == 0 || n == numeric_limits<uint64_t>::max())
return expr();
- auto lead = num_leading_zeros(n);
- auto trail = num_trailing_zeros(n);
+ auto lead = countl_zero(n);
+ auto trail = countr_zero(n);
if (!is_power2((n >> trail) + 1))
return expr();

MODIFY
tools/transform.cpp
tools/transform.cpp
#include <algorithm>
#include <iostream>
#include <map>
+#include <numeric>
#include <set>
#include <sstream>
#include <unordered_map>

MODIFY
util/compiler.cpp
util/compiler.cpp
// Distributed under the MIT license that can be found in the LICENSE file.
#include "util/compiler.h"
-#ifdef _MSC_VER
-# include <intrin.h>
-#endif
+#include <algorithm>
+#include <bit>
using namespace std;
namespace util {
unsigned ilog2(uint64_t n) {
-#ifdef __GNUC__
- return n == 0 ? 0 : (63 - __builtin_clzll(n));
-#elif defined(_MSC_VER) && defined(_M_X64)
- return 63 - (unsigned)__lzcnt64(n);
-#else
-# error Unknown compiler
-#endif
+ return n == 0 ? 0 : bit_width(n) - 1;
}
unsigned ilog2_ceil(uint64_t n, bool up_power2) {
@@ -26,7 +19,7 @@ unsigned ilog2_ceil(uint64_t n, bool up_power2) {
}
bool is_power2(uint64_t n, uint64_t *log) {
- if (n == 0 || (n & (n - 1)) != 0)
+ if (!has_single_bit(n))
return false;
if (log)
@@ -35,33 +28,7 @@ bool is_power2(uint64_t n, uint64_t *log) {
}
unsigned num_sign_bits(uint64_t n) {
-#ifdef __clang__
- if (n == 0 || n == -1)
- return 63;
- int zeros = __builtin_clzll(n) - 1;
- int ones = __builtin_clzll(~n) - 1;
- return zeros > ones ? zeros : ones;
-#elif defined(__GNUC__)
- return __builtin_clrsbll(n);
-#else
-# error Unknown compiler
-#endif
-}
-
-unsigned num_leading_zeros(uint64_t n) {
-#if defined(__GNUC__)
- return n == 0 ? 64 : __builtin_clzll(n);
-#else
-# error Unknown compiler
-#endif
-}
-
-unsigned num_trailing_zeros(uint64_t n) {
-#if defined(__GNUC__)
- return n == 0 ? 64 : __builtin_ctzll(n);
-#else
-# error Unknown compiler
-#endif
+ return max(countl_zero(n), countl_one(n));
}
uint64_t add_saturate(uint64_t a, uint64_t b) {
@@ -84,12 +51,4 @@ uint64_t round_up(uint64_t n, uint64_t amount) {
return divide_up(n, amount) * amount;
}
-uint64_t gcd(uint64_t n, uint64_t m) {
- assert(n != 0 || m != 0);
- if (n < m) return gcd(m, n);
- else if (m == 0) return n;
- else if (n % m == 0) return m;
- return gcd(m, n % m);
-}
-
}

MODIFY
util/compiler.h
util/compiler.h
@@ -48,14 +48,11 @@ unsigned ilog2(uint64_t n);
unsigned ilog2_ceil(uint64_t n, bool up_power2);
bool is_power2(uint64_t n, uint64_t *log = nullptr);
unsigned num_sign_bits(uint64_t n);
-unsigned num_leading_zeros(uint64_t n);
-unsigned num_trailing_zeros(uint64_t n);
uint64_t add_saturate(uint64_t a, uint64_t b);
uint64_t mul_saturate(uint64_t a, uint64_t b);
uint64_t divide_up(uint64_t n, uint64_t amount); // division with ceiling
uint64_t round_up(uint64_t n, uint64_t amount);
-uint64_t gcd(uint64_t a, uint64_t b);
}

replace compiler-specific code with new C++20 bit manipulation libcalls