aboutsummaryrefslogtreecommitdiff
path: root/absl/base/optimization.h
diff options
context:
space:
mode:
authorBenjamin Barenblat <bbaren@google.com>2023-05-08 12:51:08 -0400
committerBenjamin Barenblat <bbaren@google.com>2023-05-08 12:51:08 -0400
commitc15cec707b1c7d847e59d2db4d0b82b711a7ee6d (patch)
tree79f448d5bbc8cf52917b0b091f0e1ab60a419c85 /absl/base/optimization.h
parentf4f2c1da90c4e6a0683c4e66c0268baa1b79cdf3 (diff)
parentc2435f8342c2d0ed8101cb43adfd605fdc52dca2 (diff)
downloadabseil-c15cec707b1c7d847e59d2db4d0b82b711a7ee6d.tar.gz
abseil-c15cec707b1c7d847e59d2db4d0b82b711a7ee6d.tar.bz2
abseil-c15cec707b1c7d847e59d2db4d0b82b711a7ee6d.zip
Merge new upstream LTS 20230125.3
Diffstat (limited to 'absl/base/optimization.h')
-rw-r--r--absl/base/optimization.h64
1 files changed, 58 insertions, 6 deletions
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index db5cc097..ad0121ad 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -91,6 +91,7 @@
#define ABSL_CACHELINE_SIZE 64
#endif
#endif
+#endif
#ifndef ABSL_CACHELINE_SIZE
// A reasonable default guess. Note that overestimates tend to waste more
@@ -141,12 +142,11 @@
// the generated machine code.
// 3) Prefer applying this attribute to individual variables. Avoid
// applying it to types. This tends to localize the effect.
+#if defined(__clang__) || defined(__GNUC__)
#define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE)))
#elif defined(_MSC_VER)
-#define ABSL_CACHELINE_SIZE 64
#define ABSL_CACHELINE_ALIGNED __declspec(align(ABSL_CACHELINE_SIZE))
#else
-#define ABSL_CACHELINE_SIZE 64
#define ABSL_CACHELINE_ALIGNED
#endif
@@ -181,6 +181,53 @@
#define ABSL_PREDICT_TRUE(x) (x)
#endif
+// `ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL()` aborts the program in the fastest
+// possible way, with no attempt at logging. One use is to implement hardening
+// aborts with ABSL_OPTION_HARDENED. Since this is an internal symbol, it
+// should not be used directly outside of Abseil.
+#if ABSL_HAVE_BUILTIN(__builtin_trap) || \
+ (defined(__GNUC__) && !defined(__clang__))
+#define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() __builtin_trap()
+#else
+#define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() abort()
+#endif
+
+// `ABSL_INTERNAL_UNREACHABLE_IMPL()` is the platform specific directive to
+// indicate that a statement is unreachable, and to allow the compiler to
+// optimize accordingly. Clients should use `ABSL_UNREACHABLE()`, which is
+// defined below.
+#if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
+#define ABSL_INTERNAL_UNREACHABLE_IMPL() std::unreachable()
+#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
+#define ABSL_INTERNAL_UNREACHABLE_IMPL() __builtin_unreachable()
+#elif ABSL_HAVE_BUILTIN(__builtin_assume)
+#define ABSL_INTERNAL_UNREACHABLE_IMPL() __builtin_assume(false)
+#elif defined(_MSC_VER)
+#define ABSL_INTERNAL_UNREACHABLE_IMPL() __assume(false)
+#else
+#define ABSL_INTERNAL_UNREACHABLE_IMPL()
+#endif
+
+// `ABSL_UNREACHABLE()` is an unreachable statement. A program which reaches
+// one has undefined behavior, and the compiler may optimize accordingly.
+#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
+// Abort in hardened mode to avoid dangerous undefined behavior.
+#define ABSL_UNREACHABLE() \
+ do { \
+ ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(); \
+ ABSL_INTERNAL_UNREACHABLE_IMPL(); \
+ } while (false)
+#else
+// The assert only fires in debug mode to aid in debugging.
+// When NDEBUG is defined, reaching ABSL_UNREACHABLE() is undefined behavior.
+#define ABSL_UNREACHABLE() \
+ do { \
+ /* NOLINTNEXTLINE: misc-static-assert */ \
+ assert(false && "ABSL_UNREACHABLE reached"); \
+ ABSL_INTERNAL_UNREACHABLE_IMPL(); \
+ } while (false)
+#endif
+
// ABSL_ASSUME(cond)
//
// Informs the compiler that a condition is always true and that it can assume
@@ -209,18 +256,23 @@
#define ABSL_ASSUME(cond) assert(cond)
#elif ABSL_HAVE_BUILTIN(__builtin_assume)
#define ABSL_ASSUME(cond) __builtin_assume(cond)
+#elif defined(_MSC_VER)
+#define ABSL_ASSUME(cond) __assume(cond)
+#elif defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
+#define ABSL_ASSUME(cond) \
+ do { \
+ if (!(cond)) std::unreachable(); \
+ } while (false)
#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable)
#define ABSL_ASSUME(cond) \
do { \
if (!(cond)) __builtin_unreachable(); \
- } while (0)
-#elif defined(_MSC_VER)
-#define ABSL_ASSUME(cond) __assume(cond)
+ } while (false)
#else
#define ABSL_ASSUME(cond) \
do { \
static_cast<void>(false && (cond)); \
- } while (0)
+ } while (false)
#endif
// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond)