PHP 7.1からOPcacheに増えた設定値「opcache.opt_debug_level」とは何か

PHP 7.1からphp.iniの設定値として`opcache.opt_debug_level`というのが増えています。これを設定すると、OPcacheの最適化フェーズごとの最適化の様子が眺められるようです。

```php:/tmp/hoge.php
<?php
for ($i = 0; $i < 10; $i++) {
    for ($j = 0; $j < 10; $j++) {
        echo $i+$j, "\n";
    }
}
```

上記のようなプログラムがあったとしましょう。

```
$ php -dopcache.enable_cli=1 -dopcache.opt_debug_level=0xffffffff /tmp/hoge.php  > /dev/null
```

そこで上のようにタイプするとOPcacheの最適化の途中経過を眺めることができます。

```
$_main: ; (lines=16, args=0, vars=2, tmps=7)
    ; (before optimizer)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L13
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L9
L4:     T4 = ADD CV0($i) CV1($j)
L5:     ECHO T4
L6:     ECHO string("
")
L7:     T5 = POST_INC CV1($j)
L8:     FREE T5
L9:     T6 = IS_SMALLER CV1($j) int(10)
L10:    JMPNZ T6 L4
L11:    T7 = POST_INC CV0($i)
L12:    FREE T7
L13:    T8 = IS_SMALLER CV0($i) int(10)
L14:    JMPNZ T8 L2
L15:    RETURN int(1)

$_main: ; (lines=16, args=0, vars=2, tmps=7)
    ; (after pass 1)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L13
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L9
L4:     T4 = ADD CV0($i) CV1($j)
L5:     ECHO T4
L6:     ECHO string("
")
L7:     T5 = POST_INC CV1($j)
L8:     FREE T5
L9:     T6 = IS_SMALLER CV1($j) int(10)
L10:    JMPNZ T6 L4
L11:    T7 = POST_INC CV0($i)
L12:    FREE T7
L13:    T8 = IS_SMALLER CV0($i) int(10)
L14:    JMPNZ T8 L2
L15:    RETURN int(1)

$_main: ; (lines=16, args=0, vars=2, tmps=7)
    ; (after pass 2)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L13
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L9
L4:     T4 = ADD CV0($i) CV1($j)
L5:     ECHO T4
L6:     ECHO string("
")
L7:     T5 = POST_INC CV1($j)
L8:     FREE T5
L9:     T6 = IS_SMALLER CV1($j) int(10)
L10:    JMPNZ T6 L4
L11:    T7 = POST_INC CV0($i)
L12:    FREE T7
L13:    T8 = IS_SMALLER CV0($i) int(10)
L14:    JMPNZ T8 L2
L15:    RETURN int(1)

$_main: ; (lines=16, args=0, vars=2, tmps=7)
    ; (after pass 3)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L13
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L9
L4:     T4 = ADD CV0($i) CV1($j)
L5:     ECHO T4
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     NOP
L9:     T6 = IS_SMALLER CV1($j) int(10)
L10:    JMPNZ T6 L4
L11:    PRE_INC CV0($i)
L12:    NOP
L13:    T8 = IS_SMALLER CV0($i) int(10)
L14:    JMPNZ T8 L2
L15:    RETURN int(1)

$_main: ; (lines=16, args=0, vars=2, tmps=7)
    ; (after pass 4)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L13
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L9
L4:     T4 = ADD CV0($i) CV1($j)
L5:     ECHO T4
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     NOP
L9:     T6 = IS_SMALLER CV1($j) int(10)
L10:    JMPNZ T6 L4
L11:    PRE_INC CV0($i)
L12:    NOP
L13:    T8 = IS_SMALLER CV0($i) int(10)
L14:    JMPNZ T8 L2
L15:    RETURN int(1)

$_main: ; (lines=16, args=0, vars=2, tmps=7)
    ; (before block pass)
    ; /private/tmp/hoge.php:1-2
BB0: start lines=[0-1]
    ; to=(BB5)
        ASSIGN CV0($i) int(0)
        JMP BB5
BB1: target lines=[2-3]
    ; to=(BB3)
        ASSIGN CV1($j) int(0)
        JMP BB3
BB2: target lines=[4-8]
    ; to=(BB3)
        T4 = ADD CV0($i) CV1($j)
        ECHO T4
        ECHO string("
")
        PRE_INC CV1($j)
        NOP
BB3: follow target lines=[9-10]
    ; to=(BB2, BB4)
        T6 = IS_SMALLER CV1($j) int(10)
        JMPNZ T6 BB2
BB4: follow lines=[11-12]
    ; to=(BB5)
        PRE_INC CV0($i)
        NOP
BB5: follow target lines=[13-14]
    ; to=(BB1, BB6)
        T8 = IS_SMALLER CV0($i) int(10)
        JMPNZ T8 BB1
BB6: follow exit lines=[15-15]
        RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=7)
    ; (after block pass)
    ; /private/tmp/hoge.php:1-2
BB0: start lines=[0-1]
    ; to=(BB5)
        ASSIGN CV0($i) int(0)
        JMP BB5
BB1: target lines=[2-3]
    ; to=(BB3)
        ASSIGN CV1($j) int(0)
        JMP BB3
BB2: target lines=[4-7]
    ; to=(BB3)
        T4 = ADD CV0($i) CV1($j)
        ECHO T4
        ECHO string("
")
        PRE_INC CV1($j)
BB3: follow target lines=[8-9]
    ; to=(BB2, BB4)
        T6 = IS_SMALLER CV1($j) int(10)
        JMPNZ T6 BB2
BB4: follow lines=[10-10]
    ; to=(BB5)
        PRE_INC CV0($i)
BB5: follow target lines=[11-12]
    ; to=(BB1, BB6)
        T8 = IS_SMALLER CV0($i) int(10)
        JMPNZ T8 BB1
BB6: follow exit lines=[13-13]
        RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=7)
    ; (after pass 5)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L11
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L8
L4:     T4 = ADD CV0($i) CV1($j)
L5:     ECHO T4
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     T6 = IS_SMALLER CV1($j) int(10)
L9:     JMPNZ T6 L4
L10:    PRE_INC CV0($i)
L11:    T8 = IS_SMALLER CV0($i) int(10)
L12:    JMPNZ T8 L2
L13:    RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=1)
    ; (after pass 9)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L11
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L8
L4:     T2 = ADD CV0($i) CV1($j)
L5:     ECHO T2
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     T2 = IS_SMALLER CV1($j) int(10)
L9:     JMPNZ T2 L4
L10:    PRE_INC CV0($i)
L11:    T2 = IS_SMALLER CV0($i) int(10)
L12:    JMPNZ T2 L2
L13:    RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=1)
    ; (after pass 11)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L11
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L8
L4:     T2 = ADD CV0($i) CV1($j)
L5:     ECHO T2
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     T2 = IS_SMALLER CV1($j) int(10)
L9:     JMPNZ T2 L4
L10:    PRE_INC CV0($i)
L11:    T2 = IS_SMALLER CV0($i) int(10)
L12:    JMPNZ T2 L2
L13:    RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=1)
    ; (after optimizer)
    ; /private/tmp/hoge.php:1-2
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L11
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L8
L4:     T2 = ADD CV0($i) CV1($j)
L5:     ECHO T2
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     T2 = IS_SMALLER CV1($j) int(10)
L9:     JMPNZ T2 L4
L10:    PRE_INC CV0($i)
L11:    T2 = IS_SMALLER CV0($i) int(10)
L12:    JMPNZ T2 L2
L13:    RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=1)
    ; (dfa cfg)
    ; /private/tmp/hoge.php:1-2
    ; return  [] RANGE[0..0]
BB0: start lines=[0-1]
    ; to=(BB5)
        ASSIGN CV0($i) int(0)
        JMP BB5
BB1: target lines=[2-3]
    ; from=(BB5)
    ; to=(BB3)
        ASSIGN CV1($j) int(0)
        JMP BB3
BB2: target lines=[4-7]
    ; from=(BB3)
    ; to=(BB3)
        T2 = ADD CV0($i) CV1($j)
        ECHO T2
        ECHO string("
")
        PRE_INC CV1($j)
BB3: follow target lines=[8-9]
    ; from=(BB1, BB2)
    ; to=(BB2, BB4)
        T2 = IS_SMALLER CV1($j) int(10)
        JMPNZ T2 BB2
BB4: follow lines=[10-10]
    ; from=(BB3)
    ; to=(BB5)
        PRE_INC CV0($i)
BB5: follow target lines=[11-12]
    ; from=(BB0, BB4)
    ; to=(BB1, BB6)
        T2 = IS_SMALLER CV0($i) int(10)
        JMPNZ T2 BB1
BB6: follow exit lines=[13-13]
    ; from=(BB5)
        RETURN int(1)

DOMINATORS-TREE for "$_main"
BB0: start lines=[0-1]
    ; to=(BB5)
    ; level=0
    ; children=(BB5)
BB1: target lines=[2-3]
    ; from=(BB5)
    ; to=(BB3)
    ; idom=BB5
    ; level=2
    ; loop_header=2
    ; children=(BB3)
BB2: target lines=[4-7]
    ; from=(BB3)
    ; to=(BB3)
    ; idom=BB3
    ; level=4
    ; loop_header=4
BB3: follow target loop_header lines=[8-9]
    ; from=(BB1, BB2)
    ; to=(BB2, BB4)
    ; idom=BB1
    ; level=3
    ; loop_header=3
    ; children=(BB2, BB4)
BB4: follow lines=[10-10]
    ; from=(BB3)
    ; to=(BB5)
    ; idom=BB3
    ; level=4
    ; loop_header=4
BB5: follow target loop_header lines=[11-12]
    ; from=(BB0, BB4)
    ; to=(BB1, BB6)
    ; idom=BB0
    ; level=1
    ; children=(BB1, BB6)
BB6: follow exit lines=[13-13]
    ; from=(BB5)
    ; idom=BB5
    ; level=2

Variable Liveness for "$_main"
  BB0:
    ; def = {CV0($i)}
    ; use = {CV0($i)}
    ; in  = {CV0($i), CV1($j)}
    ; out = {CV0($i), CV1($j)}
  BB1:
    ; def = {CV1($j)}
    ; use = {CV1($j)}
    ; in  = {CV0($i), CV1($j)}
    ; out = {CV0($i), CV1($j)}
  BB2:
    ; def = {CV1($j), X2}
    ; use = {CV0($i), CV1($j)}
    ; in  = {CV0($i), CV1($j)}
    ; out = {CV0($i), CV1($j)}
  BB3:
    ; def = {X2}
    ; use = {CV1($j)}
    ; in  = {CV0($i), CV1($j)}
    ; out = {CV0($i), CV1($j)}
  BB4:
    ; def = {CV0($i)}
    ; use = {CV0($i)}
    ; in  = {CV0($i), CV1($j)}
    ; out = {CV0($i), CV1($j)}
  BB5:
    ; def = {X2}
    ; use = {CV0($i)}
    ; in  = {CV0($i), CV1($j)}
    ; out = {CV0($i), CV1($j)}
  BB6:
    ; def = {}
    ; use = {}
    ; in  = {}
    ; out = {}

SSA Phi() Placement for "$_main"
  BB1:
    ; pi={CV0($i)}
  BB2:
    ; pi={CV1($j)}
  BB3:
    ; phi={CV1($j)}
  BB4:
    ; pi={CV1($j)}
  BB5:
    ; phi={CV0($i), CV1($j)}

$_main: ; (lines=14, args=0, vars=2, tmps=1, ssa_vars=15)
    ; (before dfa pass)
    ; /private/tmp/hoge.php:1-2
    ; return  [] RANGE[0..0]
BB0: start lines=[0-1]
    ; to=(BB5)
    ; level=0
    ; children=(BB5)
        ASSIGN #0.CV0($i) -> #2.CV0($i) int(0)
        JMP BB5
BB1: target lines=[2-3]
    ; from=(BB5)
    ; to=(BB3)
    ; idom=BB5
    ; level=2
    ; loop_header=2
    ; children=(BB3)
        #6.CV0($i) = Pi<BB5>(#3.CV0($i) & RANGE[-- .. 9])
        ASSIGN #4.CV1($j) -> #7.CV1($j) int(0)
        JMP BB3
BB2: target lines=[4-7]
    ; from=(BB3)
    ; to=(BB3)
    ; idom=BB3
    ; level=4
    ; loop_header=4
        #10.CV1($j) = Pi<BB3>(#8.CV1($j) & RANGE[-- .. 9])
        #12.T2 = ADD #6.CV0($i) #10.CV1($j)
        ECHO #12.T2
        ECHO string("
")
        PRE_INC #10.CV1($j) -> #13.CV1($j)
BB3: follow target loop_header lines=[8-9]
    ; from=(BB1, BB2)
    ; to=(BB2, BB4)
    ; idom=BB1
    ; level=3
    ; loop_header=3
    ; children=(BB2, BB4)
        #8.CV1($j) = Phi(#7.CV1($j), #13.CV1($j))
        #9.T2 = IS_SMALLER #8.CV1($j) int(10)
        JMPNZ #9.T2 BB2
BB4: follow lines=[10-10]
    ; from=(BB3)
    ; to=(BB5)
    ; idom=BB3
    ; level=4
    ; loop_header=4
        #11.CV1($j) = Pi<BB3>(#8.CV1($j) & RANGE[10 .. ++])
        PRE_INC #6.CV0($i) -> #14.CV0($i)
BB5: follow target loop_header lines=[11-12]
    ; from=(BB0, BB4)
    ; to=(BB1, BB6)
    ; idom=BB0
    ; level=1
    ; children=(BB1, BB6)
        #3.CV0($i) = Phi(#2.CV0($i), #14.CV0($i))
        #4.CV1($j) = Phi(#1.CV1($j), #11.CV1($j))
        #5.T2 = IS_SMALLER #3.CV0($i) int(10)
        JMPNZ #5.T2 BB1
BB6: follow exit lines=[13-13]
    ; from=(BB5)
    ; idom=BB5
    ; level=2
        RETURN int(1)

SSA Variable for "$_main"
    #0.CV0($i) [undef, ref, any] *SCC=3
    #1.CV1($j) [undef, ref, any] *SCC=0
    #2.CV0($i) [ref, any] RANGE[0..0] *SCC=4
    #3.CV0($i) [ref, any] RANGE[0..10] *SCC=5
    #4.CV1($j) [undef, ref, any] *SCC=1
    #5.X2 [bool] RANGE[0..1] *SCC=7
    #6.CV0($i) [ref, any] RANGE[0..9]  SCC=5
    #7.CV1($j) [ref, any] RANGE[0..0]  SCC=1
    #8.CV1($j) [ref, any] RANGE[0..10]  SCC=1
    #9.X2 [bool] RANGE[0..1] *SCC=2
    #10.CV1($j) [ref, any] RANGE[0..9]  SCC=1
    #11.CV1($j) [ref, any] RANGE[10..10]  SCC=1
    #12.X2 [long, double, array of [any, ref]] RANGE[0..18] *SCC=6
    #13.CV1($j) [ref, any] RANGE[1..10]  SCC=1
    #14.CV0($i) [ref, any] RANGE[1..10]  SCC=5

$_main: ; (lines=14, args=0, vars=2, tmps=1, ssa_vars=15)
    ; (before dfa pass)
    ; /private/tmp/hoge.php:1-2
    ; return  [long] RANGE[1..1]
    ; #0.CV0($i) [undef, ref, any]
    ; #1.CV1($j) [undef, ref, any]
BB0: start lines=[0-1]
    ; to=(BB5)
    ; level=0
    ; children=(BB5)
        ASSIGN #0.CV0($i) [undef, ref, any] -> #2.CV0($i) [ref, any] RANGE[0..0] int(0)
        JMP BB5
BB1: target lines=[2-3]
    ; from=(BB5)
    ; to=(BB3)
    ; idom=BB5
    ; level=2
    ; loop_header=2
    ; children=(BB3)
        #6.CV0($i) [ref, any] RANGE[0..9] = Pi<BB5>(#3.CV0($i) [ref, any] RANGE[0..10] & RANGE[-- .. 9])
        ASSIGN #4.CV1($j) [undef, ref, any] -> #7.CV1($j) [ref, any] RANGE[0..0] int(0)
        JMP BB3
BB2: target lines=[4-7]
    ; from=(BB3)
    ; to=(BB3)
    ; idom=BB3
    ; level=4
    ; loop_header=4
        #10.CV1($j) [ref, any] RANGE[0..9] = Pi<BB3>(#8.CV1($j) [ref, any] RANGE[0..10] & RANGE[-- .. 9])
        #12.T2 [long, double, array of [any, ref]] RANGE[0..18] = ADD #6.CV0($i) [ref, any] RANGE[0..9] #10.CV1($j) [ref, any] RANGE[0..9]
        ECHO #12.T2 [long, double, array of [any, ref]] RANGE[0..18]
        ECHO string("
")
        PRE_INC #10.CV1($j) [ref, any] RANGE[0..9] -> #13.CV1($j) [ref, any] RANGE[1..10]
BB3: follow target loop_header lines=[8-9]
    ; from=(BB1, BB2)
    ; to=(BB2, BB4)
    ; idom=BB1
    ; level=3
    ; loop_header=3
    ; children=(BB2, BB4)
        #8.CV1($j) [ref, any] RANGE[0..10] = Phi(#7.CV1($j) [ref, any] RANGE[0..0], #13.CV1($j) [ref, any] RANGE[1..10])
        #9.T2 [bool] RANGE[0..1] = IS_SMALLER #8.CV1($j) [ref, any] RANGE[0..10] int(10)
        JMPNZ #9.T2 [bool] RANGE[0..1] BB2
BB4: follow lines=[10-10]
    ; from=(BB3)
    ; to=(BB5)
    ; idom=BB3
    ; level=4
    ; loop_header=4
        #11.CV1($j) [ref, any] RANGE[10..10] = Pi<BB3>(#8.CV1($j) [ref, any] RANGE[0..10] & RANGE[10 .. ++])
        PRE_INC #6.CV0($i) [ref, any] RANGE[0..9] -> #14.CV0($i) [ref, any] RANGE[1..10]
BB5: follow target loop_header lines=[11-12]
    ; from=(BB0, BB4)
    ; to=(BB1, BB6)
    ; idom=BB0
    ; level=1
    ; children=(BB1, BB6)
        #3.CV0($i) [ref, any] RANGE[0..10] = Phi(#2.CV0($i) [ref, any] RANGE[0..0], #14.CV0($i) [ref, any] RANGE[1..10])
        #4.CV1($j) [undef, ref, any] = Phi(#1.CV1($j) [undef, ref, any], #11.CV1($j) [ref, any] RANGE[10..10])
        #5.T2 [bool] RANGE[0..1] = IS_SMALLER #3.CV0($i) [ref, any] RANGE[0..10] int(10)
        JMPNZ #5.T2 [bool] RANGE[0..1] BB1
BB6: follow exit lines=[13-13]
    ; from=(BB5)
    ; idom=BB5
    ; level=2
        RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=1, ssa_vars=15)
    ; (after dfa pass)
    ; /private/tmp/hoge.php:1-2
    ; return  [long] RANGE[1..1]
    ; #0.CV0($i) [undef, ref, any]
    ; #1.CV1($j) [undef, ref, any]
BB0: start lines=[0-1]
    ; to=(BB5)
    ; level=0
    ; children=(BB5)
        ASSIGN #0.CV0($i) [undef, ref, any] -> #2.CV0($i) [ref, any] RANGE[0..0] int(0)
        JMP BB5
BB1: target lines=[2-3]
    ; from=(BB5)
    ; to=(BB3)
    ; idom=BB5
    ; level=2
    ; loop_header=2
    ; children=(BB3)
        #6.CV0($i) [ref, any] RANGE[0..9] = Pi<BB5>(#3.CV0($i) [ref, any] RANGE[0..10] & RANGE[-- .. 9])
        ASSIGN #4.CV1($j) [undef, ref, any] -> #7.CV1($j) [ref, any] RANGE[0..0] int(0)
        JMP BB3
BB2: target lines=[4-7]
    ; from=(BB3)
    ; to=(BB3)
    ; idom=BB3
    ; level=4
    ; loop_header=4
        #10.CV1($j) [ref, any] RANGE[0..9] = Pi<BB3>(#8.CV1($j) [ref, any] RANGE[0..10] & RANGE[-- .. 9])
        #12.T2 [long, double, array of [any, ref]] RANGE[0..18] = ADD #6.CV0($i) [ref, any] RANGE[0..9] #10.CV1($j) [ref, any] RANGE[0..9]
        ECHO #12.T2 [long, double, array of [any, ref]] RANGE[0..18]
        ECHO string("
")
        PRE_INC #10.CV1($j) [ref, any] RANGE[0..9] -> #13.CV1($j) [ref, any] RANGE[1..10]
BB3: follow target loop_header lines=[8-9]
    ; from=(BB1, BB2)
    ; to=(BB2, BB4)
    ; idom=BB1
    ; level=3
    ; loop_header=3
    ; children=(BB2, BB4)
        #8.CV1($j) [ref, any] RANGE[0..10] = Phi(#7.CV1($j) [ref, any] RANGE[0..0], #13.CV1($j) [ref, any] RANGE[1..10])
        #9.T2 [bool] RANGE[0..1] = IS_SMALLER #8.CV1($j) [ref, any] RANGE[0..10] int(10)
        JMPNZ #9.T2 [bool] RANGE[0..1] BB2
BB4: follow lines=[10-10]
    ; from=(BB3)
    ; to=(BB5)
    ; idom=BB3
    ; level=4
    ; loop_header=4
        #11.CV1($j) [ref, any] RANGE[10..10] = Pi<BB3>(#8.CV1($j) [ref, any] RANGE[0..10] & RANGE[10 .. ++])
        PRE_INC #6.CV0($i) [ref, any] RANGE[0..9] -> #14.CV0($i) [ref, any] RANGE[1..10]
BB5: follow target loop_header lines=[11-12]
    ; from=(BB0, BB4)
    ; to=(BB1, BB6)
    ; idom=BB0
    ; level=1
    ; children=(BB1, BB6)
        #3.CV0($i) [ref, any] RANGE[0..10] = Phi(#2.CV0($i) [ref, any] RANGE[0..0], #14.CV0($i) [ref, any] RANGE[1..10])
        #4.CV1($j) [undef, ref, any] = Phi(#1.CV1($j) [undef, ref, any], #11.CV1($j) [ref, any] RANGE[10..10])
        #5.T2 [bool] RANGE[0..1] = IS_SMALLER #3.CV0($i) [ref, any] RANGE[0..10] int(10)
        JMPNZ #5.T2 [bool] RANGE[0..1] BB1
BB6: follow exit lines=[13-13]
    ; from=(BB5)
    ; idom=BB5
    ; level=2
        RETURN int(1)

$_main: ; (lines=14, args=0, vars=2, tmps=1)
    ; (after pass 7)
    ; /private/tmp/hoge.php:1-2
    ; return  [long] RANGE[1..1]
L0:     ASSIGN CV0($i) int(0)
L1:     JMP L11
L2:     ASSIGN CV1($j) int(0)
L3:     JMP L8
L4:     T2 = ADD CV0($i) CV1($j)
L5:     ECHO T2
L6:     ECHO string("
")
L7:     PRE_INC CV1($j)
L8:     T2 = IS_SMALLER CV1($j) int(10)
L9:     JMPNZ T2 L4
L10:    PRE_INC CV0($i)
L11:    T2 = IS_SMALLER CV0($i) int(10)
L12:    JMPNZ T2 L2
L13:    RETURN int(1)
```

うむ、全然わからん！

とはいえ多少読み解ける部分もあったりします。たとえば、`$i++`に相当する処理が最初のうちは

```
L11:    T7 = POST_INC CV0($i)
L12:    FREE T7
```

と2命令だったのが最終的には次のように1命令になっていることがわかったりするわけです。

```
L10:    PRE_INC CV0($i)
```

また、上記ログ中に「SSA」という単語も見えます。これはコンパイラ等でよく用いられる[静的単一代入](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E5%8D%98%E4%B8%80%E4%BB%A3%E5%85%A5)（Static Single Assignment form）の意味でしょう。昔はOPcacheでSSAを作ったりしていなかったと思うので、PHP 7.0の頃より賢い最適化が実現できているのかもしれませんね。


**「おい、なんだか変なログが見えるぞ！」** というだけのメモなので、興味を持った方は夏休みの宿題として追いかけてみてください（丸投げ）