mirror of
https://github.com/google/benchmark.git
synced 2025-03-13 10:40:11 +08:00
Deprecate constant reference API to DoNotOptimize. (#1493)
The compiler assume that a constant reference, even though escaped via asm
volatile, is unchanged. The const-ref interface is deprecated to discourage
new uses of it, as subtle compiler optimizations (invariant hoisting, etc.) can
occur.
Within microbenchmarks for Abseil's hashtables, BM_FindMiss_Hot
(c0eaa90671/fleetbench/swissmap/hot_swissmap_benchmark.cc (L48)
)
has a `const uint32_t key` is passed to to the lookup of a hashtable.
With the `key` marked `const`, LLVM hoists part of the lookup
calculation outside of the loop.
With the `const` removed, this hoisting does not occur.
Co-authored-by: Dominic Hamon <dominichamon@users.noreply.github.com>
Co-authored-by: dominic <510002+dmah42@users.noreply.github.com>
This commit is contained in:
parent
94083ca441
commit
53df805dc8
@ -435,6 +435,9 @@ inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
||||
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
|
||||
#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
|
||||
template <class Tp>
|
||||
BENCHMARK_DEPRECATED_MSG(
|
||||
"The const-ref version of this method can permit "
|
||||
"undesired compiler optimizations in benchmarks")
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||
asm volatile("" : : "r,m"(value) : "memory");
|
||||
}
|
||||
@ -451,6 +454,9 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
|
||||
// Workaround for a bug with full argument copy overhead with GCC.
|
||||
// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519
|
||||
template <class Tp>
|
||||
BENCHMARK_DEPRECATED_MSG(
|
||||
"The const-ref version of this method can permit "
|
||||
"undesired compiler optimizations in benchmarks")
|
||||
inline BENCHMARK_ALWAYS_INLINE
|
||||
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
|
||||
(sizeof(Tp) <= sizeof(Tp*))>::type
|
||||
@ -459,6 +465,9 @@ inline BENCHMARK_ALWAYS_INLINE
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
BENCHMARK_DEPRECATED_MSG(
|
||||
"The const-ref version of this method can permit "
|
||||
"undesired compiler optimizations in benchmarks")
|
||||
inline BENCHMARK_ALWAYS_INLINE
|
||||
typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
|
||||
(sizeof(Tp) > sizeof(Tp*))>::type
|
||||
@ -487,6 +496,9 @@ inline BENCHMARK_ALWAYS_INLINE
|
||||
// to use memory operations instead of operations with registers.
|
||||
// TODO: Remove if GCC < 5 will be unsupported.
|
||||
template <class Tp>
|
||||
BENCHMARK_DEPRECATED_MSG(
|
||||
"The const-ref version of this method can permit "
|
||||
"undesired compiler optimizations in benchmarks")
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||
asm volatile("" : : "m"(value) : "memory");
|
||||
}
|
||||
@ -504,6 +516,9 @@ inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
template <class Tp>
|
||||
BENCHMARK_DEPRECATED_MSG(
|
||||
"The const-ref version of this method can permit "
|
||||
"undesired compiler optimizations in benchmarks")
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||
_ReadWriteBarrier();
|
||||
@ -514,6 +529,9 @@ inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); }
|
||||
#endif
|
||||
#else
|
||||
template <class Tp>
|
||||
BENCHMARK_DEPRECATED_MSG(
|
||||
"The const-ref version of this method can permit "
|
||||
"undesired compiler optimizations in benchmarks")
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user