Skip to content

Commit 596d4c8

Browse files
committed
Convert ZEND_ECHO operand to string during sccp
And filter out echoes of the empty string (e.g. false/null) Split out of php#5097
1 parent 9f4d1b9 commit 596d4c8

12 files changed

+86
-15
lines changed

ext/opcache/Optimizer/sccp.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,41 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
18291829
}
18301830
SET_RESULT_BOT(result);
18311831
break;
1832+
case ZEND_ECHO:
1833+
// fprintf(stderr, "optimizing ZEND_ECHO type=%d\n", Z_TYPE_P(op1));
1834+
SKIP_IF_TOP(op1);
1835+
if (IS_PARTIAL_ARRAY(op1)) {
1836+
break;
1837+
}
1838+
if (Z_TYPE_P(op1) == IS_STRING) {
1839+
/* already a string */
1840+
} else if (zend_optimizer_eval_cast(&zv, IS_STRING, op1) == SUCCESS) {
1841+
opline->op1_type = IS_CONST;
1842+
opline->op1.constant = zend_optimizer_add_literal(ctx->scdf.op_array, &zv);
1843+
op1 = get_op1_value(ctx, opline, ssa_op);
1844+
if (ssa_op->op1_use >= 0) {
1845+
ZEND_ASSERT(ssa_op->op1_def == -1);
1846+
zend_ssa_unlink_use_chain(ctx->scdf.ssa, ssa_op - ctx->scdf.ssa->ops, ssa_op->op1_use);
1847+
ssa_op->op1_use = -1;
1848+
ssa_op->op1_use_chain = -1;
1849+
}
1850+
} else {
1851+
break;
1852+
}
1853+
if (Z_STRLEN_P(op1) == 0) {
1854+
if (ssa_op->op1_use >= 0) {
1855+
ZEND_ASSERT(ssa_op->op1_def == -1);
1856+
zend_ssa_unlink_use_chain(ctx->scdf.ssa, ssa_op - ctx->scdf.ssa->ops, ssa_op->op1_use);
1857+
ssa_op->op1_use = -1;
1858+
ssa_op->op1_use_chain = -1;
1859+
}
1860+
MAKE_NOP(opline);
1861+
break;
1862+
}
1863+
/* TODO: In a subsequent pass, *after* inferring values and compacting nops, combine consecutive ZEND_ECHOs using the block information from ssa->cfg */
1864+
/* (e.g. for ext/opcache/tests/opt/sccp_010.phpt) */
1865+
/* https://github.com/php/php-src/pull/5097#issuecomment-577306560 */
1866+
break;
18321867
case ZEND_DO_ICALL:
18331868
{
18341869
zend_call_info *call;

ext/opcache/tests/opt/sccp_002.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ foo: ; (lines=4, args=1, vars=1, tmps=0)
3232
; (after optimizer)
3333
; %ssccp_002.php:2-12
3434
L0 (2): CV0($x) = RECV 1
35-
L1 (9): ECHO int(1)
36-
L2 (11): ECHO int(1)
35+
L1 (9): ECHO string("1")
36+
L2 (11): ECHO string("1")
3737
L3 (12): RETURN null

ext/opcache/tests/opt/sccp_003.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ L0 (14): RETURN int(1)
3131
foo: ; (lines=3, args=0, vars=0, tmps=0)
3232
; (after optimizer)
3333
; %ssccp_003.php:2-12
34-
L0 (9): ECHO int(1)
35-
L1 (11): ECHO int(1)
34+
L0 (9): ECHO string("1")
35+
L1 (11): ECHO string("1")
3636
L2 (12): RETURN null

ext/opcache/tests/opt/sccp_004.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ foo: ; (lines=4, args=1, vars=1, tmps=0)
3535
; (after optimizer)
3636
; %ssccp_004.php:2-15
3737
L0 (2): CV0($x) = RECV 1
38-
L1 (11): ECHO bool(true)
39-
L2 (14): ECHO int(1)
38+
L1 (11): ECHO string("1")
39+
L2 (14): ECHO string("1")
4040
L3 (15): RETURN null

ext/opcache/tests/opt/sccp_005.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0)
2525
; (after optimizer)
2626
; %ssccp_005.php:2-5
2727
L0 (2): CV0($x) = RECV 1
28-
L1 (4): ECHO int(2)
28+
L1 (4): ECHO string("2")
2929
L2 (5): RETURN null

ext/opcache/tests/opt/sccp_007.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0)
2929
; (after optimizer)
3030
; %ssccp_007.php:2-9
3131
L0 (2): CV0($x) = RECV 1
32-
L1 (8): ECHO int(0)
32+
L1 (8): ECHO string("0")
3333
L2 (9): RETURN null

ext/opcache/tests/opt/sccp_009.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0)
2626
; (after optimizer)
2727
; %ssccp_009.php:2-6
2828
L0 (2): CV0($x) = RECV 1
29-
L1 (5): ECHO int(2)
29+
L1 (5): ECHO string("2")
3030
L2 (6): RETURN null

ext/opcache/tests/opt/sccp_010.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ L0 (15): RETURN int(1)
3232
foo: ; (lines=3, args=0, vars=0, tmps=0)
3333
; (after optimizer)
3434
; %ssccp_010.php:2-13
35-
L0 (10): ECHO int(1)
36-
L1 (12): ECHO int(1)
35+
L0 (10): ECHO string("1")
36+
L1 (12): ECHO string("1")
3737
L2 (13): RETURN null

ext/opcache/tests/opt/sccp_011.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0)
3232
; (after optimizer)
3333
; %ssccp_011.php:2-12
3434
L0 (2): CV0($x) = RECV 1
35-
L1 (11): ECHO int(0)
35+
L1 (11): ECHO string("0")
3636
L2 (12): RETURN null

ext/opcache/tests/opt/sccp_012.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ L0 (17): RETURN int(1)
3434
foo: ; (lines=3, args=0, vars=0, tmps=0)
3535
; (after optimizer)
3636
; %ssccp_012.php:2-15
37-
L0 (10): ECHO int(1)
38-
L1 (14): ECHO int(4)
37+
L0 (10): ECHO string("1")
38+
L1 (14): ECHO string("4")
3939
L2 (15): RETURN null

ext/opcache/tests/opt/sccp_022.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ L1 (3): ASSIGN_DIM CV1($a) int(0)
3232
L2 (3): OP_DATA CV0($x)
3333
L3 (4): ASSIGN_DIM CV1($a) int(1)
3434
L4 (4): OP_DATA int(5)
35-
L5 (5): ECHO int(5)
35+
L5 (5): ECHO string("5")
3636
L6 (6): ASSIGN_OBJ CV1($a) string("foo")
3737
L7 (6): OP_DATA int(5)
3838
L8 (7): T2 = FETCH_DIM_R CV1($a) int(1)

ext/opcache/tests/opt/sccp_031.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
SCCP 031: Echo optimizations
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
opcache.opt_debug_level=0x20000
8+
opcache.preload=
9+
--SKIPIF--
10+
<?php require_once('skipif.inc'); ?>
11+
--FILE--
12+
<?php
13+
function foo() {
14+
$k = 0;
15+
$a = [null];
16+
echo isset($a[$k]);
17+
echo "b";
18+
echo isset($a[$k+1]);
19+
echo "c";
20+
echo $a[$k];
21+
echo $a; // Should not be optimized
22+
}
23+
?>
24+
--EXPECTF--
25+
$_main: ; (lines=1, args=0, vars=0, tmps=0)
26+
; (after optimizer)
27+
; %ssccp_031.php:1-13
28+
L0 (13): RETURN int(1)
29+
30+
foo: ; (lines=4, args=0, vars=0, tmps=0)
31+
; (after optimizer)
32+
; %s_031.php:2-11
33+
L0 (6): ECHO string("b")
34+
L1 (8): ECHO string("c")
35+
L2 (10): ECHO array(...)
36+
L3 (11): RETURN null

0 commit comments

Comments
 (0)