Skip to content

Fix GH-14551: PGO build fails with xxhash #18814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix GH-14551: PGO build fails with xxhash
Turns out that the instrumentation added for gcov can change inlining
decisions of the compiler, which results in a mismatch between the
profile data CFG and the actual generated CFG between compiles.

There are two functions that suffer from this issue:
1. _PHP_XXH3_Init: Removing the inline hint fixes this one. In fact,
   always inlining this makes no sense as there's no real opportunity
   for specialising. It just bloats the binary and increases I$ pressure.
   So besides fixing this issue it's beneficial on its own to drop the
   attribute.
2. PHP_XXH3_128_Final: Sometimes XXH128_canonicalFromHash gets inlined
   and sometimes not. Make sure it gets always inlined.
  • Loading branch information
nielsdos committed Jun 9, 2025
commit c53c078f16e33d4b2e39e39afe8320f45a20b38a
2 changes: 1 addition & 1 deletion ext/hash/hash_xxhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const php_hash_ops php_hash_xxh3_64_ops = {
typedef XXH_errorcode (*xxh3_reset_with_secret_func_t)(XXH3_state_t*, const void*, size_t);
typedef XXH_errorcode (*xxh3_reset_with_seed_func_t)(XXH3_state_t*, XXH64_hash_t);

zend_always_inline static void _PHP_XXH3_Init(PHP_XXH3_64_CTX *ctx, HashTable *args,
static void _PHP_XXH3_Init(PHP_XXH3_64_CTX *ctx, HashTable *args,
xxh3_reset_with_seed_func_t func_init_seed, xxh3_reset_with_secret_func_t func_init_secret, const char* algo_name)
{
memset(&ctx->s, 0, sizeof ctx->s);
Expand Down
4 changes: 2 additions & 2 deletions ext/hash/xxhash/xxhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);

/******* Canonical representation *******/
typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
XXH_PUBLIC_API zend_always_inline void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);


Expand Down Expand Up @@ -5503,7 +5503,7 @@ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)

/*====== Canonical representation ======*/
/*! @ingroup xxh3_family */
XXH_PUBLIC_API void
XXH_PUBLIC_API zend_always_inline void
XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
{
XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t));
Expand Down
Loading