Fix SimpleBarrier
[folly.git] / folly / Bits.cpp
index 1c825d2a1fd1c1e8060d4bcef165acc9483d926a..7571078efbdd0bf4812d96539b9b060a894add76 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#include "folly/Bits.h"
+#include <folly/Bits.h>
 
-#include "folly/CpuId.h"
+#include <folly/CpuId.h>
+#include <folly/Portability.h>
 
 // None of this is necessary if we're compiling for a target that supports
-// popcnt
-#ifndef __POPCNT__
-
+// popcnt, which includes MSVC
+#if !defined(__POPCNT__) && !defined(_MSC_VER)
 namespace {
 
+int popcount_builtin(unsigned int x) {
+  return __builtin_popcount(x);
+}
+
+int popcountll_builtin(unsigned long long x) {
+  return __builtin_popcountll(x);
+}
+
+#if FOLLY_HAVE_IFUNC && !defined(FOLLY_SANITIZE_ADDRESS)
+
+// Strictly speaking, these versions of popcount are usable without ifunc
+// support. However, we would have to check, via CpuId, if the processor
+// implements the popcnt instruction first, which is what we use ifunc for.
 int popcount_inst(unsigned int x) {
   int n;
   asm ("popcntl %1, %0" : "=r" (n) : "r" (x));
   return n;
 }
 
-int popcount_builtin(unsigned int x) {
-  return __builtin_popcount(x);
-}
-
 int popcountll_inst(unsigned long long x) {
   unsigned long long n;
   asm ("popcntq %1, %0" : "=r" (n) : "r" (x));
   return n;
 }
 
-int popcountll_builtin(unsigned long long x) {
-  return __builtin_popcountll(x);
-}
-
 typedef decltype(popcount_builtin) Type_popcount;
 typedef decltype(popcountll_builtin) Type_popcountll;
 
-}  // namespace
-
 // This function is called on startup to resolve folly::detail::popcount
 extern "C" Type_popcount* folly_popcount_ifunc() {
   return folly::CpuId().popcnt() ?  popcount_inst : popcount_builtin;
@@ -59,21 +62,32 @@ extern "C" Type_popcountll* folly_popcountll_ifunc() {
   return folly::CpuId().popcnt() ?  popcountll_inst : popcountll_builtin;
 }
 
+#endif  // FOLLY_HAVE_IFUNC && !defined(FOLLY_SANITIZE_ADDRESS)
+
+}  // namespace
+
 namespace folly {
 namespace detail {
 
 // Call folly_popcount_ifunc on startup to resolve to either popcount_inst
 // or popcount_builtin
 int popcount(unsigned int x)
-  __attribute__((ifunc("folly_popcount_ifunc")));
+#if FOLLY_HAVE_IFUNC && !defined(FOLLY_SANITIZE_ADDRESS)
+  __attribute__((__ifunc__("folly_popcount_ifunc")));
+#else
+{  return popcount_builtin(x); }
+#endif
 
 // Call folly_popcount_ifunc on startup to resolve to either popcountll_inst
 // or popcountll_builtin
 int popcountll(unsigned long long x)
-  __attribute__((ifunc("folly_popcountll_ifunc")));
+#if FOLLY_HAVE_IFUNC && !defined(FOLLY_SANITIZE_ADDRESS)
+  __attribute__((__ifunc__("folly_popcountll_ifunc")));
+#else
+{  return popcountll_builtin(x); }
+#endif
 
 }  // namespace detail
 }  // namespace folly
 
 #endif  /* !__POPCNT__ */
-