1//===-- Portable optimization macros ----------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// This header file defines portable macros for performance optimization.
9
10#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
11#define LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
12
13#include "src/__support/macros/attributes.h" // LIBC_INLINE
14#include "src/__support/macros/config.h"
15#include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
16
17// We use a template to implement likely/unlikely to make sure that we don't
18// accidentally pass an integer.
19// Note that `__builtin_expect` requires the second argument to be a constant
20// expression.
21namespace LIBC_NAMESPACE_DECL {
22namespace details {
23template <typename T>
24LIBC_ALWAYS_INLINE constexpr bool expects_bool_condition(T value) = delete;
25
26template <>
27LIBC_ALWAYS_INLINE constexpr bool expects_bool_condition<bool>(bool value) {
28 return value;
29}
30} // namespace details
31} // namespace LIBC_NAMESPACE_DECL
32#define LIBC_LIKELY(x) \
33 (__builtin_expect(LIBC_NAMESPACE::details::expects_bool_condition((x)), true))
34#define LIBC_UNLIKELY(x) \
35 (__builtin_expect(LIBC_NAMESPACE::details::expects_bool_condition((x)), \
36 false))
37
38#if defined(LIBC_COMPILER_IS_CLANG)
39#define LIBC_LOOP_NOUNROLL _Pragma("nounroll")
40#define LIBC_LOOP_UNROLL _Pragma("unroll")
41#elif defined(LIBC_COMPILER_IS_GCC)
42#if LIBC_COMPILER_GCC_VER >= 800
43#define LIBC_LOOP_NOUNROLL _Pragma("GCC unroll 0")
44#define LIBC_LOOP_UNROLL _Pragma("GCC unroll 2048")
45#else
46#define LIBC_LOOP_NOUNROLL
47#define LIBC_LOOP_UNROLL
48#endif
49#elif defined(LIBC_COMPILER_IS_MSVC)
50#define LIBC_LOOP_NOUNROLL
51#define LIBC_LOOP_UNROLL
52#else
53#error "Unhandled compiler"
54#endif
55
56// Defining optimization options for math functions.
57// TODO: Exporting this to public generated headers?
58#define LIBC_MATH_SKIP_ACCURATE_PASS 0x01
59#define LIBC_MATH_SMALL_TABLES 0x02
60#define LIBC_MATH_NO_ERRNO 0x04
61#define LIBC_MATH_NO_EXCEPT 0x08
62#define LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT 0x10
63#define LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY 0x20
64#define LIBC_MATH_FAST \
65 (LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | \
66 LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT | \
67 LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY)
68
69#ifndef LIBC_MATH
70#define LIBC_MATH 0
71#endif // LIBC_MATH
72
73#if ((LIBC_MATH) & LIBC_MATH_SKIP_ACCURATE_PASS)
74#define LIBC_MATH_HAS_SKIP_ACCURATE_PASS
75#endif
76
77#if ((LIBC_MATH) & LIBC_MATH_SMALL_TABLES)
78#define LIBC_MATH_HAS_SMALL_TABLES
79#endif
80
81#if ((LIBC_MATH) & LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT)
82#define LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT
83#endif
84
85#if ((LIBC_MATH) & LIBC_MATH_NO_ERRNO)
86#define LIBC_MATH_HAS_NO_ERRNO
87#endif
88
89#if ((LIBC_MATH) & LIBC_MATH_NO_EXCEPT)
90#define LIBC_MATH_HAS_NO_EXCEPT
91#endif
92
93#if ((LIBC_MATH) & LIBC_MATH_ASSUME_ROUND_NEAREST_ONLY)
94#define LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
95#endif
96
97#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
98