From f1eb3c506a6510dd1101da0d071ef4a41650f70a Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Mon, 5 Jun 2017 16:38:24 -0700 Subject: [PATCH] Switch Bits.h to just use the popcount builtins directly 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 | 93 --------------------------------------- folly/Bits.h | 5 +-- folly/Makefile.am | 2 - folly/detail/BitsDetail.h | 50 --------------------- 4 files changed, 2 insertions(+), 148 deletions(-) delete mode 100644 folly/Bits.cpp delete mode 100644 folly/detail/BitsDetail.h diff --git a/folly/Bits.cpp b/folly/Bits.cpp deleted file mode 100644 index 5b61d470..00000000 --- a/folly/Bits.cpp +++ /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 - -#include -#include - -// 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__ */ diff --git a/folly/Bits.h b/folly/Bits.h index b818655e..ade5bbee 100644 --- a/folly/Bits.h +++ b/folly/Bits.h @@ -66,7 +66,6 @@ #include #include -#include #include #include @@ -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 @@ -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)); } /** diff --git a/folly/Makefile.am b/folly/Makefile.am index 8a15e9a4..6d46439c 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -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 index d693ff95..00000000 --- a/folly/detail/BitsDetail.h +++ /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 -- 2.34.1