Cleanup duplicated bit-rotation code PiperOrigin-RevId: 857286087 Change-Id: Ie79f5b9e7ca8417f6311750c0de469ca6de4a8f9
diff --git a/absl/crc/CMakeLists.txt b/absl/crc/CMakeLists.txt index f068e54..09d3485 100644 --- a/absl/crc/CMakeLists.txt +++ b/absl/crc/CMakeLists.txt
@@ -43,13 +43,13 @@ ${ABSL_DEFAULT_COPTS} DEPS absl::crc_cpu_detect + absl::bits absl::config absl::core_headers absl::endian + absl::memory absl::prefetch absl::raw_logging_internal - absl::memory - absl::bits ) absl_cc_library(
diff --git a/absl/crc/internal/crc.cc b/absl/crc/internal/crc.cc index 22e91c5..6262dd2 100644 --- a/absl/crc/internal/crc.cc +++ b/absl/crc/internal/crc.cc
@@ -47,6 +47,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/prefetch.h" #include "absl/crc/internal/crc_internal.h" +#include "absl/numeric/bits.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -410,16 +411,13 @@ // Rotate by near half the word size plus 1. See the scramble comment in // crc_internal.h for an explanation. constexpr int scramble_rotate = (32 / 2) + 1; - *crc = RotateRight<uint32_t>(static_cast<unsigned int>(*crc + kScrambleLo), - 32, scramble_rotate) & - MaskOfLength<uint32_t>(32); + *crc = absl::rotr(static_cast<uint32_t>(*crc + kScrambleLo), scramble_rotate); } void CRC32::Unscramble(uint32_t* crc) const { constexpr int scramble_rotate = (32 / 2) + 1; - uint64_t rotated = RotateRight<uint32_t>(static_cast<unsigned int>(*crc), 32, - 32 - scramble_rotate); - *crc = (rotated - kScrambleLo) & MaskOfLength<uint32_t>(32); + uint64_t rotated = absl::rotl(*crc, scramble_rotate); + *crc = static_cast<uint32_t>(rotated - kScrambleLo); } // Constructor and destructor for base class CRC.
diff --git a/absl/crc/internal/crc_internal.h b/absl/crc/internal/crc_internal.h index 4d3582d..0447858 100644 --- a/absl/crc/internal/crc_internal.h +++ b/absl/crc/internal/crc_internal.h
@@ -137,22 +137,6 @@ // Helpers -// Return a bit mask containing len 1-bits. -// Requires 0 < len <= sizeof(T) -template <typename T> -T MaskOfLength(int len) { - // shift 2 by len-1 rather than 1 by len because shifts of wordsize - // are undefined. - return (T(2) << (len - 1)) - 1; -} - -// Rotate low-order "width" bits of "in" right by "r" bits, -// setting other bits in word to arbitrary values. -template <typename T> -T RotateRight(T in, int width, int r) { - return (in << (width - r)) | ((in >> r) & MaskOfLength<T>(width - r)); -} - // RoundUp<N>(p) returns the lowest address >= p aligned to an N-byte // boundary. Requires that N is a power of 2. template <int alignment>
diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index 187689f..76dd606 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel
@@ -174,6 +174,7 @@ "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/numeric:bits", ], )
diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index b439e4c..c8797ff 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt
@@ -137,6 +137,7 @@ DEPS absl::config absl::core_headers + absl::bits absl::endian )
diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index f0d3196..416beed 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc
@@ -21,13 +21,13 @@ #include "absl/hash/internal/city.h" -#include <string.h> // for memcpy and memset #include <algorithm> #include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/internal/unaligned_access.h" #include "absl/base/optimization.h" +#include "absl/numeric/bits.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -68,11 +68,6 @@ return h; } -static uint32_t Rotate32(uint32_t val, int shift) { - // Avoid shifting by 32: doing so yields an undefined result. - return shift == 0 ? val : ((val >> shift) | (val << (32 - shift))); -} - #undef PERMUTE3 #define PERMUTE3(a, b, c) \ do { \ @@ -83,10 +78,10 @@ static uint32_t Mur(uint32_t a, uint32_t h) { // Helper from Murmur3 for combining two 32-bit values. a *= c1; - a = Rotate32(a, 17); + a = absl::rotr(a, 17); a *= c2; h ^= a; - h = Rotate32(h, 19); + h = absl::rotr(h, 19); return h * 5 + 0xe6546b64; } @@ -131,44 +126,44 @@ // len > 24 uint32_t h = static_cast<uint32_t>(len), g = c1 * h, f = g; - uint32_t a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2; - uint32_t a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2; - uint32_t a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2; - uint32_t a3 = Rotate32(Fetch32(s + len - 12) * c1, 17) * c2; - uint32_t a4 = Rotate32(Fetch32(s + len - 20) * c1, 17) * c2; + uint32_t a0 = absl::rotr(Fetch32(s + len - 4) * c1, 17) * c2; + uint32_t a1 = absl::rotr(Fetch32(s + len - 8) * c1, 17) * c2; + uint32_t a2 = absl::rotr(Fetch32(s + len - 16) * c1, 17) * c2; + uint32_t a3 = absl::rotr(Fetch32(s + len - 12) * c1, 17) * c2; + uint32_t a4 = absl::rotr(Fetch32(s + len - 20) * c1, 17) * c2; h ^= a0; - h = Rotate32(h, 19); + h = absl::rotr(h, 19); h = h * 5 + 0xe6546b64; h ^= a2; - h = Rotate32(h, 19); + h = absl::rotr(h, 19); h = h * 5 + 0xe6546b64; g ^= a1; - g = Rotate32(g, 19); + g = absl::rotr(g, 19); g = g * 5 + 0xe6546b64; g ^= a3; - g = Rotate32(g, 19); + g = absl::rotr(g, 19); g = g * 5 + 0xe6546b64; f += a4; - f = Rotate32(f, 19); + f = absl::rotr(f, 19); f = f * 5 + 0xe6546b64; size_t iters = (len - 1) / 20; do { - uint32_t b0 = Rotate32(Fetch32(s) * c1, 17) * c2; + uint32_t b0 = absl::rotr(Fetch32(s) * c1, 17) * c2; uint32_t b1 = Fetch32(s + 4); - uint32_t b2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2; - uint32_t b3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2; + uint32_t b2 = absl::rotr(Fetch32(s + 8) * c1, 17) * c2; + uint32_t b3 = absl::rotr(Fetch32(s + 12) * c1, 17) * c2; uint32_t b4 = Fetch32(s + 16); h ^= b0; - h = Rotate32(h, 18); + h = absl::rotr(h, 18); h = h * 5 + 0xe6546b64; f += b1; - f = Rotate32(f, 19); + f = absl::rotr(f, 19); f = f * c1; g += b2; - g = Rotate32(g, 18); + g = absl::rotr(g, 18); g = g * 5 + 0xe6546b64; h ^= b3 + b1; - h = Rotate32(h, 19); + h = absl::rotr(h, 19); h = h * 5 + 0xe6546b64; g ^= b4; g = absl::gbswap_32(g) * 5; @@ -178,26 +173,19 @@ PERMUTE3(f, h, g); s += 20; } while (--iters != 0); - g = Rotate32(g, 11) * c1; - g = Rotate32(g, 17) * c1; - f = Rotate32(f, 11) * c1; - f = Rotate32(f, 17) * c1; - h = Rotate32(h + g, 19); + g = absl::rotr(g, 11) * c1; + g = absl::rotr(g, 17) * c1; + f = absl::rotr(f, 11) * c1; + f = absl::rotr(f, 17) * c1; + h = absl::rotr(h + g, 19); h = h * 5 + 0xe6546b64; - h = Rotate32(h, 17) * c1; - h = Rotate32(h + f, 19); + h = absl::rotr(h, 17) * c1; + h = absl::rotr(h + f, 19); h = h * 5 + 0xe6546b64; - h = Rotate32(h, 17) * c1; + h = absl::rotr(h, 17) * c1; return h; } -// Bitwise right rotate. Normally this will compile to a single -// instruction, especially if the shift is a manifest constant. -static uint64_t Rotate(uint64_t val, int shift) { - // Avoid shifting by 64: doing so yields an undefined result. - return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); -} - static uint64_t ShiftMix(uint64_t val) { return val ^ (val >> 47); } static uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) { @@ -220,8 +208,8 @@ uint64_t mul = k2 + len * 2; uint64_t a = Fetch64(s) + k2; uint64_t b = Fetch64(s + len - 8); - uint64_t c = Rotate(b, 37) * mul + a; - uint64_t d = (Rotate(a, 25) + b) * mul; + uint64_t c = absl::rotr(b, 37) * mul + a; + uint64_t d = (absl::rotr(a, 25) + b) * mul; return HashLen16(c, d, mul); } if (len >= 4) { @@ -248,8 +236,8 @@ uint64_t b = Fetch64(s + 8); uint64_t c = Fetch64(s + len - 8) * mul; uint64_t d = Fetch64(s + len - 16) * k2; - return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d, - a + Rotate(b + k2, 18) + c, mul); + return HashLen16(absl::rotr(a + b, 43) + absl::rotr(c, 30) + d, + a + absl::rotr(b + k2, 18) + c, mul); } // Return a 16-byte hash for 48 bytes. Quick and dirty. @@ -257,11 +245,11 @@ static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { a += w; - b = Rotate(b + a + z, 21); + b = absl::rotr(b + a + z, 21); uint64_t c = a; a += x; a += y; - b += Rotate(a, 44); + b += absl::rotr(a, 44); return std::make_pair(a + z, b + c); } @@ -284,10 +272,10 @@ uint64_t f = Fetch64(s + 24) * 9; uint64_t g = Fetch64(s + len - 8); uint64_t h = Fetch64(s + len - 16) * mul; - uint64_t u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9; + uint64_t u = absl::rotr(a + g, 43) + (absl::rotr(b, 30) + c) * 9; uint64_t v = ((a + g) ^ d) + f + 1; uint64_t w = absl::gbswap_64((u + v) * mul) + h; - uint64_t x = Rotate(e + f, 42) + c; + uint64_t x = absl::rotr(e + f, 42) + c; uint64_t y = (absl::gbswap_64((v + w) * mul) + g) * mul; uint64_t z = e + f + c; a = absl::gbswap_64((x + z) * mul + y) + b; @@ -320,11 +308,11 @@ // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. len = (len - 1) & ~static_cast<size_t>(63); do { - x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; - y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; + x = absl::rotr(x + y + v.first + Fetch64(s + 8), 37) * k1; + y = absl::rotr(y + v.second + Fetch64(s + 48), 42) * k1; x ^= w.second; y += v.first + Fetch64(s + 40); - z = Rotate(z + w.first, 33) * k1; + z = absl::rotr(z + w.first, 33) * k1; v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); std::swap(z, x);