[core] Add branch prediction annotations to Parrot. From: Mark Glines --- include/parrot/compiler.h | 8 ++++++++ include/parrot/exceptions.h | 4 ++-- src/gc/mark_sweep.c | 2 +- src/hash.c | 6 +++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/parrot/compiler.h b/include/parrot/compiler.h index 7657801..051718d 100644 --- a/include/parrot/compiler.h +++ b/include/parrot/compiler.h @@ -28,6 +28,14 @@ # define PARROT_HAS_SAL 0 #endif +#ifdef __GNUC__ +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +#else +# define likely(x) (x) +# define unlikely(x) (x) +#endif + #ifdef HASATTRIBUTE_NEVER_WORKS # error This attribute can never succeed. Something has mis-sniffed your configuration. #endif diff --git a/include/parrot/exceptions.h b/include/parrot/exceptions.h index 1c0a3a2..14def86 100644 --- a/include/parrot/exceptions.h +++ b/include/parrot/exceptions.h @@ -280,8 +280,8 @@ void Parrot_print_backtrace(void); # define PARROT_ASSERT_ARG(x) (0) # define ASSERT_ARGS(a) #else -# define PARROT_ASSERT(x) (x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__) -# define PARROT_ASSERT_ARG(x) ((x) ? (0) : (Parrot_confess(#x, __FILE__, __LINE__), 0)) +# define PARROT_ASSERT(x) likely(x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__) +# define PARROT_ASSERT_ARG(x) (likely(x) ? (0) : (Parrot_confess(#x, __FILE__, __LINE__), 0)) # ifdef __GNUC__ # define ASSERT_ARGS(a) ASSERT_ARGS_ ## a ; diff --git a/src/gc/mark_sweep.c b/src/gc/mark_sweep.c index 8c2b680..d482b6a 100644 --- a/src/gc/mark_sweep.c +++ b/src/gc/mark_sweep.c @@ -771,7 +771,7 @@ free_pmc_in_pool(PARROT_INTERP, SHIM(Small_Object_Pool *pool), Arenas * const arena_base = interp->arena_base; /* TODO collect objects with finalizers */ - if (PObj_needs_early_gc_TEST(p)) + if (unlikely(PObj_needs_early_gc_TEST(p))) --arena_base->num_early_gc_PMCs; if (PObj_active_destroy_TEST(p)) diff --git a/src/hash.c b/src/hash.c index 6d5dc0d..0bd7054 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1192,7 +1192,7 @@ parrot_hash_get_bucket(PARROT_INTERP, ARGIN(const Hash *hash), ARGIN(const void { ASSERT_ARGS(parrot_hash_get_bucket) - if (hash->entries <= 0) + if (unlikely(hash->entries <= 0)) return NULL; /* a very fast search for very small hashes */ @@ -1214,9 +1214,9 @@ parrot_hash_get_bucket(PARROT_INTERP, ARGIN(const Hash *hash), ARGIN(const void const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed); HashBucket *bucket = hash->bi[hashval & hash->mask]; - while (bucket) { + while (likely(bucket)) { /* key equality is always a match, so it's worth checking */ - if (bucket->key == key + if (unlikely(bucket->key == key) /* ... but the slower comparison is more accurate */ || ((hash->compare)(interp, key, bucket->key) == 0))