mirror of
https://github.com/google/benchmark.git
synced 2025-03-23 07:30:07 +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
|
#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
|
||||||
#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
|
#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
|
||||||
template <class Tp>
|
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) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
asm volatile("" : : "r,m"(value) : "memory");
|
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.
|
// Workaround for a bug with full argument copy overhead with GCC.
|
||||||
// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519
|
// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
|
BENCHMARK_DEPRECATED_MSG(
|
||||||
|
"The const-ref version of this method can permit "
|
||||||
|
"undesired compiler optimizations in benchmarks")
|
||||||
inline BENCHMARK_ALWAYS_INLINE
|
inline BENCHMARK_ALWAYS_INLINE
|
||||||
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
|
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
|
||||||
(sizeof(Tp) <= sizeof(Tp*))>::type
|
(sizeof(Tp) <= sizeof(Tp*))>::type
|
||||||
@ -459,6 +465,9 @@ inline BENCHMARK_ALWAYS_INLINE
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
|
BENCHMARK_DEPRECATED_MSG(
|
||||||
|
"The const-ref version of this method can permit "
|
||||||
|
"undesired compiler optimizations in benchmarks")
|
||||||
inline BENCHMARK_ALWAYS_INLINE
|
inline BENCHMARK_ALWAYS_INLINE
|
||||||
typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
|
typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
|
||||||
(sizeof(Tp) > sizeof(Tp*))>::type
|
(sizeof(Tp) > sizeof(Tp*))>::type
|
||||||
@ -487,6 +496,9 @@ inline BENCHMARK_ALWAYS_INLINE
|
|||||||
// to use memory operations instead of operations with registers.
|
// to use memory operations instead of operations with registers.
|
||||||
// TODO: Remove if GCC < 5 will be unsupported.
|
// TODO: Remove if GCC < 5 will be unsupported.
|
||||||
template <class Tp>
|
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) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
asm volatile("" : : "m"(value) : "memory");
|
asm volatile("" : : "m"(value) : "memory");
|
||||||
}
|
}
|
||||||
@ -504,6 +516,9 @@ inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
|
|||||||
#endif
|
#endif
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
template <class Tp>
|
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) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||||
_ReadWriteBarrier();
|
_ReadWriteBarrier();
|
||||||
@ -514,6 +529,9 @@ inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); }
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
template <class Tp>
|
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) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user