From 145781a293b0a3dedd13308d14b9d08bfbefdfef Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 12 Jul 2021 20:21:14 +0100 Subject: [PATCH] Added COLD_EXPR() and HOT_EXPR() macros that (ab)use label attrs. Not sure of a better way to mark blocks/expressions as `cold` :/ I dunno if `if(UNLIKELY(1))` would work. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for naka's current commit: Great blessing − 大吉 --- include/macros.h | 26 ++++++++++++++++++++++++++ include/map.h | 1 + 2 files changed, 27 insertions(+) diff --git a/include/macros.h b/include/macros.h index e4586c5..fd44f4b 100644 --- a/include/macros.h +++ b/include/macros.h @@ -16,6 +16,9 @@ #define _pure __attribute__((const)) #define _readonly __attribute__((pure)) +#define _cold __attribute__((cold)) +#define _hot __attribute__((hot)) + #ifndef __cplusplus #define noreturn __attribute__((noreturn)) #define deprecated __attribute__((deprecated)) @@ -71,6 +74,21 @@ #define ifL(x) if(LIKELY((x))) #define ifU(x) if(UNLIKELY((x))) +#define COLD_EXPR(expr) ({ \ + goto _cold_expr; \ + UNREACHABLE_UNSAFE(); \ + _cold_expr: \ + __attribute__((cold)); \ + expr; \ + }) +#define HOT_EXPR(expr) ({ \ + goto _hot_expr; \ + UNREACHABLE_UNSAFE(); \ + _hot_expr: \ + __attribute__((hot)); \ + expr; \ + }) + /// Equivalent to GNU C `x ?: y` operator. #define TERN_OR(x, y) ({ let _x = (x); _x ? _x : (y); }) @@ -100,6 +118,14 @@ _mixin void _drain_val(void* x, ...) { IGNORE(x); } // This compiles to no-op on #define assert_msg(expr, ...) ( (expr) ? 1 : FATAL(__VA_ARGS__)) +#define UNREACHABLE_UNSAFE() __builtin_unreachable() + +#ifdef DEBUG +#define UNREACHABLE() do { COLD_EXPR(FATAL("unreachable code entered")); } while(0) +#else +#define UNREACHABLE() UNREACHABLE_UNSAFE() +#endif + #ifdef DEBUG #define debug_assert(x) assert((x)) #elif defined(_EVAL_DEBUG_ONLY_STMTS) diff --git a/include/map.h b/include/map.h index 96e5159..19fb4a5 100644 --- a/include/map.h +++ b/include/map.h @@ -68,6 +68,7 @@ _mixin int _map_handle_err(const char* stmt, const char* file, int line, const c return 0; } } + UNREACHABLE(); } #define map_handle_err(stmt) _map_handle_err(#stmt, __FILE__, __LINE__, __func__, stmt)