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 #endif
68 #else
69 // config/platform/win32.hpp will define UTIL_SYMBOL_EXPORT, etc., unless already defined
70 #define UTIL_SYMBOL_EXPORT
71 #define UTIL_SYMBOL_IMPORT
72 #define UTIL_SYMBOL_VISIBLE
73 #endif
74 
75 #elif defined(_MSC_VER)
76 // Microsoft Visual C++
77 //
78 // Must remain the last #elif since some other vendors (Metrowerks, for
79 // example) also #define _MSC_VER
80 #else
81 #endif
82 // ---------------- import/export: for compilers ----------------
83 
84 // ================ import/export: for platform ================
85 // Default defines for UTIL_SYMBOL_EXPORT and UTIL_SYMBOL_IMPORT
86 // If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport),
87 // its boost/config/compiler/ file must define UTIL_SYMBOL_EXPORT and
88 // UTIL_SYMBOL_IMPORT
89 #if !defined(UTIL_SYMBOL_EXPORT) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__))
90 #define UTIL_SYMBOL_EXPORT __declspec(dllexport)
91 #define UTIL_SYMBOL_IMPORT __declspec(dllimport)
92 #endif
93 // ---------------- import/export: for platform ----------------
94 
95 #ifndef UTIL_SYMBOL_EXPORT
96 #define UTIL_SYMBOL_EXPORT
97 #endif
98 #ifndef UTIL_SYMBOL_IMPORT
99 #define UTIL_SYMBOL_IMPORT
100 #endif
101 #ifndef UTIL_SYMBOL_VISIBLE
102 #define UTIL_SYMBOL_VISIBLE
103 #endif
104 
105 // ---------------- import/export ----------------
106 
107 // ================ __cdecl ================
108 #if defined(__GNUC__) || defined(__GNUG__)
109 #ifndef __cdecl
110 // see https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html
111 // Intel x86 architecture specific calling conventions
112 #ifdef _M_IX86
113 #define __cdecl __attribute__((__cdecl__))
114 #else
115 #define __cdecl
116 #endif
117 #endif
118 #endif
119 // ---------------- __cdecl ----------------
120 
121 // ================ always inline ================
122 
123 #ifndef UTIL_FORCEINLINE
124 #if defined(__clang__)
125 #if __has_attribute(always_inline)
126 #define UTIL_FORCEINLINE __attribute__((always_inline))
127 #else
128 #define UTIL_FORCEINLINE inline
129 #endif
130 
131 #elif defined(__GNUC__) && __GNUC__ > 3
132 #define UTIL_FORCEINLINE __attribute__((always_inline))
133 #elif defined(_MSC_VER)
134 #define UTIL_FORCEINLINE __forceinline
135 #else
136 #define UTIL_FORCEINLINE inline
137 #endif
138 #endif
139 
140 #ifndef UTIL_NOINLINE
141 #if defined(_MSC_VER)
142 #define UTIL_NOINLINE __declspec(noinline)
143 #elif defined(__GNUC__) && __GNUC__ > 3
144 // Clang also defines __GNUC__ (as 4)
145 #if defined(__CUDACC__)
146 // nvcc doesn't always parse __noinline__,
147 // see: https://svn.boost.org/trac/boost/ticket/9392
148 #define UTIL_NOINLINE __attribute__((noinline))
149 #else
150 #define UTIL_NOINLINE __attribute__((__noinline__))
151 #endif
152 #else
153 #define UTIL_NOINLINE
154 #endif
155 #endif
156 
157 #endif