Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6773197

Browse files
committed
Add MSVC support for pg_leftmost_one_pos32() and friends
To allow testing for general support for fast bitscan intrinsics,add symbols HAVE_BITSCAN_REVERSE and HAVE_BITSCAN_FORWARD.Also do related cleanup in AllocSetFreeIndex(): Previously, wetested for HAVE__BUILTIN_CLZ and copied the relevant internals ofpg_leftmost_one_pos32(), with a special fallback that does lesswork than the general fallback for that function. Now that we havea more general test, we just call pg_leftmost_one_pos32() directlyfor platforms with intrinsic support. On gcc at least, there is nodifference in the binary for non-assert builds.Discussion:https://www.postgresql.org/message-id/CAFBsxsEPc%2BFnX_0vmmQ5DHv60sk4rL_RZJ%2BMD6ei%3D76L0kFMvA%40mail.gmail.com
1 parent204b0cb commit6773197

File tree

2 files changed

+70
-11
lines changed

2 files changed

+70
-11
lines changed

‎src/backend/utils/mmgr/aset.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ AllocSetFreeIndex(Size size)
289289
* or equivalently
290290
*pg_leftmost_one_pos32(size - 1) - ALLOC_MINBITS + 1
291291
*
292-
* However,rather than just calling that function, we duplicate the
292+
* However,for platforms without intrinsic support, we duplicate the
293293
* logic here, allowing an additional optimization. It's reasonable
294294
* to assume that ALLOC_CHUNK_LIMIT fits in 16 bits, so we can unroll
295295
* the byte-at-a-time loop in pg_leftmost_one_pos32 and just handle
@@ -299,8 +299,8 @@ AllocSetFreeIndex(Size size)
299299
* much trouble.
300300
*----------
301301
*/
302-
#ifdefHAVE__BUILTIN_CLZ
303-
idx=31-__builtin_clz((uint32)size-1)-ALLOC_MINBITS+1;
302+
#ifdefHAVE_BITSCAN_REVERSE
303+
idx=pg_leftmost_one_pos32((uint32)size-1)-ALLOC_MINBITS+1;
304304
#else
305305
uint32t,
306306
tsize;

‎src/include/port/pg_bitutils.h

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@
1313
#ifndefPG_BITUTILS_H
1414
#definePG_BITUTILS_H
1515

16+
#ifdef_MSC_VER
17+
#include<intrin.h>
18+
#defineHAVE_BITSCAN_FORWARD
19+
#defineHAVE_BITSCAN_REVERSE
20+
21+
#else
22+
#if defined(HAVE__BUILTIN_CTZ)
23+
#defineHAVE_BITSCAN_FORWARD
24+
#endif
25+
26+
#if defined(HAVE__BUILTIN_CLZ)
27+
#defineHAVE_BITSCAN_REVERSE
28+
#endif
29+
#endif/* _MSC_VER */
30+
1631
externPGDLLIMPORTconstuint8pg_leftmost_one_pos[256];
1732
externPGDLLIMPORTconstuint8pg_rightmost_one_pos[256];
1833
externPGDLLIMPORTconstuint8pg_number_of_ones[256];
@@ -27,9 +42,12 @@ pg_leftmost_one_pos32(uint32 word)
2742
{
2843
#ifdefHAVE__BUILTIN_CLZ
2944
intbitscan_result;
45+
#elif defined(_MSC_VER)
46+
unsigned longbitscan_result;
47+
boolnon_zero;
3048
#endif
3149

32-
#if !defined(HAVE__BUILTIN_CLZ)|| defined(USE_ASSERT_CHECKING)
50+
#if !defined(HAVE_BITSCAN_REVERSE)|| defined(USE_ASSERT_CHECKING)
3351
intresult;
3452
intshift=32-8;
3553

@@ -41,13 +59,20 @@ pg_leftmost_one_pos32(uint32 word)
4159
result=shift+pg_leftmost_one_pos[(word >>shift)&255];
4260
#endif
4361

62+
#ifdefHAVE_BITSCAN_REVERSE
63+
4464
#if defined(HAVE__BUILTIN_CLZ)
4565
bitscan_result=31-__builtin_clz(word);
66+
#elif defined(_MSC_VER)
67+
non_zero=_BitScanReverse(&bitscan_result,word);
68+
Assert(non_zero);
69+
#endif
4670
Assert(bitscan_result==result);
4771
returnbitscan_result;
72+
4873
#else
4974
returnresult;
50-
#endif/*HAVE__BUILTIN_CLZ */
75+
#endif/*HAVE_BITSCAN_REVERSE */
5176
}
5277

5378
/*
@@ -59,9 +84,12 @@ pg_leftmost_one_pos64(uint64 word)
5984
{
6085
#ifdefHAVE__BUILTIN_CLZ
6186
intbitscan_result;
87+
#elif defined(_MSC_VER)
88+
unsigned longbitscan_result;
89+
boolnon_zero;
6290
#endif
6391

64-
#if !defined(HAVE__BUILTIN_CLZ)|| defined(USE_ASSERT_CHECKING)
92+
#if !defined(HAVE_BITSCAN_REVERSE)|| defined(USE_ASSERT_CHECKING)
6593
intresult;
6694
intshift=64-8;
6795

@@ -73,6 +101,8 @@ pg_leftmost_one_pos64(uint64 word)
73101
result=shift+pg_leftmost_one_pos[(word >>shift)&255];
74102
#endif
75103

104+
#ifdefHAVE_BITSCAN_REVERSE
105+
76106
#if defined(HAVE__BUILTIN_CLZ)
77107
#if defined(HAVE_LONG_INT_64)
78108
bitscan_result=63-__builtin_clzl(word);
@@ -81,11 +111,17 @@ pg_leftmost_one_pos64(uint64 word)
81111
#else
82112
#error must have a working 64-bit integer datatype
83113
#endif/* HAVE_LONG_INT_64 */
114+
115+
#elif defined(_MSC_VER)
116+
non_zero=_BitScanReverse64(&bitscan_result,word);
117+
Assert(non_zero);
118+
#endif/* HAVE__BUILTIN_CLZ */
84119
Assert(bitscan_result==result);
85120
returnbitscan_result;
121+
86122
#else
87123
returnresult;
88-
#endif/*HAVE__BUILTIN_CLZ */
124+
#endif/*HAVE_BITSCAN_REVERSE */
89125
}
90126

91127
/*
@@ -99,9 +135,13 @@ pg_rightmost_one_pos32(uint32 word)
99135
#ifdefHAVE__BUILTIN_CTZ
100136
constuint32orig_word=word;
101137
intbitscan_result;
138+
#elif defined(_MSC_VER)
139+
constunsigned longorig_word=word;
140+
unsigned longbitscan_result;
141+
boolnon_zero;
102142
#endif
103143

104-
#if !defined(HAVE__BUILTIN_CTZ)|| defined(USE_ASSERT_CHECKING)
144+
#if !defined(HAVE_BITSCAN_FORWARD)|| defined(USE_ASSERT_CHECKING)
105145
intresult=0;
106146

107147
Assert(word!=0);
@@ -114,13 +154,20 @@ pg_rightmost_one_pos32(uint32 word)
114154
result+=pg_rightmost_one_pos[word&255];
115155
#endif
116156

157+
#ifdefHAVE_BITSCAN_FORWARD
158+
117159
#if defined(HAVE__BUILTIN_CTZ)
118160
bitscan_result=__builtin_ctz(orig_word);
161+
#elif defined(_MSC_VER)
162+
non_zero=_BitScanForward(&bitscan_result,orig_word);
163+
Assert(non_zero);
164+
#endif
119165
Assert(bitscan_result==result);
120166
returnbitscan_result;
167+
121168
#else
122169
returnresult;
123-
#endif/*HAVE__BUILTIN_CTZ */
170+
#endif/*HAVE_BITSCAN_FORWARD */
124171
}
125172

126173
/*
@@ -133,9 +180,13 @@ pg_rightmost_one_pos64(uint64 word)
133180
#ifdefHAVE__BUILTIN_CTZ
134181
constuint64orig_word=word;
135182
intbitscan_result;
183+
#elif defined(_MSC_VER)
184+
constunsigned__int64orig_word=word;
185+
unsigned longbitscan_result;
186+
boolnon_zero;
136187
#endif
137188

138-
#if !defined(HAVE__BUILTIN_CTZ)|| defined(USE_ASSERT_CHECKING)
189+
#if !defined(HAVE_BITSCAN_FORWARD)|| defined(USE_ASSERT_CHECKING)
139190
intresult=0;
140191

141192
Assert(word!=0);
@@ -148,6 +199,8 @@ pg_rightmost_one_pos64(uint64 word)
148199
result+=pg_rightmost_one_pos[word&255];
149200
#endif
150201

202+
#ifdefHAVE_BITSCAN_FORWARD
203+
151204
#if defined(HAVE__BUILTIN_CTZ)
152205
#if defined(HAVE_LONG_INT_64)
153206
bitscan_result=__builtin_ctzl(orig_word);
@@ -156,11 +209,17 @@ pg_rightmost_one_pos64(uint64 word)
156209
#else
157210
#error must have a working 64-bit integer datatype
158211
#endif/* HAVE_LONG_INT_64 */
212+
213+
#elif defined(_MSC_VER)
214+
non_zero=_BitScanForward64(&bitscan_result,orig_word);
215+
Assert(non_zero);
216+
#endif/* HAVE__BUILTIN_CTZ */
159217
Assert(bitscan_result==result);
160218
returnbitscan_result;
219+
161220
#else
162221
returnresult;
163-
#endif/*HAVE__BUILTIN_CTZ */
222+
#endif/*HAVE_BITSCAN_FORWARD */
164223
}
165224

166225
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp