com php-src: Respect RC_INFERENCE during DFG constructi on: ext/opcache/Optimizer/zend_dfg.c ext/opcache/Opti mizer/zend_dfg.h
ext/opcache/Optimizer/zend_ssa.c
| From: | Nikita Popov | Date: | Sun, 24 Jan 2016 22:04:06 +0000 |
| Subject: | com php-src: Respect RC_INFERENCE during DFG constructi on: ext/opcache/Optimizer/zend_dfg.c ext/opcache/Opti mizer/zend_dfg.h ext/opcache/Optimizer/zend_ssa.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-90740@lists.php.net to get a copy of this message | ||
Commit: c2fea2a46d789231791e770267614fb621443359
Author: Nikita Popov <nikic@php.net> Sat, 23 Jan 2016 16:56:27 +0100
Parents: 949aaea66ee2bd7171e802a2f1a4fa2efbd03e6c
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=c2fea2a46d789231791e770267614fb621443359
Log:
Respect RC_INFERENCE during DFG construction
To avoid inserting phis that are only relevant with rc inference
enabled. Suprisingly, this affects only 0.8% of phis.
Changed paths:
M ext/opcache/Optimizer/zend_dfg.c
M ext/opcache/Optimizer/zend_dfg.h
M ext/opcache/Optimizer/zend_ssa.c
Diff:
diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c
index 4bf5d79..8644a7c 100644
--- a/ext/opcache/Optimizer/zend_dfg.c
+++ b/ext/opcache/Optimizer/zend_dfg.c
@@ -20,7 +20,7 @@
#include "zend_compile.h"
#include "zend_dfg.h"
-int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg) /* {{{ */
+int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg, uint32_t
build_flags) /* {{{ */
{
int set_size;
zend_basic_block *blocks = cfg->blocks;
@@ -89,6 +89,24 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
}
if (opline->op1_type == IS_CV) {
switch (opline->opcode) {
+ case ZEND_ADD_ARRAY_ELEMENT:
+ case ZEND_INIT_ARRAY:
+ if ((build_flags & ZEND_SSA_RC_INFERENCE)
+ || (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+ goto op1_def;
+ }
+ goto op1_use;
+ case ZEND_FE_RESET_R:
+ if (build_flags & ZEND_SSA_RC_INFERENCE) {
+ goto op1_def;
+ }
+ goto op1_use;
+ case ZEND_YIELD:
+ if ((build_flags & ZEND_SSA_RC_INFERENCE)
+ || (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+ goto op1_def;
+ }
+ goto op1_use;
case ZEND_ASSIGN:
case ZEND_ASSIGN_REF:
case ZEND_BIND_GLOBAL:
@@ -96,11 +114,8 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
case ZEND_SEND_VAR_EX:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
- case ZEND_FE_RESET_R:
case ZEND_FE_RESET_RW:
- case ZEND_ADD_ARRAY_ELEMENT:
- case ZEND_INIT_ARRAY:
- case ZEND_YIELD:
+op1_def:
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) {
// FIXME: include into "use" to ...?
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
@@ -141,6 +156,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
case ZEND_FETCH_OBJ_UNSET:
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
default:
+op1_use:
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
}
@@ -154,10 +170,19 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg,
zend_dfg
if (opline->op2_type == IS_CV) {
switch (opline->opcode) {
case ZEND_ASSIGN:
+ if (build_flags & ZEND_SSA_RC_INFERENCE) {
+ goto op2_def;
+ }
+ goto op2_use;
+ case ZEND_BIND_LEXICAL:
+ if ((build_flags & ZEND_SSA_RC_INFERENCE) || opline->extended_value) {
+ goto op2_def;
+ }
+ goto op2_use;
case ZEND_ASSIGN_REF:
case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW:
- case ZEND_BIND_LEXICAL:
+op2_def:
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
// FIXME: include into "use" to ...?
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
@@ -166,6 +191,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
break;
default:
+op2_use:
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
}
diff --git a/ext/opcache/Optimizer/zend_dfg.h b/ext/opcache/Optimizer/zend_dfg.h
index ebbb98a..9d86499 100644
--- a/ext/opcache/Optimizer/zend_dfg.h
+++ b/ext/opcache/Optimizer/zend_dfg.h
@@ -44,7 +44,7 @@ typedef struct _zend_dfg {
BEGIN_EXTERN_C()
-int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg);
+int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg, uint32_t
build_flags);
END_EXTERN_C()
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index b984d41..e80be77 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -532,7 +532,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
dfg.in = dfg.use + set_size * blocks_count;
dfg.out = dfg.in + set_size * blocks_count;
- if (zend_build_dfg(op_array, &ssa->cfg, &dfg) != SUCCESS) {
+ if (zend_build_dfg(op_array, &ssa->cfg, &dfg, build_flags) != SUCCESS) {
free_alloca(dfg.tmp, dfg_use_heap);
return FAILURE;
}