File indexing completed on 2025-01-30 10:02:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef CATCH_OPTIMIZER_HPP_INCLUDED
0011 #define CATCH_OPTIMIZER_HPP_INCLUDED
0012
0013 #if defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__)
0014 # include <atomic> // atomic_thread_fence
0015 #endif
0016
0017 #include <catch2/internal/catch_move_and_forward.hpp>
0018
0019 #include <type_traits>
0020
0021 namespace Catch {
0022 namespace Benchmark {
0023 #if defined(__GNUC__) || defined(__clang__)
0024 template <typename T>
0025 inline void keep_memory(T* p) {
0026 asm volatile("" : : "g"(p) : "memory");
0027 }
0028 inline void keep_memory() {
0029 asm volatile("" : : : "memory");
0030 }
0031
0032 namespace Detail {
0033 inline void optimizer_barrier() { keep_memory(); }
0034 }
0035 #elif defined(_MSC_VER) || defined(__IAR_SYSTEMS_ICC__)
0036
0037 #if defined(_MSVC_VER)
0038 #pragma optimize("", off)
0039 #elif defined(__IAR_SYSTEMS_ICC__)
0040
0041 #pragma optimize=disable
0042 #endif
0043 template <typename T>
0044 inline void keep_memory(T* p) {
0045
0046 *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
0047 }
0048
0049 #if defined(_MSVC_VER)
0050 #pragma optimize("", on)
0051 #endif
0052
0053 namespace Detail {
0054 inline void optimizer_barrier() {
0055 std::atomic_thread_fence(std::memory_order_seq_cst);
0056 }
0057 }
0058
0059 #endif
0060
0061 template <typename T>
0062 inline void deoptimize_value(T&& x) {
0063 keep_memory(&x);
0064 }
0065
0066 template <typename Fn, typename... Args>
0067 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<!std::is_same<void, decltype(fn(args...))>::value> {
0068 deoptimize_value(CATCH_FORWARD(fn) (CATCH_FORWARD(args)...));
0069 }
0070
0071 template <typename Fn, typename... Args>
0072 inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> std::enable_if_t<std::is_same<void, decltype(fn(args...))>::value> {
0073 CATCH_FORWARD(fn) (CATCH_FORWARD(args)...);
0074 }
0075 }
0076 }
0077
0078 #endif