Switch Bits.h to just use the popcount builtins directly
authorChristopher Dykes <cdykes@fb.com>
Mon, 5 Jun 2017 23:38:24 +0000 (16:38 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Mon, 5 Jun 2017 23:38:55 +0000 (16:38 -0700)
Summary:
These builtins are available on all platforms under GCC, using the instruction directly when available and a fallback implementation otherwise.
They are implemented in the builtins portability header for MSVC.

Reviewed By: yfeldblum

Differential Revision: D5185106

fbshipit-source-id: a58305a6b99eb49bd165876a4a60c512a259b225

folly/Bits.cpp [deleted file]
folly/Bits.h
folly/Makefile.am
folly/detail/BitsDetail.h [deleted file]

diff --git a/folly/Bits.cpp b/folly/Bits.cpp
deleted file mode 100644 (file)
index 5b61d47..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2017 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <folly/Bits.h>
-
-#include <folly/CpuId.h>
-#include <folly/Portability.h>
-
-// None of this is necessary if we're compiling for a target that supports
-// 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 popcountll_inst(unsigned long long x) {
-  unsigned long long n;
-  asm ("popcntq %1, %0" : "=r" (n) : "r" (x));
-  return n;
-}
-
-typedef decltype(popcount_builtin) Type_popcount;
-typedef decltype(popcountll_builtin) Type_popcountll;
-
-// 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;
-}
-
-// This function is called on startup to resolve folly::detail::popcountll
-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)
-#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)
-#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__ */
index b818655..ade5bbe 100644 (file)
@@ -66,7 +66,6 @@
 #include <folly/portability/Builtins.h>
 
 #include <folly/Assume.h>
-#include <folly/detail/BitsDetail.h>
 #include <folly/detail/BitIteratorDetail.h>
 #include <folly/Likely.h>
 
@@ -214,7 +213,7 @@ inline typename std::enable_if<
    sizeof(T) <= sizeof(unsigned int)),
   size_t>::type
   popcount(T x) {
-  return size_t(detail::popcount(x));
+  return size_t(__builtin_popcount(x));
 }
 
 template <class T>
@@ -225,7 +224,7 @@ inline typename std::enable_if<
    sizeof(T) <= sizeof(unsigned long long)),
   size_t>::type
   popcount(T x) {
-  return size_t(detail::popcountll(x));
+  return size_t(__builtin_popcountll(x));
 }
 
 /**
index 8a15e9a..6d46439 100644 (file)
@@ -63,7 +63,6 @@ nobase_follyinclude_HEADERS = \
        detail/AtomicUnorderedMapUtils.h \
        detail/AtomicUtils.h \
        detail/BitIteratorDetail.h \
-       detail/BitsDetail.h \
        detail/CacheLocality.h \
        detail/CachelinePaddedImpl.h \
        detail/ChecksumDetail.h \
@@ -440,7 +439,6 @@ libfollybase_la_SOURCES = \
 
 libfolly_la_SOURCES = \
        Assume.cpp \
-       Bits.cpp \
        Checksum.cpp \
        ClockGettimeWrappers.cpp \
        detail/CacheLocality.cpp \
diff --git a/folly/detail/BitsDetail.h b/folly/detail/BitsDetail.h
deleted file mode 100644 (file)
index d693ff9..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace folly {
-namespace detail {
-
-// If we're targeting an architecture with popcnt support, use
-// __builtin_popcount directly, as it's presumably inlined.
-// If not, use runtime detection using __attribute__((__ifunc__))
-// (see Bits.cpp)
-#ifdef _MSC_VER
-inline int popcount(unsigned int x) {
-  return int(__popcnt(x));
-}
-inline int popcountll(unsigned long long x) {
-  return int(__popcnt64(x));
-}
-#elif defined(__POPCNT__)
-
-inline int popcount(unsigned int x) {
-  return __builtin_popcount(x);
-}
-inline int popcountll(unsigned long long x) {
-  return __builtin_popcountll(x);
-}
-
-#else   /* !__POPCNT__ */
-
-int popcount(unsigned int x);
-int popcountll(unsigned long long x);
-
-#endif  /* !__POPCNT__ */
-
-}  // namespace detail
-}  // namespace folly