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>
master
Michael Forney 2019-06-04 14:01:02 -07:00
parent db7e79e78d
commit 9d58bbd4ff
4 changed files with 3 additions and 15 deletions

View 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])

View 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

View 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;

View 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