Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-03 08:06:33

0001 //
0002 // Copyright 2017 The Abseil Authors.
0003 //
0004 // Licensed under the Apache License, Version 2.0 (the "License");
0005 // you may not use this file except in compliance with the License.
0006 // You may obtain a copy of the License at
0007 //
0008 //      https://www.apache.org/licenses/LICENSE-2.0
0009 //
0010 // Unless required by applicable law or agreed to in writing, software
0011 // distributed under the License is distributed on an "AS IS" BASIS,
0012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 // See the License for the specific language governing permissions and
0014 // limitations under the License.
0015 //
0016 // -----------------------------------------------------------------------------
0017 // File: optimization.h
0018 // -----------------------------------------------------------------------------
0019 //
0020 // This header file defines portable macros for performance optimization.
0021 //
0022 // This header is included in both C++ code and legacy C code and thus must
0023 // remain compatible with both C and C++. C compatibility will be removed if
0024 // the legacy code is removed or converted to C++. Do not include this header in
0025 // new code that requires C compatibility or assume C compatibility will remain
0026 // indefinitely.
0027 
0028 #ifndef ABSL_BASE_OPTIMIZATION_H_
0029 #define ABSL_BASE_OPTIMIZATION_H_
0030 
0031 #include <assert.h>
0032 
0033 #ifdef __cplusplus
0034 // Included for std::unreachable()
0035 #include <utility>
0036 #endif  // __cplusplus
0037 
0038 #include "absl/base/config.h"
0039 #include "absl/base/options.h"
0040 
0041 // ABSL_BLOCK_TAIL_CALL_OPTIMIZATION
0042 //
0043 // Instructs the compiler to avoid optimizing tail-call recursion. This macro is
0044 // useful when you wish to preserve the existing function order within a stack
0045 // trace for logging, debugging, or profiling purposes.
0046 //
0047 // Example:
0048 //
0049 //   int f() {
0050 //     int result = g();
0051 //     ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
0052 //     return result;
0053 //   }
0054 #if defined(__pnacl__)
0055 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
0056 #elif defined(__clang__)
0057 // Clang will not tail call given inline volatile assembly.
0058 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
0059 #elif defined(__GNUC__)
0060 // GCC will not tail call given inline volatile assembly.
0061 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("")
0062 #elif defined(_MSC_VER)
0063 #include <intrin.h>
0064 // The __nop() intrinsic blocks the optimisation.
0065 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop()
0066 #else
0067 #define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; }
0068 #endif
0069 
0070 // ABSL_CACHELINE_SIZE
0071 //
0072 // Explicitly defines the size of the L1 cache for purposes of alignment.
0073 // Setting the cacheline size allows you to specify that certain objects be
0074 // aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations.
0075 // (See below.)
0076 //
0077 // NOTE: this macro should be replaced with the following C++17 features, when
0078 // those are generally available:
0079 //
0080 //   * `std::hardware_constructive_interference_size`
0081 //   * `std::hardware_destructive_interference_size`
0082 //
0083 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
0084 // for more information.
0085 #if defined(__GNUC__)
0086 // Cache line alignment
0087 #if defined(__i386__) || defined(__x86_64__)
0088 #define ABSL_CACHELINE_SIZE 64
0089 #elif defined(__powerpc64__)
0090 #define ABSL_CACHELINE_SIZE 128
0091 #elif defined(__aarch64__)
0092 // We would need to read special register ctr_el0 to find out L1 dcache size.
0093 // This value is a good estimate based on a real aarch64 machine.
0094 #define ABSL_CACHELINE_SIZE 64
0095 #elif defined(__arm__)
0096 // Cache line sizes for ARM: These values are not strictly correct since
0097 // cache line sizes depend on implementations, not architectures.  There
0098 // are even implementations with cache line sizes configurable at boot
0099 // time.
0100 #if defined(__ARM_ARCH_5T__)
0101 #define ABSL_CACHELINE_SIZE 32
0102 #elif defined(__ARM_ARCH_7A__)
0103 #define ABSL_CACHELINE_SIZE 64
0104 #endif
0105 #endif
0106 #endif
0107 
0108 #ifndef ABSL_CACHELINE_SIZE
0109 // A reasonable default guess.  Note that overestimates tend to waste more
0110 // space, while underestimates tend to waste more time.
0111 #define ABSL_CACHELINE_SIZE 64
0112 #endif
0113 
0114 // ABSL_CACHELINE_ALIGNED
0115 //
0116 // Indicates that the declared object be cache aligned using
0117 // `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to
0118 // load a set of related objects in the L1 cache for performance improvements.
0119 // Cacheline aligning objects properly allows constructive memory sharing and
0120 // prevents destructive (or "false") memory sharing.
0121 //
0122 // NOTE: callers should replace uses of this macro with `alignas()` using
0123 // `std::hardware_constructive_interference_size` and/or
0124 // `std::hardware_destructive_interference_size` when C++17 becomes available to
0125 // them.
0126 //
0127 // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
0128 // for more information.
0129 //
0130 // On some compilers, `ABSL_CACHELINE_ALIGNED` expands to an `__attribute__`
0131 // or `__declspec` attribute. For compilers where this is not known to work,
0132 // the macro expands to nothing.
0133 //
0134 // No further guarantees are made here. The result of applying the macro
0135 // to variables and types is always implementation-defined.
0136 //
0137 // WARNING: It is easy to use this attribute incorrectly, even to the point
0138 // of causing bugs that are difficult to diagnose, crash, etc. It does not
0139 // of itself guarantee that objects are aligned to a cache line.
0140 //
0141 // NOTE: Some compilers are picky about the locations of annotations such as
0142 // this attribute, so prefer to put it at the beginning of your declaration.
0143 // For example,
0144 //
0145 //   ABSL_CACHELINE_ALIGNED static Foo* foo = ...
0146 //
0147 //   class ABSL_CACHELINE_ALIGNED Bar { ...
0148 //
0149 // Recommendations:
0150 //
0151 // 1) Consult compiler documentation; this comment is not kept in sync as
0152 //    toolchains evolve.
0153 // 2) Verify your use has the intended effect. This often requires inspecting
0154 //    the generated machine code.
0155 // 3) Prefer applying this attribute to individual variables. Avoid
0156 //    applying it to types. This tends to localize the effect.
0157 #if defined(__clang__) || defined(__GNUC__)
0158 #define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE)))
0159 #elif defined(_MSC_VER)
0160 #define ABSL_CACHELINE_ALIGNED __declspec(align(ABSL_CACHELINE_SIZE))
0161 #else
0162 #define ABSL_CACHELINE_ALIGNED
0163 #endif
0164 
0165 // ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE
0166 //
0167 // Enables the compiler to prioritize compilation using static analysis for
0168 // likely paths within a boolean branch.
0169 //
0170 // Example:
0171 //
0172 //   if (ABSL_PREDICT_TRUE(expression)) {
0173 //     return result;                        // Faster if more likely
0174 //   } else {
0175 //     return 0;
0176 //   }
0177 //
0178 // Compilers can use the information that a certain branch is not likely to be
0179 // taken (for instance, a CHECK failure) to optimize for the common case in
0180 // the absence of better information (ie. compiling gcc with `-fprofile-arcs`).
0181 //
0182 // Recommendation: Modern CPUs dynamically predict branch execution paths,
0183 // typically with accuracy greater than 97%. As a result, annotating every
0184 // branch in a codebase is likely counterproductive; however, annotating
0185 // specific branches that are both hot and consistently mispredicted is likely
0186 // to yield performance improvements.
0187 #if ABSL_HAVE_BUILTIN(__builtin_expect) || \
0188     (defined(__GNUC__) && !defined(__clang__))
0189 #define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false))
0190 #define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))
0191 #else
0192 #define ABSL_PREDICT_FALSE(x) (x)
0193 #define ABSL_PREDICT_TRUE(x) (x)
0194 #endif
0195 
0196 // `ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL()` aborts the program in the fastest
0197 // possible way, with no attempt at logging. One use is to implement hardening
0198 // aborts with ABSL_OPTION_HARDENED.  Since this is an internal symbol, it
0199 // should not be used directly outside of Abseil.
0200 #if ABSL_HAVE_BUILTIN(__builtin_trap) || \
0201     (defined(__GNUC__) && !defined(__clang__))
0202 #define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() __builtin_trap()
0203 #else
0204 #define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() abort()
0205 #endif
0206 
0207 // `ABSL_INTERNAL_UNREACHABLE_IMPL()` is the platform specific directive to
0208 // indicate that a statement is unreachable, and to allow the compiler to
0209 // optimize accordingly. Clients should use `ABSL_UNREACHABLE()`, which is
0210 // defined below.
0211 #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
0212 #define ABSL_INTERNAL_UNREACHABLE_IMPL() std::unreachable()
0213 #elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
0214 #define ABSL_INTERNAL_UNREACHABLE_IMPL() __builtin_unreachable()
0215 #elif ABSL_HAVE_BUILTIN(__builtin_assume)
0216 #define ABSL_INTERNAL_UNREACHABLE_IMPL() __builtin_assume(false)
0217 #elif defined(_MSC_VER)
0218 #define ABSL_INTERNAL_UNREACHABLE_IMPL() __assume(false)
0219 #else
0220 #define ABSL_INTERNAL_UNREACHABLE_IMPL()
0221 #endif
0222 
0223 // `ABSL_UNREACHABLE()` is an unreachable statement.  A program which reaches
0224 // one has undefined behavior, and the compiler may optimize accordingly.
0225 #if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
0226 // Abort in hardened mode to avoid dangerous undefined behavior.
0227 #define ABSL_UNREACHABLE()                \
0228   do {                                    \
0229     ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(); \
0230     ABSL_INTERNAL_UNREACHABLE_IMPL();     \
0231   } while (false)
0232 #else
0233 // The assert only fires in debug mode to aid in debugging.
0234 // When NDEBUG is defined, reaching ABSL_UNREACHABLE() is undefined behavior.
0235 #define ABSL_UNREACHABLE()                       \
0236   do {                                           \
0237     /* NOLINTNEXTLINE: misc-static-assert */     \
0238     assert(false && "ABSL_UNREACHABLE reached"); \
0239     ABSL_INTERNAL_UNREACHABLE_IMPL();            \
0240   } while (false)
0241 #endif
0242 
0243 // ABSL_ASSUME(cond)
0244 //
0245 // Informs the compiler that a condition is always true and that it can assume
0246 // it to be true for optimization purposes.
0247 //
0248 // WARNING: If the condition is false, the program can produce undefined and
0249 // potentially dangerous behavior.
0250 //
0251 // In !NDEBUG mode, the condition is checked with an assert().
0252 //
0253 // NOTE: The expression must not have side effects, as it may only be evaluated
0254 // in some compilation modes and not others. Some compilers may issue a warning
0255 // if the compiler cannot prove the expression has no side effects. For example,
0256 // the expression should not use a function call since the compiler cannot prove
0257 // that a function call does not have side effects.
0258 //
0259 // Example:
0260 //
0261 //   int x = ...;
0262 //   ABSL_ASSUME(x >= 0);
0263 //   // The compiler can optimize the division to a simple right shift using the
0264 //   // assumption specified above.
0265 //   int y = x / 16;
0266 //
0267 #if !defined(NDEBUG)
0268 #define ABSL_ASSUME(cond) assert(cond)
0269 #elif ABSL_HAVE_BUILTIN(__builtin_assume)
0270 #define ABSL_ASSUME(cond) __builtin_assume(cond)
0271 #elif defined(_MSC_VER)
0272 #define ABSL_ASSUME(cond) __assume(cond)
0273 #elif defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
0274 #define ABSL_ASSUME(cond)            \
0275   do {                               \
0276     if (!(cond)) std::unreachable(); \
0277   } while (false)
0278 #elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
0279 #define ABSL_ASSUME(cond)                 \
0280   do {                                    \
0281     if (!(cond)) __builtin_unreachable(); \
0282   } while (false)
0283 #else
0284 #define ABSL_ASSUME(cond)               \
0285   do {                                  \
0286     static_cast<void>(false && (cond)); \
0287   } while (false)
0288 #endif
0289 
0290 // ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond)
0291 // This macro forces small unique name on a static file level symbols like
0292 // static local variables or static functions. This is intended to be used in
0293 // macro definitions to optimize the cost of generated code. Do NOT use it on
0294 // symbols exported from translation unit since it may cause a link time
0295 // conflict.
0296 //
0297 // Example:
0298 //
0299 // #define MY_MACRO(txt)
0300 // namespace {
0301 //  char VeryVeryLongVarName[] ABSL_INTERNAL_UNIQUE_SMALL_NAME() = txt;
0302 //  const char* VeryVeryLongFuncName() ABSL_INTERNAL_UNIQUE_SMALL_NAME();
0303 //  const char* VeryVeryLongFuncName() { return txt; }
0304 // }
0305 //
0306 
0307 #if defined(__GNUC__)
0308 #define ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) #x
0309 #define ABSL_INTERNAL_UNIQUE_SMALL_NAME1(x) ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x)
0310 #define ABSL_INTERNAL_UNIQUE_SMALL_NAME() \
0311   asm(ABSL_INTERNAL_UNIQUE_SMALL_NAME1(.absl.__COUNTER__))
0312 #else
0313 #define ABSL_INTERNAL_UNIQUE_SMALL_NAME()
0314 #endif
0315 
0316 #endif  // ABSL_BASE_OPTIMIZATION_H_