diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 1ba47c194b..42c5e052b6 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -219,6 +219,19 @@ err_gettext(const char *str) #endif } +/* + * errstart_cold + * A simple wrapper around errstart, but hinted to be "cold". Supporting + * compilers are more likely to move code for branches containing this + * function into an area away from the calling function's code. This can + * result in more commonly executed code being more compact and fitting + * on fewer cache lines. + */ +pg_attribute_cold bool +errstart_cold(int elevel, const char *domain) +{ + return errstart(elevel, domain); +} /* * errstart --- begin an error-reporting cycle diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 1e09ee0541..270bfbcfe5 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -111,6 +111,15 @@ * ereport_domain() directly, or preferably they can override the TEXTDOMAIN * macro. * + * When __builtin_constant_p is available and elevel >= ERROR we make a call + * to errstart_cold() instead of errstart(). This version of the function is + * marked with pg_attribute_cold which will coax supporting compilers into + * generating code which is more optimized towards non-ERROR cases. Because + * we use __builtin_constant_p() in the condition, when elevel is not a + * compile-time constant, or if it is, but it's < ERROR, the compiler has no + * need to generate any code for this branch. It can simply call errstart() + * unconditionally. + * * If elevel >= ERROR, the call will not return; we try to inform the compiler * of that via pg_unreachable(). However, no useful optimization effect is * obtained unless the compiler sees elevel as a compile-time constant, else @@ -124,7 +133,9 @@ #define ereport_domain(elevel, domain, ...) \ do { \ pg_prevent_errno_in_scope(); \ - if (errstart(elevel, domain)) \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR ? \ + errstart_cold(elevel, domain) : \ + errstart(elevel, domain)) \ __VA_ARGS__, errfinish(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ pg_unreachable(); \ @@ -146,6 +157,7 @@ #define TEXTDOMAIN NULL +extern bool pg_attribute_cold errstart_cold(int elevel, const char *domain); extern bool errstart(int elevel, const char *domain); extern void errfinish(const char *filename, int lineno, const char *funcname);