Skip to content

configure: disable Apple clang size optimizations that hurt runtime speed - #23080

Open
staabm wants to merge 1 commit into
php:masterfrom
staabm:apple
Open

configure: disable Apple clang size optimizations that hurt runtime speed#23080
staabm wants to merge 1 commit into
php:masterfrom
staabm:apple

Conversation

@staabm

@staabm staabm commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

disclaimer: this change was generated by claude opus. I have little experience with php-src development


Apple clang enables the AArch64 machine outliner and hot/cold code splitting by default at -O2. Both trade speed for size: the outliner inserts extra bl/ret pairs into hot paths (measured inside the inlined zval destructor loops of zend_array_destroy, among others), and cold-split fragments (4700+ in a default cli build) are compiled for size, which mispredicted branch hints turn into slow hot code.

Disabling both speeds up a CPU-bound static analysis workload (PHPStan analysing its own codebase, no opcache) by ~4% wall time on an Apple M-series machine. The flags are added only when the compiler accepts them (-Werror guards against clang's unknown -m flag warnings), so non-Apple toolchains are unaffected.


benchmark (3 runs after 2 warmup runs):

run /Users/staabm/workspace/php-src/sapi/cli/php bin/phpstan clear-result-cache -q && /Users/staabm/workspace/php-src/sapi/cli/php -d memory_limit=450M bin/phpstan -v after checking out phpstan/phpstan-src#5942 from the git root folder.
(on first time phpstan-src checkout you need composer install and make to prepare the codebase)

before this PR:
14,47s
14,87s
14,60s

after this PR:
13,91s
13,68s
13,86s

on M4-Pro with macOS 26.6 (25G72)

…peed

Apple clang enables the AArch64 machine outliner and hot/cold code
splitting by default at -O2. Both trade speed for size: the outliner
inserts extra bl/ret pairs into hot paths (measured inside the inlined
zval destructor loops of zend_array_destroy, among others), and
cold-split fragments (4700+ in a default cli build) are compiled for
size, which mispredicted branch hints turn into slow hot code.

Disabling both speeds up a CPU-bound static analysis workload (PHPStan
analysing its own codebase, no opcache) by ~4% wall time on an Apple
M-series machine. The flags are added only when the compiler accepts
them (-Werror guards against clang's unknown -m flag warnings), so
non-Apple toolchains are unaffected.
@realFlowControl

Copy link
Copy Markdown
Contributor

I played with this PR locally on my M4 Max and can confirm the speedup:

Metric Baseline (master) PR (-mno-outline -Xclang -fno-split-cold-code)
Mean 8.485s 8.194s
Median 8.446s 8.213s
Stdev 0.059s 0.058s
Speedup 3.4%

With this setup:

  • Compiler: Apple clang 21.0.0 (clang-2100.1.1.101)
  • PHP: 8.6.0-dev, built from same commit (e9deb0a), default ./configure
  • PHPStan 2.2.5, level 6, analysing Sylius src/ (v2.2.7-dev)
  • 2 warmup runs + 5 alternating timed runs, result cache cleared before each run

One interesting caveat: When compiling PHP with clang from Homebrew I would not see any difference because:

  • -mno-outline is accepted but is a no-op: upstream LLVM (Homebrew) does not enable the AArch64 machine outliner by default at -O2, unlike Apple clang.
  • -Xclang -fno-split-cold-code is specific to Apple clang and the Homebrew version rejects those flags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants