Use bitwise test instead of popcount to check if one bit is set
authorMichael Forney <mforney@mforney.org>
Tue, 4 Jun 2019 21:01:02 +0000 (14:01 -0700)
committerMichael Forney <mforney@mforney.org>
Mon, 10 Jun 2019 18:15:55 +0000 (11:15 -0700)
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>
configure.ac
meson.build
src/state.c
src/utils.h

index 957da59..cd958b0 100644 (file)
@@ -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])
index 6f0b596..61ba681 100644 (file)
@@ -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
index 16a4caa..4b601b7 100644 (file)
@@ -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;
index cb98e8e..d823e74 100644 (file)
@@ -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