Skip to content

Commit

Permalink
Deprecate constant reference API to DoNotOptimize.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ckennelly committed Sep 27, 2022
1 parent 49aa374 commit 1246945
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/benchmark/benchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@ 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");
}
Expand All @@ -457,6 +459,8 @@ 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
Expand All @@ -465,6 +469,8 @@ 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
Expand Down Expand Up @@ -493,6 +499,8 @@ 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");
}
Expand All @@ -510,6 +518,8 @@ 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();
Expand All @@ -520,6 +530,8 @@ 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));
}
Expand Down

0 comments on commit 1246945

Please sign in to comment.