diff --git a/src/basic/siphash24.c b/src/basic/siphash24.c index b73ede34c8..fb40f3d6bd 100644 --- a/src/basic/siphash24.c +++ b/src/basic/siphash24.c @@ -26,13 +26,17 @@ #include "string-util.h" #include "unaligned.h" -static uint64_t rotate_left(uint64_t x, uint8_t b) { +/* The round is small enough that it is worth inlining at every call site, but large enough that gcc's + * -O2 inlining budget declines to do so on its own, leaving a call/ret and a reload of the state around + * six rounds of ~14 ALU ops. clang inlines it either way, and the SipHash reference implementation this + * file is derived from inlines the round manually, by writing it as a macro. */ +static inline _always_inline_ uint64_t rotate_left(uint64_t x, uint8_t b) { assert(b < 64); return (x << b) | (x >> (64 - b)); } -static void sipround(struct siphash *state) { +static inline _always_inline_ void sipround(struct siphash *state) { assert(state); state->v0 += state->v1; diff --git a/src/fundamental/macro.h b/src/fundamental/macro.h index 970bfbcf4c..ef12a0dfba 100644 --- a/src/fundamental/macro.h +++ b/src/fundamental/macro.h @@ -76,6 +76,7 @@ #define _align_(x) __attribute__((__aligned__(x))) #define _alignas_(x) __attribute__((__aligned__(alignof(x)))) #define _alignptr_ __attribute__((__aligned__(sizeof(void *)))) +#define _always_inline_ __attribute__((__always_inline__)) #define _cleanup_(x) __attribute__((__cleanup__(x))) #define _const_ __attribute__((__const__)) #define _deprecated_ __attribute__((__deprecated__))