Handle non-Intel platforms in Range and CpuId
authorOwen Yamauchi <oyamauchi@fb.com>
Thu, 21 Mar 2013 14:32:47 +0000 (07:32 -0700)
committerOwen Yamauchi <oyamauchi@fb.com>
Wed, 27 Mar 2013 21:40:58 +0000 (14:40 -0700)
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

folly/CpuId.h
folly/Range.cpp
folly/Range.h
folly/configure.ac

index f11637c0e192bc4648b55a428ec22ad037746be3..ab4eb27ff48c763e5834a8250437238f7d342c9c 100644 (file)
@@ -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)
index cf0ba535713003046ee13d97858e4ca420300cd4..2796cd470854df789e31e734f90a4668dfed55fc 100644 (file)
@@ -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 <bool HAYSTACK_ALIGNED>
 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) {
index a65cab62ab76b5e4c9f64129f15c069e886d468e..a56caa74014e5372890d3b4fc35413ef4a462444 100644 (file)
@@ -578,10 +578,11 @@ size_t qfind(const Range<T>& 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 <class T, class Comp>
index d2b28c59c3e98858fe7765f193ad0ced1f652c48..267fae39ff46e85aa1c9d9830c131e32b0234087 100644 (file)
@@ -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 \