bpo-32436: Don't use native popcount() (also fixes bpo-32641) (#5292)

This commit is contained in:
Yury Selivanov 2018-01-23 22:17:04 -05:00 committed by GitHub
parent 6b273f7f40
commit b7a80d543e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 15 deletions

View file

@ -1171,7 +1171,7 @@ get_token_missing(void)
int int
PyContext_ClearFreeList(void) PyContext_ClearFreeList(void)
{ {
int size = ctx_freelist_len; Py_ssize_t size = ctx_freelist_len;
while (ctx_freelist_len) { while (ctx_freelist_len) {
PyContext *ctx = ctx_freelist; PyContext *ctx = ctx_freelist;
ctx_freelist = (PyContext *)ctx->ctx_weakreflist; ctx_freelist = (PyContext *)ctx->ctx_weakreflist;

View file

@ -4,11 +4,6 @@
#include "internal/pystate.h" #include "internal/pystate.h"
#include "internal/hamt.h" #include "internal/hamt.h"
/* popcnt support in Visual Studio */
#ifdef _MSC_VER
#include <intrin.h>
#endif
/* /*
This file provides an implemention of an immutable mapping using the This file provides an implemention of an immutable mapping using the
Hash Array Mapped Trie (or HAMT) datastructure. Hash Array Mapped Trie (or HAMT) datastructure.
@ -440,18 +435,21 @@ hamt_bitpos(int32_t hash, uint32_t shift)
static inline uint32_t static inline uint32_t
hamt_bitcount(uint32_t i) hamt_bitcount(uint32_t i)
{ {
#if defined(__GNUC__) && (__GNUC__ > 4) /* We could use native popcount instruction but that would
return (uint32_t)__builtin_popcountl(i); require to either add configure flags to enable SSE4.2
#elif defined(__clang__) && (__clang_major__ > 3) support or to detect it dynamically. Otherwise, we have
return (uint32_t)__builtin_popcountl(i); a risk of CPython not working properly on older hardware.
#elif defined(_MSC_VER)
return (uint32_t)__popcnt(i); In practice, there's no observable difference in
#else performance between using a popcount instruction or the
/* https://graphics.stanford.edu/~seander/bithacks.html */ following fallback code.
The algorithm is copied from:
https://graphics.stanford.edu/~seander/bithacks.html
*/
i = i - ((i >> 1) & 0x55555555); i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333); i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; return ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
#endif
} }
static inline uint32_t static inline uint32_t