Skip to content

opcache: re-enable PASS_15 (constant collection) by default#22007

Closed
wilaak wants to merge 2 commits into
php:masterfrom
wilaak:fix/inline-file-scope-const-declarations-master
Closed

opcache: re-enable PASS_15 (constant collection) by default#22007
wilaak wants to merge 2 commits into
php:masterfrom
wilaak:fix/inline-file-scope-const-declarations-master

Conversation

@wilaak
Copy link
Copy Markdown

@wilaak wilaak commented May 11, 2026

PASS_15 was disabled in Dec 2015 (940c68b, 4070279) to fix bug #71127.

define() values are not inlined; a sentinel entry also blocks inlining of any subsequent const redeclaration of the same name. Attributed constants are similarly blocked since their attributes need to fire at access time.

Not 100% sure every edge case is covered or if this is a good approach.

Dmitry, does this look safe to you?

Probably not worth it for the tiny benefit it provides. It only provides perf gains if you were to define and use it in the same file. Should I close this as it's a better idea to defer until the optimizer can do whole-program analysis?

@wilaak wilaak requested a review from dstogov as a code owner May 11, 2026 10:54
@wilaak wilaak force-pushed the fix/inline-file-scope-const-declarations-master branch from e57f1f4 to c5e2cf5 Compare May 11, 2026 12:20
Disabled in Dec 2015 (940c68b, 4070279) to fix bug #71127.

define() and attributed constants are blocked from inlining via a
sentinel entry. define() can be overridden at runtime (bug #71127)
and attributed constants need to fire at access time. The sentinel
also prevents inlining of any subsequent const redeclaration of the
same name.

Adds zend_optimizer_block_constant() for sentinel logic.
@wilaak wilaak force-pushed the fix/inline-file-scope-const-declarations-master branch from c5e2cf5 to 35cd64d Compare May 11, 2026 13:15
--FILE--
<?php

const CONST_VAL = 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also add tests for what happens if the constant is already declared in a separate file

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the constant is only declared in the separate file the optimizer can't inline it since the value is unknown at compile time, so it emits FETCH_CONSTANT.

If you also redeclare it locally the optimizer inlines the local value, but at runtime the required declaration wins and the local one warns. You get different results with and without opcache, so there's a real divergence there!

Comment thread ext/opcache/tests/pass1_const_inline_002.phpt
@dstogov
Copy link
Copy Markdown
Member

dstogov commented May 12, 2026

We can't enable this optimization by default because of the "stupid" PHP redeclaration behavior.

<?php
const X = 5;
const X = 42; // this emits warning and keeps X defined as 5
var_dump(X); // prints 5
?>

In general, constant may de defined in different files, and we can't use declaration from the current file, because it might be declared early.

@wilaak
Copy link
Copy Markdown
Author

wilaak commented May 12, 2026

That's stupid but I see now. Top level constants are all runtime unlike class constants. Hopefully some of that behaviour could change in the future.

@wilaak wilaak closed this May 12, 2026
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