From 17f1bd79e251bd570ad79da2249f8e0bdaf5aa9f Mon Sep 17 00:00:00 2001 From: Fabrice Date: Mon, 23 Mar 2026 07:52:39 +0100 Subject: specialize for 8 byte and 16 byte groups --- cheesemap.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'cheesemap.c') diff --git a/cheesemap.c b/cheesemap.c index 4e56823..ade0659 100644 --- a/cheesemap.c +++ b/cheesemap.c @@ -6,9 +6,10 @@ #include #include -static inline uintptr_t cm_ctz(uintptr_t val) { +#define CM_ATTR(...) __attribute__((__VA_ARGS__)) + +CM_ATTR(hot) static inline uintptr_t cm_ctz(uintptr_t val) { assert(val != 0); -#if defined(__GNUC__) || defined(__clang__) #if UINTPTR_MAX == UINT64_MAX return (uintptr_t)__builtin_ctzll(val); #elif UINTPTR_MAX == UINT32_MAX @@ -16,14 +17,10 @@ static inline uintptr_t cm_ctz(uintptr_t val) { #else #error "unknown word width" #endif -#else -#error "ctz not implemented" -#endif } -static inline uintptr_t cm_clz(uintptr_t val) { +CM_ATTR(hot) static inline uintptr_t cm_clz(uintptr_t val) { assert(val != 0); -#if defined(__GNUC__) || defined(__clang__) #if UINTPTR_MAX == UINT64_MAX return (uintptr_t)__builtin_clzll(val); #elif UINTPTR_MAX == UINT32_MAX @@ -31,23 +28,38 @@ static inline uintptr_t cm_clz(uintptr_t val) { #else #error "unknown word width" #endif -#else -#error "clz not implemented" -#endif } -static inline uintptr_t cm_bitmask_lowest_set_bit(bitmask_t mask) { +CM_ATTR(hot) static inline uintptr_t cm_bitmask_lowest_set_bit(bitmask_t mask) { +#if CM_GROUP_SIZE == 8 return cm_ctz(mask) / CHAR_BIT; +#elif CM_GROUP_SIZE == 16 + return cm_ctz(mask) +#else +#error "unknown group size" +#endif } -static inline uintptr_t cm_bitmask_ctz(bitmask_t mask) { - if (mask == 0) return sizeof(mask) * CHAR_BIT / CHAR_BIT; +CM_ATTR(hot) static inline uintptr_t cm_bitmask_ctz(bitmask_t mask) { + if (mask == 0) return CM_GROUP_SIZE; +#if CM_GROUP_SIZE == 8 return cm_ctz(mask) / CHAR_BIT; +#elif CM_GROUP_SIZE == 16 + return cm_ctz(mask); +#else +#error "unknown group size" +#endif } -static inline uintptr_t cm_bitmask_clz(bitmask_t mask) { - if (mask == 0) return sizeof(mask) * CHAR_BIT / CHAR_BIT; +CM_ATTR(hot) static inline uintptr_t cm_bitmask_clz(bitmask_t mask) { + if (mask == 0) return CM_GROUP_SIZE; +#if CM_GROUP_SIZE == 8 return cm_clz(mask) / CHAR_BIT; +#elif CM_GROUP_SIZE == 16 + return cm_clz(mask); +#else +#error "unknown group size" +#endif } #define cm_max(x, y) x > y ? x : y -- cgit v1.2.3