IS_VAR
or IS_CV
operand, but only in IS_CONST
or sometimes in IS_TMP_VAR
.IS_CONST
; We can also replace some OPCodes by others (more optimized at runtime), we also find and trash dead code branches by using a CFG (control flow graph) analysis, but we don't unroll loops, or process to loop invariant motions as such optimizations are hard to apply to PHP.opcache.optimization_level
. It should represent a mask for optimizations you'd like to see enabled, based on their binary values:if(false)
branch has been trashed, the Zend VM executor will then simply have to run a ZEND_ECHO
OPcode. We then saved some memory, because we threw away some OPCodes, and we may save a little bit of CPU cycles at runtime as well.IS_CV
operand instead of IS_CONST
, could not have been optimized:__DIR__
will be substituted and the equality check will be performed by the PHP 7 compiler, that is without OPcache. However, the branch analysis and the branch dead code removing is still done by an OPcache optimizer pass.__DIR__
is still substituted, but the equality check is not performed by PHP 5 compiler. This latter is performed by OPcache.IS_TMP_VAR
to IS_CONST
. That is, OPcache can compute itself at compile-time, some known values.function_exists()
and is_callable()
, for internal functions only.
* extension_loaded()
, if dl()
is disabled in userland.
* defined()
and constant()
for internal constants only.
* dirname()
if the argument is constant.
* strlen()
and dirname()
with constant argument (PHP 7 only).my_custom_function
is another file. And remember, the PHP compiler and OPcache optimizer only works on a file basis. Even if you do this:dirname()
(PHP 7 only):strlen()
is optimized in PHP 7. If we chain them together, we obviously meet a nice optimization. Like this:IS_CONST
operand types, when it knows runtime will have to transtype them. That effectively saves some CPU cycles at runtime:ZEND_ADD
operation; it has switched from a string to an int
. The optimizer did the job of transtyping the argument type for the math add operation. If it had not; the runtime VM would have done it again, and again, and again as the code is run again, and again, and again. This saves some CPU cycles involved in the transtyping operation.IS_CONST
expressions, the result can then be computed at compile-time, something the PHP compiler does not do by default in PHP 5, OPcache optimizer is needed:4 + 33
, and erased the ZEND_ADD
operation to be run by replacing it directly by the result. This saves again some CPU at runtime, as the VM executor now has less job to do. Here again, this is done in PHP 7 by the compiler, whereas in PHP 5 you would need OPcache optimizer to do that.ZEND_ADD
plus a ZEND_ASSIGN
, into a ZEND_ASSIGN_ADD
, usually involved in statements such as $i+=3;
ZEND_ASSIGN_ADD
is more optimized, it is one OPCode instead of two (which usually is better, but not every time).$i++
by a ++$i
statement, because it had the same meaning in this piece of code. ZEND_POST_INC
is not very nice OPCode, because it must read the value, return it as-is, but increment a temporary value in memory, whereas ZEND_PRE_INC
plays with the value itself, and reads it, increments it and returns it (this is just the PRE vs POST incrementation difference).ZEND_POST_INC
is not used in the script above, the compiler must issue a ZEND_FREE
OPCode, to free it from memory. OPcache optimizer turns the structure into a ZEND_PRE_INC
, and removes the useless ZEND_FREE
; less job to figure out at runtime.define()
function can be replaced by a const
statement, if its argument is constant:define()
is ugly, because it declares a constant but runs such a job at runtime, issuing a function call (define()
is really a function). This is very bad.const
keyword leads to a DECLARE_CONST
OPCode. Note that in PHP 7, define()
may lead to a const construct into the compiler directly (no optimizer needed).if
, switch
, while
, try
, foreach
, ?:
... are PHP statements making a decision, if the decision is true: jump to branch A, if not, jump to branch B.while
into an if
, in which a goto
is performed, leading to a switch
which performs try-catches
, etc...