diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index 9150789aaf..39b55f51ec 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -40,39 +40,30 @@ extern PGDLLIMPORT const uint8 pg_number_of_ones[256]; static inline int pg_leftmost_one_pos32(uint32 word) { -#ifdef HAVE__BUILTIN_CLZ - int bitscan_result; -#elif defined(_MSC_VER) - unsigned long bitscan_result; +#if defined(_MSC_VER) + unsigned long result; bool non_zero; -#endif - -#if !defined(HAVE_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) +#else int result; - int shift = 32 - 8; +#endif Assert(word != 0); +#if defined(HAVE__BUILTIN_CLZ) + result = 31 - __builtin_clz(word); +#elif defined(_MSC_VER) + non_zero = _BitScanReverse(&result, word); + Assert(non_zero); +#else + int shift = 32 - 8; + while ((word >> shift) == 0) shift -= 8; result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; #endif -#ifdef HAVE_BITSCAN_REVERSE - -#if defined(HAVE__BUILTIN_CLZ) - bitscan_result = 31 - __builtin_clz(word); -#elif defined(_MSC_VER) - non_zero = _BitScanReverse(&bitscan_result, word); - Assert(non_zero); -#endif - Assert(bitscan_result == result); - return bitscan_result; - -#else return result; -#endif /* HAVE_BITSCAN_REVERSE */ } /* @@ -82,46 +73,38 @@ pg_leftmost_one_pos32(uint32 word) static inline int pg_leftmost_one_pos64(uint64 word) { -#ifdef HAVE__BUILTIN_CLZ - int bitscan_result; -#elif defined(_MSC_VER) - unsigned long bitscan_result; +#if defined(_MSC_VER) + unsigned long result; bool non_zero; -#endif - -#if !defined(HAVE_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) +#else int result; - int shift = 64 - 8; - - Assert(word != 0); - - while ((word >> shift) == 0) - shift -= 8; - - result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; #endif -#ifdef HAVE_BITSCAN_REVERSE + Assert(word != 0); #if defined(HAVE__BUILTIN_CLZ) #if defined(HAVE_LONG_INT_64) - bitscan_result = 63 - __builtin_clzl(word); + result = 63 - __builtin_clzl(word); #elif defined(HAVE_LONG_LONG_INT_64) - bitscan_result = 63 - __builtin_clzll(word); + result = 63 - __builtin_clzll(word); #else #error must have a working 64-bit integer datatype #endif /* HAVE_LONG_INT_64 */ #elif defined(_MSC_VER) - non_zero = _BitScanReverse64(&bitscan_result, word); + non_zero = _BitScanReverse64(&result, word); Assert(non_zero); +#else + int result; + int shift = 64 - 8; + + while ((word >> shift) == 0) + shift -= 8; + + result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; #endif /* HAVE__BUILTIN_CLZ */ - Assert(bitscan_result == result); - return bitscan_result; -#else return result; -#endif /* HAVE_BITSCAN_REVERSE */ } /* @@ -132,20 +115,23 @@ pg_leftmost_one_pos64(uint64 word) static inline int pg_rightmost_one_pos32(uint32 word) { -#ifdef HAVE__BUILTIN_CTZ - const uint32 orig_word = word; - int bitscan_result; -#elif defined(_MSC_VER) - const unsigned long orig_word = word; - unsigned long bitscan_result; +#if defined(_MSC_VER) + unsigned long result; bool non_zero; +#else + int result; #endif -#if !defined(HAVE_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) - int result = 0; - Assert(word != 0); +#if defined(HAVE__BUILTIN_CTZ) + result = __builtin_ctz(word); +#elif defined(_MSC_VER) + non_zero = _BitScanForward(&result, word); + Assert(non_zero); +#else + result = 0; + while ((word & 255) == 0) { word >>= 8; @@ -154,20 +140,7 @@ pg_rightmost_one_pos32(uint32 word) result += pg_rightmost_one_pos[word & 255]; #endif -#ifdef HAVE_BITSCAN_FORWARD - -#if defined(HAVE__BUILTIN_CTZ) - bitscan_result = __builtin_ctz(orig_word); -#elif defined(_MSC_VER) - non_zero = _BitScanForward(&bitscan_result, orig_word); - Assert(non_zero); -#endif - Assert(bitscan_result == result); - return bitscan_result; - -#else return result; -#endif /* HAVE_BITSCAN_FORWARD */ } /* @@ -177,49 +150,39 @@ pg_rightmost_one_pos32(uint32 word) static inline int pg_rightmost_one_pos64(uint64 word) { -#ifdef HAVE__BUILTIN_CTZ - const uint64 orig_word = word; - int bitscan_result; -#elif defined(_MSC_VER) - const unsigned __int64 orig_word = word; - unsigned long bitscan_result; +#if defined(_MSC_VER) + unsigned long result; bool non_zero; +#else + int result; #endif -#if !defined(HAVE_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) - int result = 0; - Assert(word != 0); - while ((word & 255) == 0) - { - word >>= 8; - result += 8; - } - result += pg_rightmost_one_pos[word & 255]; -#endif - -#ifdef HAVE_BITSCAN_FORWARD - #if defined(HAVE__BUILTIN_CTZ) #if defined(HAVE_LONG_INT_64) - bitscan_result = __builtin_ctzl(orig_word); + result = __builtin_ctzl(word); #elif defined(HAVE_LONG_LONG_INT_64) - bitscan_result = __builtin_ctzll(orig_word); + result = __builtin_ctzll(word); #else #error must have a working 64-bit integer datatype #endif /* HAVE_LONG_INT_64 */ #elif defined(_MSC_VER) - non_zero = _BitScanForward64(&bitscan_result, orig_word); + non_zero = _BitScanForward64(&result, word); Assert(non_zero); -#endif /* HAVE__BUILTIN_CTZ */ - Assert(bitscan_result == result); - return bitscan_result; - #else + result = 0; + + while ((word & 255) == 0) + { + word >>= 8; + result += 8; + } + result += pg_rightmost_one_pos[word & 255]; +#endif + return result; -#endif /* HAVE_BITSCAN_FORWARD */ } /*