Add ability to prevent "useless" SSA variable creation for "refcounting inference".

This commit is contained in:
Dmitry Stogov 2015-12-22 16:43:37 +03:00
parent e8f1db14d5
commit b4b6d58990
3 changed files with 8 additions and 7 deletions

View File

@ -93,6 +93,7 @@ typedef struct _zend_cfg {
#define ZEND_CFG_STACKLESS (1<<30)
#define ZEND_SSA_DEBUG_LIVENESS (1<<29)
#define ZEND_SSA_DEBUG_PHI_PLACEMENT (1<<28)
#define ZEND_SSA_RC_INFERENCE (1<<27)
#define CRT_CONSTANT_EX(op_array, node, rt_constants) \
((rt_constants) ? \

View File

@ -2924,7 +2924,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
}
UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
}
if ((opline+1)->op1_type == IS_CV) {
if ((opline+1)->op1_type == IS_CV && ssa_ops[i+1].op1_def >= 0) {
opline++;
i++;
tmp = OP1_INFO();
@ -2974,7 +2974,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
}
break;
case ZEND_ASSIGN:
if (opline->op2_type == IS_CV) {
if (opline->op2_type == IS_CV && ssa_ops[i].op2_def >= 0) {
tmp = t2;
if (tmp & (MAY_BE_ANY | MAY_BE_REF)) {
if (tmp & MAY_BE_RC1) {

View File

@ -129,7 +129,7 @@ static inline zend_bool sub_will_overflow(zend_long a, zend_long b) {
|| (b < 0 && a > ZEND_LONG_MAX + b);
}
static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *var, int n) /* {{{ */
static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
{
zend_basic_block *blocks = ssa->cfg.blocks;
zend_ssa_block *ssa_blocks = ssa->blocks;
@ -230,7 +230,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
ssa_vars_count++;
//NEW_SSA_VAR(opline->op1.var)
}
if (opline->op2_type == IS_CV) {
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op2_type == IS_CV) {
ssa_ops[k].op2_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
ssa_vars_count++;
@ -268,7 +268,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
ssa_vars_count++;
//NEW_SSA_VAR(opline->op1.var)
}
if (next->op1_type == IS_CV) {
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++;
@ -418,7 +418,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, zend_ssa *ssa, int *va
j = blocks[n].children;
while (j >= 0) {
// FIXME: Tail call optimization?
if (zend_ssa_rename(op_array, ssa, var, j) != SUCCESS)
if (zend_ssa_rename(op_array, build_flags, ssa, var, j) != SUCCESS)
return FAILURE;
j = blocks[j].next_child;
}
@ -863,7 +863,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b
var[j] = j;
}
ssa->vars_count = op_array->last_var;
if (zend_ssa_rename(op_array, ssa, var, 0) != SUCCESS) {
if (zend_ssa_rename(op_array, build_flags, ssa, var, 0) != SUCCESS) {
failure:
free_alloca(var, var_use_heap);
free_alloca(dfg.tmp, dfg_use_heap);