zend_ssa_op *ssa_ops = ssa->ops;
int ssa_vars_count = ssa->vars_count;
int i, j;
- zend_op *opline, *end;
+ zend_op *opline, *end, *next;
int *tmp = NULL;
ALLOCA_FLAG(use_heap = 0);
for (; opline < end; opline++) {
uint32_t k = opline - op_array->opcodes;
if (opline->opcode != ZEND_OP_DATA) {
- zend_op *next = opline + 1;
- if (next < end && next->opcode == ZEND_OP_DATA) {
- if (next->op1_type == IS_CV) {
- ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
- //USE_SSA_VAR(next->op1.var);
- } else if (next->op1_type & (IS_VAR|IS_TMP_VAR)) {
- ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
- //USE_SSA_VAR(op_array->last_var + next->op1.var);
- }
- if (next->op2_type == IS_CV) {
- ssa_ops[k + 1].op2_use = var[EX_VAR_TO_NUM(next->op2.var)];
- //USE_SSA_VAR(next->op2.var);
- } else if (next->op2_type & (IS_VAR|IS_TMP_VAR)) {
- ssa_ops[k + 1].op2_use = var[EX_VAR_TO_NUM(next->op2.var)];
- //USE_SSA_VAR(op_array->last_var + next->op2.var);
- }
- }
+
if (opline->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
ssa_ops[k].op1_use = var[EX_VAR_TO_NUM(opline->op1.var)];
//USE_SSA_VAR(op_array->last_var + opline->op1.var)
}
- if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
- if (opline->op2_type == IS_CV) {
- ssa_ops[k].op2_use = var[EX_VAR_TO_NUM(opline->op2.var)];
- }
- ssa_ops[k].op2_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op2.var)
- } else if (opline->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ if (opline->op2_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
ssa_ops[k].op2_use = var[EX_VAR_TO_NUM(opline->op2.var)];
//USE_SSA_VAR(op_array->last_var + opline->op2.var)
}
+ if ((build_flags & ZEND_SSA_USE_CV_RESULTS)
+ && opline->result_type == IS_CV
+ && opline->opcode != ZEND_RECV) {
+ ssa_ops[k].result_use = var[EX_VAR_TO_NUM(opline->result.var)];
+ //USE_SSA_VAR(op_array->last_var + opline->result.var)
+ }
+
switch (opline->opcode) {
+ case ZEND_ADD_ARRAY_UNPACK:
+ case ZEND_ADD_ARRAY_ELEMENT:
+ ssa_ops[k].result_use = var[EX_VAR_TO_NUM(opline->result.var)];
+ break;
case ZEND_ASSIGN:
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op2_type == IS_CV) {
ssa_ops[k].op2_def = ssa_vars_count;
//NEW_SSA_VAR(opline->op2.var)
}
if (opline->op1_type == IS_CV) {
+add_op1_def:
ssa_ops[k].op1_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
ssa_vars_count++;
}
break;
case ZEND_ASSIGN_REF:
-//TODO: ???
if (opline->op2_type == IS_CV) {
ssa_ops[k].op2_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
//NEW_SSA_VAR(opline->op2.var)
}
if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
- }
- break;
- case ZEND_BIND_GLOBAL:
- case ZEND_BIND_STATIC:
- if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ goto add_op1_def;
}
break;
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
- if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ next = opline + 1;
+ if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
+ //USE_SSA_VAR(op_array->last_var + next->op1.var);
+ if (build_flags & ZEND_SSA_RC_INFERENCE && next->op1_type == IS_CV) {
+ ssa_ops[k + 1].op1_def = ssa_vars_count;
+ var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
+ ssa_vars_count++;
+ //NEW_SSA_VAR(next->op1.var)
+ }
}
- if ((build_flags & ZEND_SSA_RC_INFERENCE) && next->op1_type == IS_CV) {
- ssa_ops[k + 1].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(next->op1.var)
+ if (opline->op1_type == IS_CV) {
+ goto add_op1_def;
}
break;
case ZEND_ASSIGN_OBJ_REF:
- if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ next = opline + 1;
+ if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
+ //USE_SSA_VAR(op_array->last_var + next->op1.var);
+ if (next->op1_type == IS_CV) {
+ ssa_ops[k + 1].op1_def = ssa_vars_count;
+ var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
+ ssa_vars_count++;
+ //NEW_SSA_VAR(next->op1.var)
+ }
}
- /* break missing intentionally */
- case ZEND_ASSIGN_STATIC_PROP_REF:
- if (next->op1_type == IS_CV) {
- ssa_ops[k + 1].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(next->op1.var)
+ if (opline->op1_type == IS_CV) {
+ goto add_op1_def;
}
break;
- case ZEND_PRE_INC_OBJ:
- case ZEND_PRE_DEC_OBJ:
- case ZEND_POST_INC_OBJ:
- case ZEND_POST_DEC_OBJ:
- if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ case ZEND_ASSIGN_STATIC_PROP:
+ next = opline + 1;
+ if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
+ //USE_SSA_VAR(op_array->last_var + next->op1.var);
+#if 0
+ if ((build_flags & ZEND_SSA_RC_INFERENCE) && next->op1_type == IS_CV) {
+ ssa_ops[k + 1].op1_def = ssa_vars_count;
+ var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
+ ssa_vars_count++;
+ //NEW_SSA_VAR(next->op1.var)
+ }
+#endif
}
break;
- case ZEND_ADD_ARRAY_ELEMENT:
- ssa_ops[k].result_use = var[EX_VAR_TO_NUM(opline->result.var)];
- case ZEND_INIT_ARRAY:
- if (((build_flags & ZEND_SSA_RC_INFERENCE)
- || (opline->extended_value & ZEND_ARRAY_ELEMENT_REF))
- && opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline+->op1.var)
+ case ZEND_ASSIGN_STATIC_PROP_REF:
+ next = opline + 1;
+ if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
+ //USE_SSA_VAR(op_array->last_var + next->op1.var);
+ if (next->op1_type == IS_CV) {
+ ssa_ops[k + 1].op1_def = ssa_vars_count;
+ var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
+ ssa_vars_count++;
+ //NEW_SSA_VAR(next->op1.var)
+ }
}
break;
- case ZEND_ADD_ARRAY_UNPACK:
- ssa_ops[k].result_use = var[EX_VAR_TO_NUM(opline->result.var)];
+ case ZEND_ASSIGN_STATIC_PROP_OP:
+ next = opline + 1;
+ if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
+ //USE_SSA_VAR(op_array->last_var + next->op1.var);
+ }
break;
- case ZEND_SEND_VAR:
- case ZEND_CAST:
- case ZEND_QM_ASSIGN:
- case ZEND_JMP_SET:
- case ZEND_COALESCE:
- if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
+ next = opline + 1;
+ if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+ ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
+ //USE_SSA_VAR(op_array->last_var + next->op1.var);
+ }
+ if (opline->op1_type == IS_CV) {
+ goto add_op1_def;
}
break;
+ case ZEND_ASSIGN_OP:
+ case ZEND_PRE_INC:
+ case ZEND_PRE_DEC:
+ case ZEND_POST_INC:
+ case ZEND_POST_DEC:
+ case ZEND_BIND_GLOBAL:
+ case ZEND_BIND_STATIC:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_VAR_EX:
case ZEND_SEND_UNPACK:
case ZEND_FE_RESET_RW:
case ZEND_MAKE_REF:
- if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
- }
- break;
- case ZEND_FE_RESET_R:
- if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
- }
- break;
- case ZEND_ASSIGN_OP:
- case ZEND_ASSIGN_DIM_OP:
- case ZEND_ASSIGN_OBJ_OP:
- case ZEND_ASSIGN_STATIC_PROP_OP:
- case ZEND_PRE_INC:
- case ZEND_PRE_DEC:
- case ZEND_POST_INC:
- case ZEND_POST_DEC:
- if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
- }
- break;
- case ZEND_UNSET_CV:
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- break;
+ case ZEND_PRE_INC_OBJ:
+ case ZEND_PRE_DEC_OBJ:
+ case ZEND_POST_INC_OBJ:
+ case ZEND_POST_DEC_OBJ:
case ZEND_UNSET_DIM:
case ZEND_UNSET_OBJ:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_UNSET:
case ZEND_FETCH_LIST_W:
if (opline->op1_type == IS_CV) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ goto add_op1_def;
}
break;
- case ZEND_BIND_LEXICAL:
- if ((opline->extended_value & ZEND_BIND_REF) || (build_flags & ZEND_SSA_RC_INFERENCE)) {
- ssa_ops[k].op2_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
- ssa_vars_count++;
+ case ZEND_SEND_VAR:
+ case ZEND_CAST:
+ case ZEND_QM_ASSIGN:
+ case ZEND_JMP_SET:
+ case ZEND_COALESCE:
+ case ZEND_FE_RESET_R:
+ if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
+ goto add_op1_def;
+ }
+ break;
+ case ZEND_INIT_ARRAY:
+ if (((build_flags & ZEND_SSA_RC_INFERENCE)
+ || (opline->extended_value & ZEND_ARRAY_ELEMENT_REF))
+ && opline->op1_type == IS_CV) {
+ goto add_op1_def;
}
break;
case ZEND_YIELD:
if (opline->op1_type == IS_CV
&& ((op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)
|| (build_flags & ZEND_SSA_RC_INFERENCE))) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
- ssa_vars_count++;
+ goto add_op1_def;
}
break;
+ case ZEND_UNSET_CV:
+ goto add_op1_def;
case ZEND_VERIFY_RETURN_TYPE:
if (opline->op1_type & (IS_TMP_VAR|IS_VAR|IS_CV)) {
- ssa_ops[k].op1_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
+ goto add_op1_def;
+ }
+ break;
+ case ZEND_FE_FETCH_R:
+ case ZEND_FE_FETCH_RW:
+ if (opline->op2_type != IS_CV) {
+ ssa_ops[k].op2_use = -1; /* not used */
+ }
+ ssa_ops[k].op2_def = ssa_vars_count;
+ var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
+ ssa_vars_count++;
+ //NEW_SSA_VAR(opline->op2.var)
+ break;
+ case ZEND_BIND_LEXICAL:
+ if ((opline->extended_value & ZEND_BIND_REF) || (build_flags & ZEND_SSA_RC_INFERENCE)) {
+ ssa_ops[k].op2_def = ssa_vars_count;
+ var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
ssa_vars_count++;
- //NEW_SSA_VAR(opline->op1.var)
+ //NEW_SSA_VAR(opline->op2.var)
}
break;
default:
break;
}
- if (opline->result_type == IS_CV) {
- if ((build_flags & ZEND_SSA_USE_CV_RESULTS)
- && opline->opcode != ZEND_RECV) {
- ssa_ops[k].result_use = var[EX_VAR_TO_NUM(opline->result.var)];
- }
- ssa_ops[k].result_def = ssa_vars_count;
- var[EX_VAR_TO_NUM(opline->result.var)] = ssa_vars_count;
- ssa_vars_count++;
- //NEW_SSA_VAR(opline->result.var)
- } else if (opline->result_type & (IS_VAR|IS_TMP_VAR)) {
+
+ if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
ssa_ops[k].result_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->result.var)] = ssa_vars_count;
ssa_vars_count++;