From: Tudor Bosman Date: Wed, 8 Aug 2012 21:32:27 +0000 (-0700) Subject: Use gcc builtins instead of library functions for ffs* X-Git-Tag: v0.22.0~1221 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2d94f42770dabbf430c44f38a72faab73d041a32;p=folly.git Use gcc builtins instead of library functions for ffs* Summary: because, shockingly, glibc doesn't divert to the gcc builtins which are inlined and fast Test Plan: folly/test Reviewed By: sding@fb.com FB internal diff: D543363 --- diff --git a/folly/Bits.h b/folly/Bits.h index 4d4656d2..4649a073 100644 --- a/folly/Bits.h +++ b/folly/Bits.h @@ -69,7 +69,6 @@ #include #include #include -#include // for ffs, ffsl, ffsll #include #include #include @@ -80,57 +79,53 @@ namespace folly { // Generate overloads for findFirstSet as wrappers around -// appropriate ffs, ffsl, ffsll functions from glibc. -// We first define these overloads for signed types (because ffs, ffsl, ffsll -// take int, long, and long long as arguments, respectively) and then -// define an overload for unsigned that forwards to the overload for the -// corresponding signed type. +// appropriate ffs, ffsl, ffsll gcc builtins template typename std::enable_if< (std::is_integral::value && - std::is_signed::value && - (std::numeric_limits::digits <= std::numeric_limits::digits)), + std::is_unsigned::value && + (std::numeric_limits::digits <= + std::numeric_limits::digits)), unsigned int>::type findFirstSet(T x) { - return ::ffs(static_cast(x)); + return __builtin_ffs(x); } template typename std::enable_if< (std::is_integral::value && - std::is_signed::value && - (std::numeric_limits::digits > std::numeric_limits::digits) && - (std::numeric_limits::digits <= std::numeric_limits::digits)), + std::is_unsigned::value && + (std::numeric_limits::digits > + std::numeric_limits::digits) && + (std::numeric_limits::digits <= + std::numeric_limits::digits)), unsigned int>::type findFirstSet(T x) { - return ::ffsl(static_cast(x)); + return __builtin_ffsl(x); } -#ifdef FOLLY_HAVE_FFSLL - template typename std::enable_if< (std::is_integral::value && - std::is_signed::value && - (std::numeric_limits::digits > std::numeric_limits::digits) && - (std::numeric_limits::digits <= std::numeric_limits::digits)), + std::is_unsigned::value && + (std::numeric_limits::digits > + std::numeric_limits::digits) && + (std::numeric_limits::digits <= + std::numeric_limits::digits)), unsigned int>::type findFirstSet(T x) { - return ::ffsll(static_cast(x)); + return __builtin_ffsll(x); } -#endif - template typename std::enable_if< - (std::is_integral::value && - !std::is_signed::value), + (std::is_integral::value && std::is_signed::value), unsigned int>::type findFirstSet(T x) { - // Note that conversion from an unsigned type to the corresponding signed + // Note that conversion from a signed type to the corresponding unsigned // type is technically implementation-defined, but will likely work // on any impementation that uses two's complement. - return findFirstSet(static_cast::type>(x)); + return findFirstSet(static_cast::type>(x)); } // findLastSet: return the 1-based index of the highest bit set diff --git a/folly/configure.ac b/folly/configure.ac index 9048e5f2..ed487786 100644 --- a/folly/configure.ac +++ b/folly/configure.ac @@ -61,7 +61,6 @@ AC_CHECK_FUNCS([getdelim \ pow \ strerror \ pthread_yield \ - ffsll \ rallocm \ malloc_size \ malloc_usable_size])