1 ///
2 /// @file  macros.hpp
3 ///
4 /// Copyright (C) 2020 Kim Walisch, <kim.walisch@gmail.com>
5 ///
6 /// This file is distributed under the BSD License. See the COPYING
7 /// file in the top level directory.
8 ///
9 
10 #ifndef MACROS_HPP
11 #define MACROS_HPP
12 
13 #ifndef __has_attribute
14   #define __has_attribute(x) 0
15 #endif
16 
17 #ifndef __has_builtin
18   #define __has_builtin(x) 0
19 #endif
20 
21 #ifndef __has_cpp_attribute
22   #define __has_cpp_attribute(x) 0
23 #endif
24 
25 /// Some functions in primesieve use a large number of variables
26 /// at the same time. If such functions are inlined then
27 /// performance drops because not all variables fit into registers
28 /// which causes register spilling. We annotate such functions
29 /// with NOINLINE in order to avoid these issues.
30 ///
31 #if __has_attribute(noinline)
32   #define NOINLINE __attribute__((noinline))
33 #elif defined(_MSC_VER)
34   #define NOINLINE __declspec(noinline)
35 #else
36   #define NOINLINE
37 #endif
38 
39 #if __cplusplus >= 202002L && \
40     __has_cpp_attribute(unlikely)
41   #define if_unlikely(x) if (x) [[unlikely]]
42 #elif defined(__GNUC__) || \
43       __has_builtin(__builtin_expect)
44   #define if_unlikely(x) if (__builtin_expect(!!(x), 0))
45 #else
46   #define if_unlikely(x) if (x)
47 #endif
48 
49 #if __cplusplus >= 201703L && \
50     __has_cpp_attribute(fallthrough)
51   #define FALLTHROUGH [[fallthrough]]
52 #elif __has_attribute(fallthrough)
53   #define FALLTHROUGH __attribute__((fallthrough))
54 #else
55   #define FALLTHROUGH
56 #endif
57 
58 #if defined(__GNUC__) || \
59     __has_builtin(__builtin_unreachable)
60   #define UNREACHABLE __builtin_unreachable()
61 #elif defined(_MSC_VER)
62   #define UNREACHABLE __assume(0)
63 #else
64   #define UNREACHABLE
65 #endif
66 
67 /// Use [[maybe_unused]] from C++17 once widely supported
68 #if defined(NDEBUG)
69   #define MAYBE_UNUSED(x)
70 #else
71   #define MAYBE_UNUSED(x) x
72 #endif
73 
74 #endif
75