mirror of https://github.com/google/benchmark.git
Force DoNotOptimize operand to memory for both gcc and clang
This commit is contained in:
parent
a38f022b5a
commit
74e82e822f
1
AUTHORS
1
AUTHORS
|
@ -8,6 +8,7 @@
|
||||||
#
|
#
|
||||||
# Please keep the list sorted.
|
# Please keep the list sorted.
|
||||||
|
|
||||||
|
Albert Pretorius <pretoalb@gmail.com>
|
||||||
Arne Beer <arne@twobeer.de>
|
Arne Beer <arne@twobeer.de>
|
||||||
Christopher Seymour <chris.j.seymour@hotmail.com>
|
Christopher Seymour <chris.j.seymour@hotmail.com>
|
||||||
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
|
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#
|
#
|
||||||
# Please keep the list sorted.
|
# Please keep the list sorted.
|
||||||
|
|
||||||
|
Albert Pretorius <pretoalb@gmail.com>
|
||||||
Arne Beer <arne@twobeer.de>
|
Arne Beer <arne@twobeer.de>
|
||||||
Billy Robert O'Neal III <billy.oneal@gmail.com> <bion@microsoft.com>
|
Billy Robert O'Neal III <billy.oneal@gmail.com> <bion@microsoft.com>
|
||||||
Chris Kennelly <ckennelly@google.com> <ckennelly@ckennelly.com>
|
Chris Kennelly <ckennelly@google.com> <ckennelly@ckennelly.com>
|
||||||
|
|
|
@ -210,20 +210,18 @@ Benchmark* RegisterBenchmarkInternal(Benchmark*);
|
||||||
// expression from being optimized away by the compiler. This function is
|
// expression from being optimized away by the compiler. This function is
|
||||||
// intented to add little to no overhead.
|
// intented to add little to no overhead.
|
||||||
// See: http://stackoverflow.com/questions/28287064
|
// See: http://stackoverflow.com/questions/28287064
|
||||||
#if defined(__clang__) && defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
// TODO(ericwf): Clang has a bug where it tries to always use a register
|
// TODO(ericwf): Clang has a bug where it tries to always use a register
|
||||||
// even if value must be stored in memory. This causes codegen to fail.
|
// even if value must be stored in memory. This causes codegen to fail.
|
||||||
// To work around this we remove the "r" modifier so the operand is always
|
// To work around this we remove the "r" modifier so the operand is always
|
||||||
// loaded into memory.
|
// loaded into memory.
|
||||||
|
// GCC also has a bug where it complains about inconsistent operand constraints
|
||||||
|
// when "+rm" is used for a type larger than can fit in a register or two.
|
||||||
|
// For now force the operand to memory for both GCC and Clang.
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
asm volatile("" : "+m" (const_cast<Tp&>(value)));
|
asm volatile("" : "+m" (const_cast<Tp&>(value)));
|
||||||
}
|
}
|
||||||
#elif defined(__GNUC__)
|
|
||||||
template <class Tp>
|
|
||||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
|
||||||
asm volatile("" : "+rm" (const_cast<Tp&>(value)));
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
template <class Tp>
|
template <class Tp>
|
||||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||||
|
|
|
@ -39,6 +39,9 @@ add_test(diagnostics_test diagnostics_test --benchmark_min_time=0.01)
|
||||||
compile_benchmark_test(skip_with_error_test)
|
compile_benchmark_test(skip_with_error_test)
|
||||||
add_test(skip_with_error_test skip_with_error_test --benchmark_min_time=0.01)
|
add_test(skip_with_error_test skip_with_error_test --benchmark_min_time=0.01)
|
||||||
|
|
||||||
|
compile_benchmark_test(donotoptimize_test)
|
||||||
|
add_test(donotoptimize_test donotoptimize_test --benchmark_min_time=0.01)
|
||||||
|
|
||||||
compile_benchmark_test(fixture_test)
|
compile_benchmark_test(fixture_test)
|
||||||
add_test(fixture_test fixture_test --benchmark_min_time=0.01)
|
add_test(fixture_test fixture_test --benchmark_min_time=0.01)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#include "benchmark/benchmark.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
std::uint64_t double_up(const std::uint64_t x) __attribute__ ((const));
|
||||||
|
#endif
|
||||||
|
std::uint64_t double_up(const std::uint64_t x) {
|
||||||
|
return x * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char*[]) {
|
||||||
|
|
||||||
|
// this test verifies compilation of DoNotOptimize() for some types
|
||||||
|
|
||||||
|
char buffer8[8];
|
||||||
|
benchmark::DoNotOptimize(buffer8);
|
||||||
|
|
||||||
|
char buffer20[20];
|
||||||
|
benchmark::DoNotOptimize(buffer20);
|
||||||
|
|
||||||
|
char buffer1024[1024];
|
||||||
|
benchmark::DoNotOptimize(buffer1024);
|
||||||
|
benchmark::DoNotOptimize(&buffer1024[0]);
|
||||||
|
|
||||||
|
int x = 123;
|
||||||
|
benchmark::DoNotOptimize(x);
|
||||||
|
benchmark::DoNotOptimize(&x);
|
||||||
|
benchmark::DoNotOptimize(x += 42);
|
||||||
|
|
||||||
|
benchmark::DoNotOptimize(double_up(x));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue