Realm
A distributed, event-based tasking library
Loading...
Searching...
No Matches
compiler_support.h
Go to the documentation of this file.
1/*
2 * Copyright 2025 Stanford University, NVIDIA Corporation
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// different compilers spell things different ways - here we define a bunch
19// of macros that contain the which-compiler-am-i tests
20
21// NOTE: none of the macros definitions are really Realm-specific, but all
22// macro names are prefixed with REALM_ to avoid name conflicts
23
24#ifndef REALM_COMPILER_SUPPORT_H
25#define REALM_COMPILER_SUPPORT_H
26
27// REALM_COMPILER_IS_GCC - defined if compiler is really gcc
28// REALM_COMPILER_IS_CLANG - defined if compiler is clang
29// REALM_COMPILER_IS_ICC - defined if compiler is icc
30// REALM_COMPILER_IS_PGI - defined if compiler is pgcc/nvcc
31// REALM_COMPILER_IS_MSVC - defined if compiler is MSVC
32// REALM_COMPILER_IS_NVCC - defined if compiler is really nvcc
33// REALM_COMPILER_IS_HIPCC - defined if compiler is hipcc
34#if defined(__HIPCC__)
35#define REALM_COMPILER_IS_HIPCC
36// Detect nvc++ before testing __CUDACC__
37#elif defined(__PGIC__) || defined(__NVCOMPILER)
38#define REALM_COMPILER_IS_PGI
39#elif defined(__CUDACC__)
40#define REALM_COMPILER_IS_NVCC
41#elif defined(__ICC)
42#define REALM_COMPILER_IS_ICC
43#elif defined(__clang__)
44#define REALM_COMPILER_IS_CLANG
45#elif defined(_MSC_VER)
46#define REALM_COMPILER_IS_MSVC
47#elif defined(__GNUC__)
48#define REALM_COMPILER_IS_GCC
49#else
50// unknown compiler?
51#endif
52
53// realm.h can be include by C, so we only check for C++17 when
54// imported by C++
55#ifdef __cplusplus
56// C++ 17 is supported after Visual Studio 2017 15.8, and __cplusplus
57// is available for MSVC after 2017 15.7, so it is safe to just check
58// __cplusplus
59#if __cplusplus < 201703L
60#error "Realm needs at least C++17"
61#endif
62#endif
63
64// REALM_NOEXCEPT - indicates that the declaration does not throw exceptions
65#define REALM_NOEXCEPT noexcept
66
67// REALM_ON_LINUX - defined if Realm is being built for a Linux host
68// REALM_ON_MACOS - defined if Realm is being built for a macOS host
69// REALM_ON_FREEBSD - defined if Realm is being built for a FreeBSD host
70// REALM_ON_WINDOWS - defined if Realm is being built for a Windows host
71#ifdef __linux__
72#define REALM_ON_LINUX
73#endif
74#ifdef __MACH__
75#define REALM_ON_MACOS
76#endif
77#ifdef __FreeBSD__
78#define REALM_ON_FREEBSD
79#endif
80#ifdef _MSC_VER
81#define REALM_ON_WINDOWS
82#endif
83
84// REALM_BIG_ENDIAN - defined if Realm is being built for a big-endian host
85#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
86#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
87#define REALM_BIG_ENDIAN
88#endif
89#endif
90
91// REALM_CUDA_HD - adds __host__ __device__ iff compiling with NVCC
92#if defined(__CUDACC__) || defined(__HIPCC__)
93#define REALM_CUDA_HD __host__ __device__
94#else
95#define REALM_CUDA_HD
96#endif
97
98// REALM_LIKELY(expr) - suggest that `expr` is usually true
99// REALM_UNLILELY(expr) - suggest that `expr` is usually false
100// REALM_EXPECT(expr, expval) - suggest that `expr` usually evaluates to `expval`
101#ifdef _MSC_VER
102// no __builtin_expect in MSVC
103#define REALM_LIKELY(expr) (expr)
104#define REALM_UNLIKELY(expr) (expr)
105#define REALM_EXPECT(expr, expval) (expr)
106#else
107#define REALM_LIKELY(expr) __builtin_expect((expr), true)
108#define REALM_UNLIKELY(expr) __builtin_expect((expr), false)
109#define REALM_EXPECT(expr, expval) __builtin_expect((expr), (expval))
110#endif
111
112// REALM_ATTR_UNUSED(thing) - indicate that `thing` is unused
113#define REALM_ATTR_UNUSED(thing) thing __attribute__((unused))
114
115// REALM_ATTR_WARN_UNUSED(thing) - ask compiler to warn if result of `thing` is
116// not used
117#ifdef _MSC_VER
118// MSVC has _Check_return_, but needs it on the definition too, which makes
119// it not a drop-in replacement
120#define REALM_ATTR_WARN_UNUSED(thing) /*_Check_return_*/ thing
121#else
122#define REALM_ATTR_WARN_UNUSED(thing) thing __attribute__((warn_unused_result))
123#endif
124
125// REALM_ATTR_PRINTF_FORMAT(thing, stridx, first) - check printf-style args
126#ifdef _MSC_VER
127#define REALM_ATTR_PRINTF_FORMAT(thing, stridx, first) thing
128#else
129#define REALM_ATTR_PRINTF_FORMAT(thing, stridx, first) \
130 thing __attribute__((format(printf, stridx, first)))
131#endif
132
133// REALM_ATTR_NORETURN(thing) - indicates that `thing` never returns
134#ifdef _MSC_VER
135#define REALM_ATTR_NORETURN(thing) __declspec(noreturn) thing
136#else
137#define REALM_ATTR_NORETURN(thing) thing __attribute__((noreturn))
138#endif
139
140// REALM_ATTR_DEPRECATED(msg, thing) - indicates `thing` is deprecated, printing
141// `msg` at compile time if possible
142// REALM_ATTR_DEPRECATED2(msg, thing1, thing2) - above when `thing` has commas in it
143#ifdef __ICC
144#define REALM_ATTR_DEPRECATED(msg, thing) thing __attribute__((deprecated))
145#define REALM_ATTR_DEPRECATED2(msg, thing1, thing2) \
146 thing1, thing2 __attribute__((deprecated))
147#elif defined(_MSC_VER)
148#define REALM_ATTR_DEPRECATED(msg, thing) __declspec(deprecated(msg)) thing
149#define REALM_ATTR_DEPRECATED2(msg, thing1, thing2) \
150 __declspec(deprecated(msg)) thing1, thing2
151#else
152#define REALM_ATTR_DEPRECATED(msg, thing) thing __attribute__((deprecated(msg)))
153#define REALM_ATTR_DEPRECATED2(msg, thing1, thing2) \
154 thing1, thing2 __attribute__((deprecated(msg)))
155#endif
156
157// REALM_ALIGNOF(type) - returns the byte alignment required for `type`
158#define REALM_ALIGNOF(type) alignof(type)
159
160// REALM_ALIGNED_TYPE_SAMEAS(newtype, origtype, reftype) - defines type `newtype`
161// that is identical to `origtype` except that it is aligned as `reftype`
162#ifdef _MSC_VER
163#define REALM_ALIGNED_TYPE_SAMEAS(newtype, origtype, reftype) \
164 typedef __declspec(align(__alignof(reftype))) origtype newtype
165#else
166#define REALM_ALIGNED_TYPE_SAMEAS(newtype, origtype, reftype) \
167 typedef origtype __attribute__((aligned(__alignof__(reftype)))) newtype
168#endif
169
170// REALM_ALIGNED_TYPE_CONST(newtype, origtype, bytes) - defines type `newtype`
171// that is identical to `origtype` except it is aligned to `bytes`
172#ifdef _MSC_VER
173#define REALM_ALIGNED_TYPE_CONST(newtype, origtype, bytes) \
174 typedef __declspec(align(bytes)) origtype newtype
175#else
176#define REALM_ALIGNED_TYPE_CONST(newtype, origtype, bytes) \
177 typedef origtype __attribute__((aligned((bytes) + 0))) newtype
178#endif
179
180// REALM_HAVE_CXXABI_H - defined if <cxxabi.h> is available
181#ifndef _MSC_VER
182#define REALM_HAVE_CXXABI_H
183#endif
184
185// the following defines are used to communicate which declarations are part
186// of the "official" public Realm API (as opposed to things that need to be in
187// the same header files for C++ reasons) - they also control which symbols
188// appear in the shared library:
189// REALM_PUBLIC_API - class/method/variable intended for direct use
190// in applications
191// REALM_INTERNAL_API_EXTERNAL_LINKAGE - method/variable not intended for
192// direct use in applications but used indirectly and
193// therefore requiring external linkage
194// REALM_INTERNAL_API - method/variable that is not part of the public API
195// despite being in an otherwise-public class
196
197#ifdef REALM_LIMIT_SYMBOL_VISIBILITY
198// TODO(cperry): replace this with realm_exports.h generated by cmake
199#if defined(_MSC_VER)
200#ifndef REALM_EXPORT
201#ifdef realm_EXPORTS
202/* We are building this library */
203#define REALM_PUBLIC_API __declspec(dllexport)
204#else
205/* We are using this library */
206#define REALM_PUBLIC_API __declspec(dllimport)
207#endif
208#endif
209#define REALM_INTERNAL_API_EXTERNAL_LINKAGE REALM_PUBLIC_API
210#define REALM_INTERNAL_API
211#else
212#define REALM_PUBLIC_API __attribute__((visibility("default")))
213#define REALM_INTERNAL_API_EXTERNAL_LINKAGE __attribute__((visibility("default")))
214#define REALM_INTERNAL_API __attribute__((visibility("hidden")))
215#endif
216#else
217#define REALM_PUBLIC_API
218#define REALM_INTERNAL_API_EXTERNAL_LINKAGE
219#define REALM_INTERNAL_API
220#endif
221
222// compiler-specific hackery
223
224// Microsoft Visual Studio
225#ifdef _MSC_VER
226#define _CRT_SECURE_NO_WARNINGS
227
228// MSVC gives a narrowing warning on explicit assignments, which is much too agressive
229#pragma warning(disable : 4244 4267)
230
231// MSVC warns if pieces of an explicit template instantiation are split across files
232#pragma warning(disable : 4661)
233
234// windows.h by default defines macros called 'min' and 'max' - suppress that
235#define NOMINMAX
236
237// ssize_t doesn't exist, so make it
238#include <basetsd.h>
239typedef SSIZE_T ssize_t;
240#endif
241
242#endif