Use bitwise test instead of popcount to check if one bit is set We don't need to determine the total number of bits set to determine if exactly one is set. Additionally, on x86_64 without any -march=* flag, __builtin_popcount will get compiled to a function call to the compiler runtime (on gcc), or a long sequence of bit operations (on clang). Signed-off-by: Michael Forney <mforney@mforney.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
diff --git a/configure.ac b/configure.ac
index 957da59..cd958b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,7 +77,6 @@ AS_IF([test "x$ac_cv_func_secure_getenv" = xno -a \
])
AX_GCC_BUILTIN(__builtin_expect)
-AX_GCC_BUILTIN(__builtin_popcount)
# Some tests use Linux-specific headers
AC_CHECK_HEADER([linux/input.h])
diff --git a/meson.build b/meson.build
index 6f0b596..61ba681 100644
--- a/meson.build
+++ b/meson.build
@@ -76,9 +76,6 @@ endif
if cc.links('int main(){if(__builtin_expect(1<0,0)){}}', name: '__builtin_expect')
configh_data.set('HAVE___BUILTIN_EXPECT', 1)
endif
-if cc.links('int main(){__builtin_popcount(1);}', name: '__builtin_popcount')
- configh_data.set('HAVE___BUILTIN_POPCOUNT', 1)
-endif
if cc.has_header_symbol('unistd.h', 'eaccess', prefix: '#define _GNU_SOURCE')
configh_data.set('HAVE_EACCESS', 1)
endif
diff --git a/src/state.c b/src/state.c
index 16a4caa..4b601b7 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1373,7 +1373,7 @@ key_get_consumed(struct xkb_state *state, const struct xkb_key *key,
if (XkbLevelsSameSyms(level, no_mods_level))
continue;
- if (entry == matching_entry || my_popcount(entry->mods.mask) == 1)
+ if (entry == matching_entry || one_bit_set(entry->mods.mask))
consumed |= entry->mods.mask & ~entry->preserve.mask;
}
break;
diff --git a/src/utils.h b/src/utils.h
index cb98e8e..d823e74 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -186,18 +186,10 @@ msb_pos(uint32_t mask)
return pos;
}
-// Avoid conflict with other popcount()s.
static inline int
-my_popcount(uint32_t x)
+one_bit_set(uint32_t x)
{
- int count;
-#if defined(HAVE___BUILTIN_POPCOUNT)
- count = __builtin_popcount(x);
-#else
- for (count = 0; x; count++)
- x &= x - 1;
-#endif
- return count;
+ return x && (x & (x - 1)) == 0;
}
bool