From cf2b5621d2e8e88dd00cd57bf3683f50440bee89 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 7 Nov 2024 11:09:33 +0100 Subject: [PATCH] MINOR: compiler: add a new "ASSUME" macro to help the compiler This macro takes an expression, tests it and calls an unreachable statement if false. This allows the compiler to know that such a combination does not happen, and totally eliminate tests that would be related to this condition. When the statement is not available in the compiler, we just perform a break from a do {} while loop so that the expression remains evaluated if needed (e.g. function call). (cherry picked from commit efc897484b8b875f908c144d82313923be8c3392) Signed-off-by: Willy Tarreau --- include/haproxy/compiler.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h index e0d8b01..725211d 100644 --- a/include/haproxy/compiler.h +++ b/include/haproxy/compiler.h @@ -207,6 +207,21 @@ #endif #endif +/* By using an unreachable statement, we can tell the compiler that certain + * conditions are not expected to be met and let it arrange as it wants to + * optimize some checks away. The principle is to place a test on the condition + * and call unreachable upon a match. It may also help static code analyzers + * know that some conditions are not supposed to happen. This can only be used + * with compilers that support it, and we do not want to emit any static code + * for other ones, so we use a construct that the compiler should easily be + * able to optimize away. + */ +#if __has_builtin(__builtin_unreachable) +# define ASSUME(expr) do { if (!(expr)) __builtin_unreachable(); } while (0) +#else +# define ASSUME(expr) do { if (!(expr)) break; } while (0) +#endif + /* This prevents the compiler from folding multiple identical code paths into a * single one, by adding a dependency on the line number in the path. This may * typically happen on function tails, or purposely placed abort() before an -- 1.7.10.4