9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-08-10

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

/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」という単語も見えます。これはコンパイラ等でよく用いられる静的単一代入(Static Single Assignment form)の意味でしょう。昔はOPcacheでSSAを作ったりしていなかったと思うので、PHP 7.0の頃より賢い最適化が実現できているのかもしれませんね。

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

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?