#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;
}
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:
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));
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));
}
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));
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));
}