Hi Dimitry,
Thank you for the acknowledgment. I am a big fan of your work.
I think adding the suggested changes to foreach will be a good improvement. With foreach one cold actually merge the jump-into-opcode (line 0 in the while-loop example) with FE_RESET.
On another note, I think there are many simple compiler optimizations (without the need for real code analysis) that should now be possible, especially in light of AST. The following samples of common patterns come to mind:
if/while (! ...)
BOOL_NOT+JMPZ -> JMPNZ
if/while ( ... &&/|| ... )
BOOL+JMPZ -> JMPZ (BOOL is obsolete)
case (...)
CASE+JMPZ -> CASE (add JMPZ functionality to CASE operation)
I understand that these aren't huge improvements per se, but they are very common and could at least help reduce the generated bytecode size (thinking OpCache).
Cheers,
Ben
========== Original ==========
From: Dmitry Stogov dmitry@zend.com
To: Benjamin Coutu ben.coutu@zeyos.com
Date: Fri, 16 Jan 2015 17:12:34 +0100
Subject: Re: [PHP-DEV] Generating more efficient code for while-loop
Hi Benjamin,
Thanks for idea.
With PHP7 AST compiler, it's quite easy to implement this (it took us 15
minutes to try :)
However, it doesn't make big improvement on our benchmarks.
We will take a look into possibilities to apply your idea to other patterns
(e.g. for and foreach loops).
Anyway, it makes full sense to include this optimization into PHP7.
I just like to try other opportunities first.
Thanks. Dmitry.
On Fri, Jan 16, 2015 at 10:56 AM, Benjamin Coutu ben.coutu@zeyos.com
wrote:
Hello,
Please consider the following PHP code:
while ( <CONDITION> ) {
<STATEMENT>
}It currently compiles to something like this for the Zend Engine:
0: <CONDITION>
1: JMPZ -> 4
2: <STATEMENT>
3: JMP -> 0
4: ...This can easily be rewritten in an equivalent but much more efficient form:
0: JMP -> 2
1: <STATEMENT>
2: <CONDITION>
3: JMPNZ -> 1The trick is to jump to the conditional expression before the first
iteration and then only having to continue with just on conditional jump on
every subsequent cycle.This would result in only 1 jump per loop iteration compared to
effectively 2 jumps needed per iteration with the current implementation.It would also make the loop tighter as upon entering the loop (after first
conditional evaluation), one less opcode remains relevant to the loop.An analogous approach can be taken for the for-loop.
Thanks,
Ben
PS: This is my first post on a PHP mailinglist - I am very excited! :)
--
Benjamin Coutu
Zeyon Technologies Inc.
http://www.zeyos.com