Commit c27ab068 by Abseil Team Committed by Andy Getz

Export of internal Abseil changes

--
3d018c03a34bf273a4b24b3584ed77f0a6d21686 by Abseil Team <absl-team@google.com>:

Fix a spelling typo (s/boundries/boundaries).

PiperOrigin-RevId: 442041877
Change-Id: I608020697d37b85316bb9a0838e4b457659c926c

--
518b8119e51db24ce7fb0fd2fe537ec43825c3e6 by Dino Radakovic <dinor@google.com>:

absl/types/internal/variant: Make include guard uppercase

https://google.github.io/styleguide/cppguide.html#The__define_Guard

PiperOrigin-RevId: 441911692
Change-Id: I9837dd07f20204d8253f20627b0917a34dc21825

--
b91696c38310a7cae8c1ea9e2d479495f5dc3f69 by Greg Falcon <gfalcon@google.com>:

Add an internal-only API to wrap __builtin_prefetch() if available.

This private API is intended for future use by the Abseil implementation.  Like any internal-namespaced function, it may be changed or removed at any time.

PiperOrigin-RevId: 441894616
Change-Id: Iaa48bd4680b373f4a0d5afab0cb35e2a1908595f

--
0f01e8b0551a662e02dff60840c54320f987315f by Derek Mauro <dmauro@google.com>:

C++20: Use the standard `constinit` keyword for `ABSL_CONST_INIT` when available

PiperOrigin-RevId: 441778874
Change-Id: I70c616469752ff23b326b1c615437599f42cc6aa
GitOrigin-RevId: 3d018c03a34bf273a4b24b3584ed77f0a6d21686
parent 8c6e53ef
...@@ -26,6 +26,7 @@ set(ABSL_INTERNAL_DLL_FILES ...@@ -26,6 +26,7 @@ set(ABSL_INTERNAL_DLL_FILES
"base/internal/low_level_alloc.h" "base/internal/low_level_alloc.h"
"base/internal/low_level_scheduling.h" "base/internal/low_level_scheduling.h"
"base/internal/per_thread_tls.h" "base/internal/per_thread_tls.h"
"base/internal/prefetch.h"
"base/internal/pretty_function.h" "base/internal/pretty_function.h"
"base/internal/raw_logging.cc" "base/internal/raw_logging.cc"
"base/internal/raw_logging.h" "base/internal/raw_logging.h"
......
...@@ -704,6 +704,31 @@ cc_test( ...@@ -704,6 +704,31 @@ cc_test(
], ],
) )
cc_library(
name = "prefetch",
hdrs = ["internal/prefetch.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
],
)
cc_test(
name = "prefetch_test",
size = "small",
srcs = ["internal/prefetch_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":prefetch",
"@com_google_googletest//:gtest_main",
],
)
cc_test( cc_test(
name = "unique_small_name_test", name = "unique_small_name_test",
size = "small", size = "small",
......
...@@ -642,6 +642,32 @@ absl_cc_test( ...@@ -642,6 +642,32 @@ absl_cc_test(
GTest::gtest_main GTest::gtest_main
) )
# Internal-only target, do not depend on directly.
absl_cc_library(
NAME
prefetch
HDRS
"internal/prefetch.h"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
)
absl_cc_test(
NAME
prefetch_test
SRCS
"internal/prefetch_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::prefetch
GTest::gtest_main
)
absl_cc_test( absl_cc_test(
NAME NAME
optimization_test optimization_test
......
...@@ -682,9 +682,18 @@ ...@@ -682,9 +682,18 @@
// not compile (on supported platforms) unless the variable has a constant // not compile (on supported platforms) unless the variable has a constant
// initializer. This is useful for variables with static and thread storage // initializer. This is useful for variables with static and thread storage
// duration, because it guarantees that they will not suffer from the so-called // duration, because it guarantees that they will not suffer from the so-called
// "static init order fiasco". Prefer to put this attribute on the most visible // "static init order fiasco".
// declaration of the variable, if there's more than one, because code that //
// accesses the variable can then use the attribute for optimization. // This attribute must be placed on the initializing declaration of the
// variable. Some compilers will give a -Wmissing-constinit warning when this
// attribute is placed on some other declaration but missing from the
// initializing declaration.
//
// In some cases (notably with thread_local variables), `ABSL_CONST_INIT` can
// also be used in a non-initializing declaration to tell the compiler that a
// variable is already initialized, reducing overhead that would otherwise be
// incurred by a hidden guard variable. Thus annotating all declarations with
// this attribute is recommended to potentially enhance optimization.
// //
// Example: // Example:
// //
...@@ -693,14 +702,19 @@ ...@@ -693,14 +702,19 @@
// ABSL_CONST_INIT static MyType my_var; // ABSL_CONST_INIT static MyType my_var;
// }; // };
// //
// MyType MyClass::my_var = MakeMyType(...); // ABSL_CONST_INIT MyType MyClass::my_var = MakeMyType(...);
//
// For code or headers that are assured to only build with C++20 and up, prefer
// just using the standard `constinit` keyword directly over this macro.
// //
// Note that this attribute is redundant if the variable is declared constexpr. // Note that this attribute is redundant if the variable is declared constexpr.
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) #if defined(__cpp_constinit) && __cpp_constinit >= 201907L
#define ABSL_CONST_INIT constinit
#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization)
#define ABSL_CONST_INIT [[clang::require_constant_initialization]] #define ABSL_CONST_INIT [[clang::require_constant_initialization]]
#else #else
#define ABSL_CONST_INIT #define ABSL_CONST_INIT
#endif // ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) #endif
// ABSL_ATTRIBUTE_PURE_FUNCTION // ABSL_ATTRIBUTE_PURE_FUNCTION
// //
......
// Copyright 2022 The Abseil Authors.
//
// 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
//
// https://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.
#ifndef ABSL_BASE_INTERNAL_PREFETCH_H_
#define ABSL_BASE_INTERNAL_PREFETCH_H_
#include "absl/base/config.h"
// Compatibility wrappers around __builtin_prefetch, to prefetch data
// for read if supported by the toolchain.
// Move data into the cache before it is read, or "prefetch" it.
//
// The value of `addr` is the address of the memory to prefetch. If
// the target and compiler support it, data prefetch instructions are
// generated. If the prefetch is done some time before the memory is
// read, it may be in the cache by the time the read occurs.
//
// The function names specify the temporal locality heuristic applied,
// using the names of Intel prefetch instructions:
//
// T0 - high degree of temporal locality; data should be left in as
// many levels of the cache possible
// T1 - moderate degree of temporal locality
// T2 - low degree of temporal locality
// Nta - no temporal locality, data need not be left in the cache
// after the read
//
// Incorrect or gratuitous use of these functions can degrade
// performance, so use them only when representative benchmarks show
// an improvement.
//
// Example usage:
//
// absl::base_internal::PrefetchT0(addr);
//
// Currently, the different prefetch calls behave on some Intel
// architectures as follows:
//
// SNB..SKL SKX
// PrefetchT0() L1/L2/L3 L1/L2
// PrefetchT1() L2/L3 L2
// PrefetchT2() L2/L3 L2
// PrefetchNta() L1/--/L3 L1*
//
// * On SKX PrefetchNta() will bring the line into L1 but will evict
// from L3 cache. This might result in surprising behavior.
//
// SNB = Sandy Bridge, SKL = Skylake, SKX = Skylake Xeon.
//
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
void PrefetchT0(const void* addr);
void PrefetchT1(const void* addr);
void PrefetchT2(const void* addr);
void PrefetchNta(const void* addr);
// Implementation details follow.
#if ABSL_HAVE_BUILTIN(__builtin_prefetch) || defined(__GNUC__)
// See __builtin_prefetch:
// https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
//
// These functions speculatively load for read only. This is
// safe for all currently supported platforms. However, prefetch for
// store may have problems depending on the target platform.
//
inline void PrefetchT0(const void* addr) {
// Note: this uses prefetcht0 on Intel.
__builtin_prefetch(addr, 0, 3);
}
inline void PrefetchT1(const void* addr) {
// Note: this uses prefetcht1 on Intel.
__builtin_prefetch(addr, 0, 2);
}
inline void PrefetchT2(const void* addr) {
// Note: this uses prefetcht2 on Intel.
__builtin_prefetch(addr, 0, 1);
}
inline void PrefetchNta(const void* addr) {
// Note: this uses prefetchtnta on Intel.
__builtin_prefetch(addr, 0, 0);
}
#else
inline void PrefetchT0(const void*) {}
inline void PrefetchT1(const void*) {}
inline void PrefetchT2(const void*) {}
inline void PrefetchNta(const void*) {}
#endif
} // namespace base_internal
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_BASE_INTERNAL_PREFETCH_H_
// Copyright 2022 The Abseil Authors.
//
// 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
//
// https://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 "absl/base/internal/prefetch.h"
#include "gtest/gtest.h"
namespace {
int number = 42;
TEST(Prefetch, TemporalLocalityNone) {
absl::base_internal::PrefetchNta(&number);
EXPECT_EQ(number, 42);
}
TEST(Prefetch, TemporalLocalityLow) {
absl::base_internal::PrefetchT2(&number);
EXPECT_EQ(number, 42);
}
TEST(Prefetch, TemporalLocalityMedium) {
absl::base_internal::PrefetchT1(&number);
EXPECT_EQ(number, 42);
}
TEST(Prefetch, TemporalLocalityHigh) {
absl::base_internal::PrefetchT0(&number);
EXPECT_EQ(number, 42);
}
} // namespace
...@@ -76,7 +76,7 @@ struct FlatHashMapPolicy; ...@@ -76,7 +76,7 @@ struct FlatHashMapPolicy;
// absl/hash/hash.h for information on extending Abseil hashing to user-defined // absl/hash/hash.h for information on extending Abseil hashing to user-defined
// types. // types.
// //
// Using `absl::flat_hash_map` at interface boundries in dynamically loaded // Using `absl::flat_hash_map` at interface boundaries in dynamically loaded
// libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may // libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may
// be randomized across dynamically loaded libraries. // be randomized across dynamically loaded libraries.
// //
......
...@@ -72,7 +72,7 @@ struct FlatHashSetPolicy; ...@@ -72,7 +72,7 @@ struct FlatHashSetPolicy;
// absl/hash/hash.h for information on extending Abseil hashing to user-defined // absl/hash/hash.h for information on extending Abseil hashing to user-defined
// types. // types.
// //
// Using `absl::flat_hash_set` at interface boundries in dynamically loaded // Using `absl::flat_hash_set` at interface boundaries in dynamically loaded
// libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may // libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may
// be randomized across dynamically loaded libraries. // be randomized across dynamically loaded libraries.
// //
......
...@@ -78,7 +78,7 @@ class NodeHashMapPolicy; ...@@ -78,7 +78,7 @@ class NodeHashMapPolicy;
// absl/hash/hash.h for information on extending Abseil hashing to user-defined // absl/hash/hash.h for information on extending Abseil hashing to user-defined
// types. // types.
// //
// Using `absl::node_hash_map` at interface boundries in dynamically loaded // Using `absl::node_hash_map` at interface boundaries in dynamically loaded
// libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may // libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may
// be randomized across dynamically loaded libraries. // be randomized across dynamically loaded libraries.
// //
......
...@@ -74,7 +74,7 @@ struct NodeHashSetPolicy; ...@@ -74,7 +74,7 @@ struct NodeHashSetPolicy;
// absl/hash/hash.h for information on extending Abseil hashing to user-defined // absl/hash/hash.h for information on extending Abseil hashing to user-defined
// types. // types.
// //
// Using `absl::node_hash_set` at interface boundries in dynamically loaded // Using `absl::node_hash_set` at interface boundaries in dynamically loaded
// libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may // libraries (e.g. .dll, .so) is unsupported due to way `absl::Hash` values may
// be randomized across dynamically loaded libraries. // be randomized across dynamically loaded libraries.
// //
......
...@@ -69,7 +69,9 @@ ABSL_CONST_INIT ...@@ -69,7 +69,9 @@ ABSL_CONST_INIT
std::atomic<const void *> VDSOSupport::vdso_base_( std::atomic<const void *> VDSOSupport::vdso_base_(
debugging_internal::ElfMemImage::kInvalidBase); debugging_internal::ElfMemImage::kInvalidBase);
std::atomic<VDSOSupport::GetCpuFn> VDSOSupport::getcpu_fn_(&InitAndGetCPU); ABSL_CONST_INIT std::atomic<VDSOSupport::GetCpuFn> VDSOSupport::getcpu_fn_(
&InitAndGetCPU);
VDSOSupport::VDSOSupport() VDSOSupport::VDSOSupport()
// If vdso_base_ is still set to kInvalidBase, we got here // If vdso_base_ is still set to kInvalidBase, we got here
// before VDSOSupport::Init has been called. Call it now. // before VDSOSupport::Init has been called. Call it now.
......
...@@ -411,7 +411,8 @@ struct ConstInitExternalStorage { ...@@ -411,7 +411,8 @@ struct ConstInitExternalStorage {
}; };
template <typename Str> template <typename Str>
CordRepExternal ConstInitExternalStorage<Str>::value(Str::value); ABSL_CONST_INIT CordRepExternal
ConstInitExternalStorage<Str>::value(Str::value);
enum { enum {
kMaxInline = 15, kMaxInline = 15,
......
...@@ -21,7 +21,7 @@ namespace absl { ...@@ -21,7 +21,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
namespace strings_internal { namespace strings_internal {
const char kBase64Chars[] = ABSL_CONST_INIT const char kBase64Chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) {
......
...@@ -757,8 +757,8 @@ struct LookupTables { ...@@ -757,8 +757,8 @@ struct LookupTables {
// //
// uint128& operator/=(uint128) is not constexpr, so hardcode the resulting // uint128& operator/=(uint128) is not constexpr, so hardcode the resulting
// array to avoid a static initializer. // array to avoid a static initializer.
template<> template <>
const uint128 LookupTables<uint128>::kVmaxOverBase[] = { ABSL_CONST_INIT const uint128 LookupTables<uint128>::kVmaxOverBase[] = {
0, 0,
0, 0,
MakeUint128(9223372036854775807u, 18446744073709551615u), MakeUint128(9223372036854775807u, 18446744073709551615u),
...@@ -809,8 +809,8 @@ const uint128 LookupTables<uint128>::kVmaxOverBase[] = { ...@@ -809,8 +809,8 @@ const uint128 LookupTables<uint128>::kVmaxOverBase[] = {
// //
// int128& operator/=(int128) is not constexpr, so hardcode the resulting array // int128& operator/=(int128) is not constexpr, so hardcode the resulting array
// to avoid a static initializer. // to avoid a static initializer.
template<> template <>
const int128 LookupTables<int128>::kVmaxOverBase[] = { ABSL_CONST_INIT const int128 LookupTables<int128>::kVmaxOverBase[] = {
0, 0,
0, 0,
MakeInt128(4611686018427387903, 18446744073709551615u), MakeInt128(4611686018427387903, 18446744073709551615u),
...@@ -862,8 +862,8 @@ const int128 LookupTables<int128>::kVmaxOverBase[] = { ...@@ -862,8 +862,8 @@ const int128 LookupTables<int128>::kVmaxOverBase[] = {
// //
// int128& operator/=(int128) is not constexpr, so hardcode the resulting array // int128& operator/=(int128) is not constexpr, so hardcode the resulting array
// to avoid a static initializer. // to avoid a static initializer.
template<> template <>
const int128 LookupTables<int128>::kVminOverBase[] = { ABSL_CONST_INIT const int128 LookupTables<int128>::kVminOverBase[] = {
0, 0,
0, 0,
MakeInt128(-4611686018427387904, 0u), MakeInt128(-4611686018427387904, 0u),
...@@ -904,11 +904,11 @@ const int128 LookupTables<int128>::kVminOverBase[] = { ...@@ -904,11 +904,11 @@ const int128 LookupTables<int128>::kVminOverBase[] = {
}; };
template <typename IntType> template <typename IntType>
const IntType LookupTables<IntType>::kVmaxOverBase[] = ABSL_CONST_INIT const IntType LookupTables<IntType>::kVmaxOverBase[] =
X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::max()); X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::max());
template <typename IntType> template <typename IntType>
const IntType LookupTables<IntType>::kVminOverBase[] = ABSL_CONST_INIT const IntType LookupTables<IntType>::kVminOverBase[] =
X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::min()); X_OVER_BASE_INITIALIZER(std::numeric_limits<IntType>::min());
#undef X_OVER_BASE_INITIALIZER #undef X_OVER_BASE_INITIALIZER
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
// separate file to avoid cluttering the top of the API header with // separate file to avoid cluttering the top of the API header with
// implementation details. // implementation details.
#ifndef ABSL_TYPES_variant_internal_H_ #ifndef ABSL_TYPES_VARIANT_INTERNAL_H_
#define ABSL_TYPES_variant_internal_H_ #define ABSL_TYPES_VARIANT_INTERNAL_H_
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
...@@ -1643,4 +1643,4 @@ ABSL_NAMESPACE_END ...@@ -1643,4 +1643,4 @@ ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
#endif // !defined(ABSL_USES_STD_VARIANT) #endif // !defined(ABSL_USES_STD_VARIANT)
#endif // ABSL_TYPES_variant_internal_H_ #endif // ABSL_TYPES_VARIANT_INTERNAL_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment