libcopp  1.3.0
compile_optimize.h
Go to the documentation of this file.
1 #ifndef UTIL_CONFIG_COMPILE_OPTIMIZE_H
2 #define UTIL_CONFIG_COMPILE_OPTIMIZE_H
3 
4 #pragma once
5 
6 
7 // ================ branch prediction information ================
8 #ifndef likely
9 #ifdef __GNUC__
10 #define likely(x) __builtin_expect(!!(x), 1)
11 #else
12 #define likely(x) !!(x)
13 #endif
14 #endif
15 
16 #ifndef unlikely
17 #ifdef __GNUC__
18 #define unlikely(x) __builtin_expect(!!(x), 0)
19 #else
20 #define unlikely(x) !!(x)
21 #endif
22 #endif
23 
24 #ifndef unreachable
25 #ifdef __GNUC__
26 #ifdef __clang__
27 #if __has_builtin(__builtin_unreachable)
28 #define unreachable() __builtin_unreachable()
29 #else
30 #define unreachable() abort()
31 #endif
32 #else
33 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
34 #define unreachable() __builtin_unreachable()
35 #else
36 #define unreachable() abort()
37 #endif
38 #endif
39 #else
40 #define unreachable() abort()
41 #endif
42 #endif
43 // ---------------- branch prediction information ----------------
44 
45 // ================ import/export ================
46 // @see https://gcc.gnu.org/wiki/Visibility
47 // @see http://releases.llvm.org/9.0.0/tools/clang/docs/AttributeReference.html
48 // 不支持 borland/sunpro_cc/xlcpp
49 
50 // ================ import/export: for compilers ================
51 #if defined(__GNUC__) && !defined(__ibmxl__)
52 // GNU C++/Clang
53 //
54 // Dynamic shared object (DSO) and dynamic-link library (DLL) support
55 //
56 #if __GNUC__ >= 4
57 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
58 // All Win32 development environments, including 64-bit Windows and MinGW, define
59 // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment,
60 // so does not define _WIN32 or its variants.
61 #define UTIL_SYMBOL_EXPORT __attribute__((__dllexport__))
62 #define UTIL_SYMBOL_IMPORT __attribute__((__dllimport__))
63 #else
64 #define UTIL_SYMBOL_EXPORT __attribute__((__visibility__("default")))
65 #define UTIL_SYMBOL_IMPORT __attribute__((__visibility__("default")))
66 #define UTIL_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
67 #define UTIL_SYMBOL_HIDDEN __attribute__((__visibility__("hidden")))
68 #endif
69 #else
70 // config/platform/win32.hpp will define UTIL_SYMBOL_EXPORT, etc., unless already defined
71 #define UTIL_SYMBOL_EXPORT
72 #define UTIL_SYMBOL_IMPORT
73 #define UTIL_SYMBOL_VISIBLE
74 #define UTIL_SYMBOL_HIDDEN
75 #endif
76 
77 #elif defined(_MSC_VER)
78 // Microsoft Visual C++
79 //
80 // Must remain the last #elif since some other vendors (Metrowerks, for
81 // example) also #define _MSC_VER
82 #else
83 #endif
84 // ---------------- import/export: for compilers ----------------
85 
86 // ================ import/export: for platform ================
87 // Default defines for UTIL_SYMBOL_EXPORT and UTIL_SYMBOL_IMPORT
88 // If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport),
89 // its boost/config/compiler/ file must define UTIL_SYMBOL_EXPORT and
90 // UTIL_SYMBOL_IMPORT
91 #if !defined(UTIL_SYMBOL_EXPORT) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))
92 #define UTIL_SYMBOL_EXPORT __declspec(dllexport)
93 #define UTIL_SYMBOL_IMPORT __declspec(dllimport)
94 #endif
95 // ---------------- import/export: for platform ----------------
96 
97 #ifndef UTIL_SYMBOL_EXPORT
98 #define UTIL_SYMBOL_EXPORT
99 #endif
100 #ifndef UTIL_SYMBOL_IMPORT
101 #define UTIL_SYMBOL_IMPORT
102 #endif
103 #ifndef UTIL_SYMBOL_VISIBLE
104 #define UTIL_SYMBOL_VISIBLE
105 #endif
106 #ifndef UTIL_SYMBOL_HIDDEN
107 #define UTIL_SYMBOL_HIDDEN
108 #endif
109 
110 // ---------------- import/export ----------------
111 
112 // ================ __cdecl ================
113 #if defined(__GNUC__) || defined(__GNUG__)
114 #ifndef __cdecl
115 // see https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html
116 // Intel x86 architecture specific calling conventions
117 #ifdef _M_IX86
118 #define __cdecl __attribute__((__cdecl__))
119 #else
120 #define __cdecl
121 #endif
122 #endif
123 #endif
124 // ---------------- __cdecl ----------------
125 
126 // ================ always inline ================
127 
128 #ifndef UTIL_FORCEINLINE
129 #if defined(__clang__)
130 #if __has_attribute(always_inline)
131 #define UTIL_FORCEINLINE __attribute__((always_inline))
132 #else
133 #define UTIL_FORCEINLINE inline
134 #endif
135 
136 #elif defined(__GNUC__) && __GNUC__ > 3
137 #define UTIL_FORCEINLINE __attribute__((always_inline))
138 #elif defined(_MSC_VER)
139 #define UTIL_FORCEINLINE __forceinline
140 #else
141 #define UTIL_FORCEINLINE inline
142 #endif
143 #endif
144 
145 #ifndef UTIL_NOINLINE
146 #if defined(_MSC_VER)
147 #define UTIL_NOINLINE __declspec(noinline)
148 #elif defined(__GNUC__) && __GNUC__ > 3
149 // Clang also defines __GNUC__ (as 4)
150 #if defined(__CUDACC__)
151 // nvcc doesn't always parse __noinline__,
152 // see: https://svn.boost.org/trac/boost/ticket/9392
153 #define UTIL_NOINLINE __attribute__((noinline))
154 #else
155 #define UTIL_NOINLINE __attribute__((__noinline__))
156 #endif
157 #else
158 #define UTIL_NOINLINE
159 #endif
160 #endif
161 
162 #endif