15#ifndef BENCHMARK_UTILS_H_
16#define BENCHMARK_UTILS_H_
22#include "benchmark/export.h"
23#include "benchmark/macros.h"
28BENCHMARK_EXPORT
void UseCharPointer(
char const volatile*);
38 typedef typename std::remove_reference<Tp>::type T;
39 static const bool value = std::is_array<T>::value ||
40 std::is_copy_assignable<T>::value ||
41 std::is_move_assignable<T>::value;
45#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
46 defined(__EMSCRIPTEN__)
47#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
50inline BENCHMARK_ALWAYS_INLINE
void ClobberMemory() {
51 std::atomic_signal_fence(std::memory_order_acq_rel);
54#define BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG \
55 "DoNotOptimize(T const&) can permit undesired compiler optimizations. " \
56 "Pass a non-const lvalue instead; if the argument is an expression result, " \
57 "store it in a local variable first."
59#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
60#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
62BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
63inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp
const& value) {
64 asm volatile(
"" : :
"r,m"(value) :
"memory");
68inline BENCHMARK_ALWAYS_INLINE
69 typename std::enable_if<internal::IsValidAsmOutput<Tp>::value>::type
70 DoNotOptimize(Tp& value) {
72 asm volatile(
"" :
"+r,m"(value) : :
"memory");
74 asm volatile(
"" :
"+m,r"(value) : :
"memory");
79inline BENCHMARK_ALWAYS_INLINE
80 typename std::enable_if<internal::IsValidAsmOutput<Tp>::value>::type
81 DoNotOptimize(Tp&& value) {
83 asm volatile(
"" :
"+r,m"(value) : :
"memory");
85 asm volatile(
"" :
"+m,r"(value) : :
"memory");
93inline BENCHMARK_ALWAYS_INLINE
94 typename std::enable_if<!internal::IsValidAsmOutput<Tp>::value>::type
95 DoNotOptimize(Tp&& value) {
96 asm volatile(
"" : :
"r,m"(value) :
"memory");
100BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
101inline BENCHMARK_ALWAYS_INLINE
102 typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
103 (
sizeof(Tp) <=
sizeof(Tp*))>::type
104 DoNotOptimize(Tp
const& value) {
105 asm volatile(
"" : :
"r,m"(value) :
"memory");
109BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
110inline BENCHMARK_ALWAYS_INLINE
111 typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
112 (
sizeof(Tp) >
sizeof(Tp*))>::type
113 DoNotOptimize(Tp
const& value) {
114 asm volatile(
"" : :
"m"(value) :
"memory");
118inline BENCHMARK_ALWAYS_INLINE
119 typename std::enable_if<internal::IsValidAsmOutput<Tp>::value &&
120 std::is_trivially_copyable<Tp>::value &&
121 (
sizeof(Tp) <=
sizeof(Tp*))>::type
122 DoNotOptimize(Tp& value) {
123 asm volatile(
"" :
"+m,r"(value) : :
"memory");
127inline BENCHMARK_ALWAYS_INLINE
128 typename std::enable_if<internal::IsValidAsmOutput<Tp>::value &&
129 (!std::is_trivially_copyable<Tp>::value ||
130 (
sizeof(Tp) >
sizeof(Tp*)))>::type
131 DoNotOptimize(Tp& value) {
132 asm volatile(
"" :
"+m"(value) : :
"memory");
136inline BENCHMARK_ALWAYS_INLINE
137 typename std::enable_if<internal::IsValidAsmOutput<Tp>::value &&
138 std::is_trivially_copyable<Tp>::value &&
139 (
sizeof(Tp) <=
sizeof(Tp*))>::type
140 DoNotOptimize(Tp&& value) {
141 asm volatile(
"" :
"+m,r"(value) : :
"memory");
145inline BENCHMARK_ALWAYS_INLINE
146 typename std::enable_if<internal::IsValidAsmOutput<Tp>::value &&
147 (!std::is_trivially_copyable<Tp>::value ||
148 (
sizeof(Tp) >
sizeof(Tp*)))>::type
149 DoNotOptimize(Tp&& value) {
150 asm volatile(
"" :
"+m"(value) : :
"memory");
157inline BENCHMARK_ALWAYS_INLINE
158 typename std::enable_if<!internal::IsValidAsmOutput<Tp>::value>::type
159 DoNotOptimize(Tp&& value) {
160 asm volatile(
"" : :
"r,m"(value) :
"memory");
164#elif defined(_MSC_VER)
166BENCHMARK_DEPRECATED_MSG(BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG)
167inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp
const& value) {
168 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
173inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp& value) {
174 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
179inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
180 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
185inline BENCHMARK_ALWAYS_INLINE
void DoNotOptimize(Tp&& value) {
186 internal::UseCharPointer(&
reinterpret_cast<char const volatile&
>(value));
190#undef BENCHMARK_DONOTOPTIMIZE_CONST_REF_DEPRECATED_MSG