Skip to content

Commit 73514d6

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Reorder optimization passes to avoid miss-optimization
2 parents 992c806 + 1aa5e93 commit 73514d6

File tree

4 files changed

+55
-27
lines changed

4 files changed

+55
-27
lines changed

Zend/Optimizer/zend_optimizer.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,8 @@ static void zend_optimize(zend_op_array *op_array,
10141014
/* pass 9:
10151015
* - Optimize temp variables usage
10161016
*/
1017-
if (ZEND_OPTIMIZER_PASS_9 & ctx->optimization_level) {
1017+
if ((ZEND_OPTIMIZER_PASS_9 & ctx->optimization_level) &&
1018+
!(ZEND_OPTIMIZER_PASS_7 & ctx->optimization_level)) {
10181019
zend_optimize_temporary_variables(op_array, ctx);
10191020
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_9) {
10201021
zend_dump_op_array(op_array, 0, "after pass 9", NULL);
@@ -1517,6 +1518,15 @@ ZEND_API void zend_optimize_script(zend_script *script, zend_long optimization_l
15171518
}
15181519
}
15191520

1521+
if (ZEND_OPTIMIZER_PASS_9 & optimization_level) {
1522+
for (i = 0; i < call_graph.op_arrays_count; i++) {
1523+
zend_optimize_temporary_variables(call_graph.op_arrays[i], &ctx);
1524+
if (debug_level & ZEND_DUMP_AFTER_PASS_9) {
1525+
zend_dump_op_array(call_graph.op_arrays[i], 0, "after pass 9", NULL);
1526+
}
1527+
}
1528+
}
1529+
15201530
if (ZEND_OPTIMIZER_PASS_11 & optimization_level) {
15211531
for (i = 0; i < call_graph.op_arrays_count; i++) {
15221532
zend_optimizer_compact_literals(call_graph.op_arrays[i], &ctx);

ext/opcache/tests/opt/nullsafe_002.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ BB0:
3030
0000 RETURN int(1)
3131

3232
test:
33-
; (lines=7, args=1, vars=1, tmps=1, ssa_vars=6, no_loops)
33+
; (lines=7, args=1, vars=1, tmps=2, ssa_vars=6, no_loops)
3434
; (before dfa pass)
3535
; %s
3636
; return [null] RANGE[0..0]
@@ -41,7 +41,7 @@ BB0:
4141
; level=0
4242
; children=(BB1, BB2)
4343
0000 #1.CV0($test) [null, object (instanceof Test)] = RECV 1
44-
0001 INIT_FCALL 1 %d string("var_dump")
44+
0001 INIT_FCALL 1 96 string("var_dump")
4545
0002 #2.T1 [null] = JMP_NULL #1.CV0($test) [null, object (instanceof Test)] BB2
4646

4747
BB1:

ext/opcache/tests/opt/prop_types.phpt

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ BB0:
5050
0000 RETURN int(1)
5151

5252
noScope:
53-
; (lines=10, args=1, vars=1, tmps=1, ssa_vars=5, no_loops)
53+
; (lines=10, args=1, vars=1, tmps=4, ssa_vars=5, no_loops)
5454
; (before dfa pass)
5555
; %s
5656
; return [null] RANGE[0..0]
@@ -59,36 +59,36 @@ BB0:
5959
; start exit lines=[0-9]
6060
; level=0
6161
0000 #1.CV0($test) [object (instanceof Test)] = RECV 1
62-
0001 INIT_FCALL 3 %d string("var_dump")
62+
0001 INIT_FCALL 3 128 string("var_dump")
6363
0002 #2.T1 [bool] = FETCH_OBJ_R #1.CV0($test) [object (instanceof Test)] string("public")
6464
0003 SEND_VAL #2.T1 [bool] 1
65-
0004 #3.T1 [any] = FETCH_OBJ_R #1.CV0($test) [object (instanceof Test)] string("protected")
66-
0005 SEND_VAL #3.T1 [any] 2
67-
0006 #4.T1 [any] = FETCH_OBJ_R #1.CV0($test) [object (instanceof Test)] string("private")
68-
0007 SEND_VAL #4.T1 [any] 3
65+
0004 #3.T2 [any] = FETCH_OBJ_R #1.CV0($test) [object (instanceof Test)] string("protected")
66+
0005 SEND_VAL #3.T2 [any] 2
67+
0006 #4.T3 [any] = FETCH_OBJ_R #1.CV0($test) [object (instanceof Test)] string("private")
68+
0007 SEND_VAL #4.T3 [any] 3
6969
0008 DO_ICALL
7070
0009 RETURN null
7171

7272
Test::inTest:
73-
; (lines=9, args=0, vars=0, tmps=1, ssa_vars=3, no_loops)
73+
; (lines=9, args=0, vars=0, tmps=4, ssa_vars=3, no_loops)
7474
; (before dfa pass)
7575
; %s
7676
; return [null] RANGE[0..0]
7777
BB0:
7878
; start exit lines=[0-8]
7979
; level=0
80-
0000 INIT_FCALL 3 %d string("var_dump")
80+
0000 INIT_FCALL 3 128 string("var_dump")
8181
0001 #0.T0 [bool] = FETCH_OBJ_R THIS string("public")
8282
0002 SEND_VAL #0.T0 [bool] 1
83-
0003 #1.T0 [long] = FETCH_OBJ_R THIS string("protected")
84-
0004 SEND_VAL #1.T0 [long] 2
85-
0005 #2.T0 [double] = FETCH_OBJ_R THIS string("private")
86-
0006 SEND_VAL #2.T0 [double] 3
83+
0003 #1.T1 [long] = FETCH_OBJ_R THIS string("protected")
84+
0004 SEND_VAL #1.T1 [long] 2
85+
0005 #2.T2 [double] = FETCH_OBJ_R THIS string("private")
86+
0006 SEND_VAL #2.T2 [double] 3
8787
0007 DO_ICALL
8888
0008 RETURN null
8989

9090
Test::inTestWithTest2:
91-
; (lines=10, args=1, vars=1, tmps=1, ssa_vars=5, no_loops)
91+
; (lines=10, args=1, vars=1, tmps=4, ssa_vars=5, no_loops)
9292
; (before dfa pass)
9393
; %s
9494
; return [null] RANGE[0..0]
@@ -97,30 +97,30 @@ BB0:
9797
; start exit lines=[0-9]
9898
; level=0
9999
0000 #1.CV0($test2) [object (instanceof Test2)] = RECV 1
100-
0001 INIT_FCALL 3 %d string("var_dump")
100+
0001 INIT_FCALL 3 128 string("var_dump")
101101
0002 #2.T1 [bool] = FETCH_OBJ_R #1.CV0($test2) [object (instanceof Test2)] string("public")
102102
0003 SEND_VAL #2.T1 [bool] 1
103-
0004 #3.T1 [long] = FETCH_OBJ_R #1.CV0($test2) [object (instanceof Test2)] string("protected")
104-
0005 SEND_VAL #3.T1 [long] 2
105-
0006 #4.T1 [double] = FETCH_OBJ_R #1.CV0($test2) [object (instanceof Test2)] string("private")
106-
0007 SEND_VAL #4.T1 [double] 3
103+
0004 #3.T2 [long] = FETCH_OBJ_R #1.CV0($test2) [object (instanceof Test2)] string("protected")
104+
0005 SEND_VAL #3.T2 [long] 2
105+
0006 #4.T3 [double] = FETCH_OBJ_R #1.CV0($test2) [object (instanceof Test2)] string("private")
106+
0007 SEND_VAL #4.T3 [double] 3
107107
0008 DO_ICALL
108108
0009 RETURN null
109109

110110
Test2::inTest2:
111-
; (lines=9, args=0, vars=0, tmps=1, ssa_vars=3, no_loops)
111+
; (lines=9, args=0, vars=0, tmps=4, ssa_vars=3, no_loops)
112112
; (before dfa pass)
113113
; %s
114114
; return [null] RANGE[0..0]
115115
BB0:
116116
; start exit lines=[0-8]
117117
; level=0
118-
0000 INIT_FCALL 3 %d string("var_dump")
118+
0000 INIT_FCALL 3 128 string("var_dump")
119119
0001 #0.T0 [bool] = FETCH_OBJ_R THIS string("public")
120120
0002 SEND_VAL #0.T0 [bool] 1
121-
0003 #1.T0 [long] = FETCH_OBJ_R THIS string("protected")
122-
0004 SEND_VAL #1.T0 [long] 2
123-
0005 #2.T0 [array of [any, ref]] = FETCH_OBJ_R THIS string("private")
124-
0006 SEND_VAL #2.T0 [array of [any, ref]] 3
121+
0003 #1.T1 [long] = FETCH_OBJ_R THIS string("protected")
122+
0004 SEND_VAL #1.T1 [long] 2
123+
0005 #2.T2 [array of [any, ref]] = FETCH_OBJ_R THIS string("private")
124+
0006 SEND_VAL #2.T2 [array of [any, ref]] 3
125125
0007 DO_ICALL
126126
0008 RETURN null

ext/opcache/tests/opt/tmp_001.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
TMP variable optimization 001: TMP variable renumbering should be done after DFA optimizations
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
--FILE--
8+
<?php
9+
is_a((int)" $y " + 0);
10+
?>
11+
--EXPECTF--
12+
Warning: Undefined variable $y in %stmp_001.php on line 2
13+
14+
Fatal error: Uncaught ArgumentCountError: is_a() expects at least 2 arguments, 1 given in %stmp_001.php:2
15+
Stack trace:
16+
#0 %stmp_001.php(2): is_a(0)
17+
#1 {main}
18+
thrown in %stmp_001.php on line 2

0 commit comments

Comments
 (0)