diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2016-02-25 23:36:50 -0800 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2016-03-03 18:24:12 -0800 |
commit | 490a25e6f8a4d2482af4364c700b68ad11a4d10b (patch) | |
tree | 87cb9f917700aa3dbcc57bfcce012473257b1491 | |
parent | 54ba591149f3a92c5a4a66e428ae2a33d1027053 (diff) | |
download | xorg-lib-libXext-490a25e6f8a4d2482af4364c700b68ad11a4d10b.tar.gz |
Use __builtin_popcountl if available to replace Ones() in XSecurity.c
If the compiler knows of a better algorithm for counting the number of
bits set in a word for the target CPU, let it use that, instead of the
classic algorithm optimized for PDP-6.
Tested for the range of values used in XSecurity.c and verified results
are the same from both:
for (unsigned long i = 0; i <= XSecurityAllAuthorizationAttributes; i++) {
printf("ones: %d\tpopcnt: %d\n", Ones(i), __builtin_popcountl(i));
}
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | m4/ax_gcc_builtin.m4 | 168 | ||||
-rw-r--r-- | src/XSecurity.c | 13 |
3 files changed, 182 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index 8efdd1f..5c241f5 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ AC_INIT([libXext], [1.3.3], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXext]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) # Initialize Automake AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -38,6 +39,8 @@ AC_SUBST(XEXT_SOREV) # Obtain compiler/linker options for depedencies PKG_CHECK_MODULES(XEXT, [xproto >= 7.0.13] [x11 >= 1.6] [xextproto >= 7.1.99]) +AX_GCC_BUILTIN([__builtin_popcountl]) + # Allow checking code with lint, sparse, etc. XORG_WITH_LINT XORG_LINT_LIBRARY([Xext]) diff --git a/m4/ax_gcc_builtin.m4 b/m4/ax_gcc_builtin.m4 new file mode 100644 index 0000000..b28a91b --- /dev/null +++ b/m4/ax_gcc_builtin.m4 @@ -0,0 +1,168 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_BUILTIN(BUILTIN) +# +# DESCRIPTION +# +# This macro checks if the compiler supports one of GCC's built-in +# functions; many other compilers also provide those same built-ins. +# +# The BUILTIN parameter is the name of the built-in function. +# +# If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since +# builtins usually start with two underscores they will be copied over +# into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for +# __builtin_expect()). +# +# The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g. +# ax_cv_have___builtin_expect). +# +# The macro currently supports the following built-in functions: +# +# __builtin_assume_aligned +# __builtin_bswap32 +# __builtin_bswap64 +# __builtin_choose_expr +# __builtin___clear_cache +# __builtin_clrsb +# __builtin_clrsbl +# __builtin_clrsbll +# __builtin_clz +# __builtin_clzl +# __builtin_clzll +# __builtin_complex +# __builtin_constant_p +# __builtin_ctz +# __builtin_ctzl +# __builtin_ctzll +# __builtin_expect +# __builtin_ffs +# __builtin_ffsl +# __builtin_ffsll +# __builtin_fpclassify +# __builtin_huge_val +# __builtin_huge_valf +# __builtin_huge_vall +# __builtin_inf +# __builtin_infd128 +# __builtin_infd32 +# __builtin_infd64 +# __builtin_inff +# __builtin_infl +# __builtin_isinf_sign +# __builtin_nan +# __builtin_nand128 +# __builtin_nand32 +# __builtin_nand64 +# __builtin_nanf +# __builtin_nanl +# __builtin_nans +# __builtin_nansf +# __builtin_nansl +# __builtin_object_size +# __builtin_parity +# __builtin_parityl +# __builtin_parityll +# __builtin_popcount +# __builtin_popcountl +# __builtin_popcountll +# __builtin_powi +# __builtin_powif +# __builtin_powil +# __builtin_prefetch +# __builtin_trap +# __builtin_types_compatible_p +# __builtin_unreachable +# +# Unsuppored built-ins will be tested with an empty parameter set and the +# result of the check might be wrong or meaningless so use with care. +# +# LICENSE +# +# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AC_DEFUN([AX_GCC_BUILTIN], [ + AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1]) + + AC_CACHE_CHECK([for $1], [ac_var], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [ + m4_case([$1], + [__builtin_assume_aligned], [$1("", 0)], + [__builtin_bswap32], [$1(0)], + [__builtin_bswap64], [$1(0)], + [__builtin_choose_expr], [$1(0, 0, 0)], + [__builtin___clear_cache], [$1("", "")], + [__builtin_clrsb], [$1(0)], + [__builtin_clrsbl], [$1(0)], + [__builtin_clrsbll], [$1(0)], + [__builtin_clz], [$1(0)], + [__builtin_clzl], [$1(0)], + [__builtin_clzll], [$1(0)], + [__builtin_complex], [$1(0.0, 0.0)], + [__builtin_constant_p], [$1(0)], + [__builtin_ctz], [$1(0)], + [__builtin_ctzl], [$1(0)], + [__builtin_ctzll], [$1(0)], + [__builtin_expect], [$1(0, 0)], + [__builtin_ffs], [$1(0)], + [__builtin_ffsl], [$1(0)], + [__builtin_ffsll], [$1(0)], + [__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)], + [__builtin_huge_val], [$1()], + [__builtin_huge_valf], [$1()], + [__builtin_huge_vall], [$1()], + [__builtin_inf], [$1()], + [__builtin_infd128], [$1()], + [__builtin_infd32], [$1()], + [__builtin_infd64], [$1()], + [__builtin_inff], [$1()], + [__builtin_infl], [$1()], + [__builtin_isinf_sign], [$1(0.0)], + [__builtin_nan], [$1("")], + [__builtin_nand128], [$1("")], + [__builtin_nand32], [$1("")], + [__builtin_nand64], [$1("")], + [__builtin_nanf], [$1("")], + [__builtin_nanl], [$1("")], + [__builtin_nans], [$1("")], + [__builtin_nansf], [$1("")], + [__builtin_nansl], [$1("")], + [__builtin_object_size], [$1("", 0)], + [__builtin_parity], [$1(0)], + [__builtin_parityl], [$1(0)], + [__builtin_parityll], [$1(0)], + [__builtin_popcount], [$1(0)], + [__builtin_popcountl], [$1(0)], + [__builtin_popcountll], [$1(0)], + [__builtin_powi], [$1(0, 0)], + [__builtin_powif], [$1(0, 0)], + [__builtin_powil], [$1(0, 0)], + [__builtin_prefetch], [$1("")], + [__builtin_trap], [$1()], + [__builtin_types_compatible_p], [$1(int, int)], + [__builtin_unreachable], [$1()], + [m4_warn([syntax], [Unsupported built-in $1, the test may fail]) + $1()] + ) + ])], + [AS_VAR_SET([ac_var], [yes])], + [AS_VAR_SET([ac_var], [no])]) + ]) + + AS_IF([test yes = AS_VAR_GET([ac_var])], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1, + [Define to 1 if the system has the `$1' built-in function])], []) + + AS_VAR_POPDEF([ac_var]) +]) diff --git a/src/XSecurity.c b/src/XSecurity.c index 3ca75b1..56b37fc 100644 --- a/src/XSecurity.c +++ b/src/XSecurity.c @@ -196,15 +196,24 @@ XSecurityFreeXauth(Xauth *auth) XFree(auth); } -static int +#ifdef HAVE___BUILTIN_POPCOUNTL +# define Ones __builtin_popcountl +#else +/* + * Count the number of bits set to 1 in a 32-bit word. + * Algorithm from MIT AI Lab Memo 239: "HAKMEM", ITEM 169. + * http://dspace.mit.edu/handle/1721.1/6086 + */ +static inline int Ones(Mask mask) { register Mask y; - y = (mask >> 1) &033333333333; + y = (mask >> 1) & 033333333333; y = mask - y - ((y >>1) & 033333333333); return (((y + (y >> 3)) & 030707070707) % 077); } +#endif Xauth * XSecurityGenerateAuthorization( |