From: Tyson Andre Date: Sun, 7 Jun 2020 17:17:40 +0000 (-0400) Subject: Optimize out no-op `yield from` statements X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=543684e7962073dcae3ecdd9504211876e630bec;p=php Optimize out no-op `yield from` statements If the array is empty, then I'd expect that the generator is never left, and that can be converted to a no-op and the return value would always be `null`. Make `yield from [];` as efficient as `if (false) { yield null; }` when opcache's sccp pass is enabled. Closes GH-5679 --- diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index b2d6dcf9e7..1bec01c5e2 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -1678,6 +1678,16 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o } SET_RESULT_BOT(result); break; + case ZEND_YIELD_FROM: + // tmp = yield from [] -> tmp = null + SKIP_IF_TOP(op1); + if (Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0) { + ZVAL_NULL(&zv); + SET_RESULT(result, &zv); + break; + } + SET_RESULT_BOT(result); + break; case ZEND_COUNT: SKIP_IF_TOP(op1); if (Z_TYPE_P(op1) == IS_ARRAY) { diff --git a/ext/opcache/tests/opt/sccp_032.phpt b/ext/opcache/tests/opt/sccp_032.phpt new file mode 100644 index 0000000000..e7d9e48991 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_032.phpt @@ -0,0 +1,56 @@ +--TEST-- +SCCP 032: Yield from optimizations +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.opt_debug_level=0x20000 +opcache.preload= +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=11, args=0, vars=1, tmps=2) + ; (after optimizer) + ; %ssccp_032.php:1-15 +0000 INIT_FCALL 0 %d string("test") +0001 V2 = DO_UCALL +0002 V1 = FE_RESET_R V2 0009 +0003 FE_FETCH_R V1 CV0($x) 0009 +0004 INIT_FCALL 1 %d string("var_export") +0005 SEND_VAR CV0($x) 1 +0006 DO_ICALL +0007 ECHO string(" +") +0008 JMP 0003 +0009 FE_FREE V1 +0010 RETURN int(1) +LIVE RANGES: + 1: 0003 - 0009 (loop) + +test: + ; (lines=5, args=0, vars=0, tmps=1) + ; (after optimizer) + ; %ssccp_032.php:2-9 +0000 GENERATOR_CREATE +0001 YIELD null +0002 T0 = YIELD_FROM array(...) +0003 FREE T0 +0004 GENERATOR_RETURN null +NULL +3