v3-0003-Add-new-symbols-for-reducing-repetition.patch
text/x-patch
Filename: v3-0003-Add-new-symbols-for-reducing-repetition.patch
Type: text/x-patch
Part: 2
Message:
bitscan forward/reverse on Windows
Patch
Format: format-patch
Series: patch v3-0003
Subject: Add new symbols for reducing repetition
| File | + | − |
|---|---|---|
| src/include/port/pg_bitutils.h | 40 | 32 |
From fb51913a6c76a5d5aa09a8ef843e16cd3c383f37 Mon Sep 17 00:00:00 2001 From: John Naylor <john.naylor@postgresql.org> Date: Tue, 24 Jan 2023 20:39:55 +0700 Subject: [PATCH v3 3/3] Add new symbols for reducing repetition --- src/include/port/pg_bitutils.h | 72 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index ce04f4ffad..68aba3e090 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -21,6 +21,10 @@ extern PGDLLIMPORT const uint8 pg_leftmost_one_pos[256]; extern PGDLLIMPORT const uint8 pg_rightmost_one_pos[256]; extern PGDLLIMPORT const uint8 pg_number_of_ones[256]; +#if defined(HAVE__BUILTIN_CLZ) || defined(_MSC_VER) +#define FAST_BITSCAN_REVERSE +#endif + /* * pg_leftmost_one_pos32 * Returns the position of the most significant set bit in "word", @@ -36,7 +40,7 @@ pg_leftmost_one_pos32(uint32 word) unsigned char non_zero; // XXX can this be bool? #endif -#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING) +#if !defined(FAST_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) int result; int shift = 32 - 8; @@ -48,18 +52,18 @@ pg_leftmost_one_pos32(uint32 word) result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; #endif -#if defined(HAVE__BUILTIN_CLZ) - bitscan_result = 31 - __builtin_clz(word); - Assert(bitscan_result == result); - return bitscan_result; -#elif defined(_MSC_VER) +#ifdef FAST_BITSCAN_REVERSE +#if defined(_MSC_VER) non_zero = _BitScanReverse(&bitscan_result, word); Assert(non_zero); +#elif defined(HAVE__BUILTIN_CLZ) + bitscan_result = 31 - __builtin_clz(word); +#endif Assert(bitscan_result == result); return bitscan_result; #else return result; -#endif /* HAVE__BUILTIN_CLZ */ +#endif /* FAST_BITSCAN_REVERSE */ } /* @@ -76,7 +80,7 @@ pg_leftmost_one_pos64(uint64 word) unsigned char non_zero; // XXX can this be bool? #endif -#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING) +#if !defined(FAST_BITSCAN_REVERSE) || defined(USE_ASSERT_CHECKING) int result; int shift = 64 - 8; @@ -88,26 +92,30 @@ pg_leftmost_one_pos64(uint64 word) result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; #endif -#if defined(HAVE__BUILTIN_CLZ) +#ifdef FAST_BITSCAN_REVERSE +#if defined(_MSC_VER) + non_zero = _BitScanReverse64(&bitscan_result, word); + Assert(non_zero); +#elif defined(HAVE__BUILTIN_CLZ) #if defined(HAVE_LONG_INT_64) bitscan_result = 63 - __builtin_clzl(word); #elif defined(HAVE_LONG_LONG_INT_64) bitscan_result = 63 - __builtin_clzll(word); #else #error must have a working 64-bit integer datatype -#endif /* HAVE_LONG_... */ - Assert(bitscan_result == result); - return bitscan_result; -#elif defined(_MSC_VER) - non_zero = _BitScanReverse64(&bitscan_result, word); - Assert(non_zero); +#endif /* HAVE_LONG_INT_64 */ +#endif /* _MSC_VER */ Assert(bitscan_result == result); return bitscan_result; #else return result; -#endif /* HAVE__BUILTIN_CLZ */ +#endif /* FAST_BITSCAN_REVERSE */ } +#if defined(HAVE__BUILTIN_CTZ) || defined(_MSC_VER) +#define FAST_BITSCAN_FORWARD +#endif + /* * pg_rightmost_one_pos32 * Returns the position of the least significant set bit in "word", @@ -125,7 +133,7 @@ pg_rightmost_one_pos32(uint32 word) unsigned char non_zero; // XXX can this be bool? #endif -#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING) +#if !defined(FAST_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) int result = 0; Assert(word != 0); @@ -138,18 +146,18 @@ pg_rightmost_one_pos32(uint32 word) result += pg_rightmost_one_pos[word & 255]; #endif -#if defined(HAVE__BUILTIN_CTZ) - bitscan_result = __builtin_ctz(orig_word); - Assert(bitscan_result == result); - return bitscan_result; -#elif defined(_MSC_VER) +#ifdef FAST_BITSCAN_FORWARD +#if defined(_MSC_VER) non_zero = _BitScanForward(&bitscan_result, orig_word); Assert(non_zero); +#elif defined(HAVE__BUILTIN_CTZ) + bitscan_result = __builtin_ctz(orig_word); +#endif Assert(bitscan_result == result); return bitscan_result; #else return result; -#endif /* HAVE__BUILTIN_CTZ */ +#endif /* FAST_BITSCAN_FORWARD */ } /* @@ -168,7 +176,7 @@ pg_rightmost_one_pos64(uint64 word) unsigned char non_zero; // XXX can this be bool? #endif -#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING) +#if !defined(FAST_BITSCAN_FORWARD) || defined(USE_ASSERT_CHECKING) int result = 0; Assert(word != 0); @@ -181,24 +189,24 @@ pg_rightmost_one_pos64(uint64 word) result += pg_rightmost_one_pos[word & 255]; #endif -#ifdef HAVE__BUILTIN_CTZ +#ifdef FAST_BITSCAN_FORWARD +#if defined(_MSC_VER) + non_zero = _BitScanForward64(&bitscan_result, orig_word); + Assert(non_zero); +#elif HAVE__BUILTIN_CTZ #if defined(HAVE_LONG_INT_64) bitscan_result = __builtin_ctzl(orig_word); #elif defined(HAVE_LONG_LONG_INT_64) bitscan_result = __builtin_ctzll(orig_word); #else #error must have a working 64-bit integer datatype -#endif /* HAVE_LONG_... */ - Assert(bitscan_result == result); - return bitscan_result; -#elif defined(_MSC_VER) - non_zero = _BitScanForward64(&bitscan_result, orig_word); - Assert(non_zero); +#endif /* HAVE_LONG_INT_64 */ +#endif /* _MSC_VER */ Assert(bitscan_result == result); return bitscan_result; #else return result; -#endif /* HAVE__BUILTIN_CTZ */ +#endif /* FAST_BITSCAN_FORWARD */ } /* -- 2.39.0