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