summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund2025-07-09 22:38:05 +0000
committerAndres Freund2025-07-09 22:38:05 +0000
commitd65eb5b1b84e9104144b6b07b526bc73e819d6d7 (patch)
tree683e0005b3b1bcdecdaf9256c7b35d380235d5d9
parent4df477153a6b9339acafbf4162fd8fa3f33e89d2 (diff)
Add pg_assume(expr) macro
This macro can be used to avoid compiler warnings, particularly when using -O3 and not using assertions, and to get the compiler to generate better code. A subsequent commit introduces a first user. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/3prdb6hkep3duglhsujrn52bkvnlkvhc54fzvph2emrsm4vodl@77yy6j4hkemb Discussion: https://postgr.es/m/20230316172818.x6375uvheom3ibt2%40awork3.anarazel.de Discussion: https://postgr.es/m/20240207203138.sknifhlppdtgtxnk%40awork3.anarazel.de
-rw-r--r--src/include/c.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/include/c.h b/src/include/c.h
index 04fd23577de..6d4495bdd9f 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -333,6 +333,36 @@
#endif
/*
+ * pg_assume(expr) states that we assume `expr` to evaluate to true. In assert
+ * enabled builds pg_assume() is turned into an assertion, in optimized builds
+ * we try to clue the compiler into the fact that `expr` is true.
+ *
+ * This is useful for two purposes:
+ *
+ * 1) Avoid compiler warnings by telling the compiler about assumptions the
+ * code makes. This is particularly useful when building with optimizations
+ * and w/o assertions.
+ *
+ * 2) Help the compiler to generate more efficient code
+ *
+ * It is unspecified whether `expr` is evaluated, therefore it better be
+ * side-effect free.
+ */
+#if defined(USE_ASSERT_CHECKING)
+#define pg_assume(expr) Assert(expr)
+#elif defined(HAVE__BUILTIN_UNREACHABLE)
+#define pg_assume(expr) \
+ do { \
+ if (!(expr)) \
+ __builtin_unreachable(); \
+ } while (0)
+#elif defined(_MSC_VER)
+#define pg_assume(expr) __assume(expr)
+#else
+#define pg_assume(expr) ((void) 0)
+#endif
+
+/*
* Hints to the compiler about the likelihood of a branch. Both likely() and
* unlikely() return the boolean value of the contained expression.
*