Mercurial > hg > octave-lyh > gnulib-hg
changeset 15947:d1ff4390df13
ffsl: Optimize on 32-bit platforms.
* lib/ffsl.h (FUNC): If TYPE has the same representation as 'int', just
use ffs() without a loop.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Fri, 14 Oct 2011 02:11:34 +0200 |
parents | d0eb709725f5 |
children | 0098fa655711 |
files | ChangeLog lib/ffsl.h |
diffstat | 2 files changed, 31 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-10-13 Bruno Haible <bruno@clisp.org> + ffsl: Optimize on 32-bit platforms. + * lib/ffsl.h (FUNC): If TYPE has the same representation as 'int', just + use ffs() without a loop. + ffsl, ffsll: Optimize for GCC. * lib/ffsl.h (FUNC): Use GCC_BUILTIN if defined. * lib/ffsl.c (GCC_BUILTIN): New macro.
--- a/lib/ffsl.h +++ b/lib/ffsl.h @@ -34,18 +34,34 @@ #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined GCC_BUILTIN return GCC_BUILTIN (i); #else - int result = 0; - unsigned TYPE j = i; + if (sizeof (TYPE) == sizeof (int)) + return ffs (i); + else + { + unsigned TYPE j = i; + /* Split j into chunks, and look at one chunk after the other. */ + /* Define chunk_bits so as to avoid a GCC warning + "right shift count >= width of type" + if sizeof (TYPE) == sizeof (int). */ + enum + { + chunk_bits = (sizeof (TYPE) != sizeof (int) + ? CHAR_BIT * sizeof (unsigned int) + : 0) + }; + int result = 0; - /* GCC has __builtin_ffs, but it is limited to int. */ - if (!i) - return 0; - while (1) - { - if ((unsigned int) j) - return result + ffs ((unsigned int) j); - j >>= CHAR_BIT * sizeof (unsigned int); - result += CHAR_BIT * sizeof (unsigned int); + /* It is tempting to write if (!j) here, but if we do this, + Solaris 10/x86 "cc -O" miscompiles the code. */ + if (!i) + return 0; + while (1) + { + if ((unsigned int) j) + return result + ffs ((unsigned int) j); + j >>= chunk_bits; + result += chunk_bits; + } } #endif }