From: Owen Yamauchi Date: Thu, 21 Mar 2013 14:32:47 +0000 (-0700) Subject: Handle non-Intel platforms in Range and CpuId X-Git-Tag: v0.22.0~1025 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=ae95c1d54ad1c3da2954673e2eb1ac24ad9d2320;p=folly.git Handle non-Intel platforms in Range and CpuId Summary: Compile out the SSE versions of these functions in Range, based on a new entry in folly-config.h. The change to CpuId feels slightly iffy to me. It seems like it would be more rigorous to make compiling CpuId.h on non-Intel an error, and force clients to handle non-Intel platforms at the callsite. However, I think that would be too susceptible to unintentional breakage on non-Intel platforms, since most people (including automated systems) aren't building and testing regularly on any. Falling back to saying "none of these features exist on this processor" seems like a reasonable alternative. Test Plan: fbmake runtests, with FOLLY_HAVE_EMMINTRIN_H set to 0 and 1. Make sure the SSE functions are getting compiled in or out as appropriate. ##autoreconf## and ##./configure## to regenerate folly-config.h. Reviewed By: delong.j@fb.com FB internal diff: D746872 --- diff --git a/folly/CpuId.h b/folly/CpuId.h index f11637c0..ab4eb27f 100644 --- a/folly/CpuId.h +++ b/folly/CpuId.h @@ -29,7 +29,14 @@ namespace folly { class CpuId { public: CpuId() { +#if defined(__x86_64__) || defined(__i386__) __asm__("cpuid" : "=c"(c_), "=d"(d_) : "a"(1) : "ebx"); +#else + // On non-Intel, none of these features exist; at least not in the same form + // as they do on Intel + c_ = 0; + d_ = 0; +#endif } #define X(name, r, bit) bool name() const { return r & (1U << bit); } #define C(name, bit) X(name, c_, bit) diff --git a/folly/Range.cpp b/folly/Range.cpp index cf0ba535..2796cd47 100644 --- a/folly/Range.cpp +++ b/folly/Range.cpp @@ -72,6 +72,7 @@ inline size_t nextAlignedIndex(const char* arr) { - firstPossible; } +#if FOLLY_HAVE_EMMINTRIN_H // build sse4.2-optimized version even if -msse4.2 is not passed to GCC size_t qfind_first_byte_of_needles16(const StringPiece& haystack, const StringPiece& needles) @@ -116,6 +117,7 @@ size_t qfind_first_byte_of_needles16(const StringPiece& haystack, } return StringPiece::npos; } +#endif // FOLLY_HAVE_EMMINTRIN_H // Aho, Hopcroft, and Ullman refer to this trick in "The Design and Analysis // of Computer Algorithms" (1974), but the best description is here: @@ -161,6 +163,8 @@ size_t qfind_first_byte_of_byteset(const StringPiece& haystack, return StringPiece::npos; } +#if FOLLY_HAVE_EMMINTRIN_H + template inline size_t scanHaystackBlock(const StringPiece& haystack, const StringPiece& needles, @@ -248,6 +252,7 @@ size_t qfind_first_byte_of_sse42(const StringPiece& haystack, return StringPiece::npos; } +#endif // FOLLY_HAVE_EMMINTRIN_H size_t qfind_first_byte_of_nosse(const StringPiece& haystack, const StringPiece& needles) { diff --git a/folly/Range.h b/folly/Range.h index a65cab62..a56caa74 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -578,10 +578,11 @@ size_t qfind(const Range& haystack, namespace detail { -size_t qfind_first_byte_of_sse42(const StringPiece& haystack, +size_t qfind_first_byte_of_nosse(const StringPiece& haystack, const StringPiece& needles); -size_t qfind_first_byte_of_nosse(const StringPiece& haystack, +#if FOLLY_HAVE_EMMINTRIN_H +size_t qfind_first_byte_of_sse42(const StringPiece& haystack, const StringPiece& needles); inline size_t qfind_first_byte_of(const StringPiece& haystack, @@ -592,6 +593,13 @@ inline size_t qfind_first_byte_of(const StringPiece& haystack, return qfind_first_byte_of_fn(haystack, needles); } +#else +inline size_t qfind_first_byte_of(const StringPiece& haystack, + const StringPiece& needles) { + return qfind_first_byte_of_nosse(haystack, needles); +} +#endif // FOLLY_HAVE_EMMINTRIN_H + } // namespace detail template diff --git a/folly/configure.ac b/folly/configure.ac index d2b28c59..267fae39 100644 --- a/folly/configure.ac +++ b/folly/configure.ac @@ -37,7 +37,7 @@ AX_BOOST_SYSTEM # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdint.h stdlib.h string.h sys/time.h unistd.h mutex.h features.h malloc.h]) +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdint.h stdlib.h string.h sys/time.h unistd.h mutex.h features.h malloc.h emmintrin.h]) AC_CHECK_HEADER(double-conversion.h, [], [AC_MSG_ERROR( [Couldn't find double-conversion.h, please download from \