From: Nikita Popov Date: Sat, 9 Jan 2016 16:36:02 +0000 (+0100) Subject: Make PI construction human-readable X-Git-Tag: php-7.1.0alpha1~617^2~79 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0e936db80172e965c414ea6b11fcd1ed95e5f358;p=php Make PI construction human-readable Also makes it easy to add PIs for TI. --- diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index 70c042e946..b942391850 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -38,40 +38,62 @@ static int needs_pi(const zend_op_array *op_array, zend_dfg *dfg, zend_ssa *ssa, } /* }}} */ -static int add_pi(zend_arena **arena, const zend_op_array *op_array, zend_dfg *dfg, zend_ssa *ssa, int from, int to, int var, int min_var, int max_var, zend_long min, zend_long max, char underflow, char overflow, char negative) /* {{{ */ +static zend_ssa_phi *add_pi( + zend_arena **arena, const zend_op_array *op_array, zend_dfg *dfg, zend_ssa *ssa, + int from, int to, int var) /* {{{ */ { - if (needs_pi(op_array, dfg, ssa, from, to, var)) { - zend_ssa_phi *phi = zend_arena_calloc(arena, 1, - sizeof(zend_ssa_phi) + - sizeof(int) * ssa->cfg.blocks[to].predecessors_count + - sizeof(void*) * ssa->cfg.blocks[to].predecessors_count); + zend_ssa_phi *phi; + if (!needs_pi(op_array, dfg, ssa, from, to, var)) { + return NULL; + } - if (!phi) { - return FAILURE; - } - phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi)); - memset(phi->sources, 0xff, sizeof(int) * ssa->cfg.blocks[to].predecessors_count); - phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[to].predecessors_count); + phi = zend_arena_calloc(arena, 1, + sizeof(zend_ssa_phi) + + sizeof(int) * ssa->cfg.blocks[to].predecessors_count + + sizeof(void*) * ssa->cfg.blocks[to].predecessors_count); + phi->sources = (int*)(((char*)phi) + sizeof(zend_ssa_phi)); + memset(phi->sources, 0xff, sizeof(int) * ssa->cfg.blocks[to].predecessors_count); + phi->use_chains = (zend_ssa_phi**)(((char*)phi->sources) + sizeof(int) * ssa->cfg.blocks[to].predecessors_count); - phi->pi = from; - phi->constraint.min_var = min_var; - phi->constraint.max_var = max_var; - phi->constraint.min_ssa_var = -1; - phi->constraint.max_ssa_var = -1; - phi->constraint.range.min = min; - phi->constraint.range.max = max; - phi->constraint.range.underflow = underflow; - phi->constraint.range.overflow = overflow; - phi->constraint.negative = negative ? NEG_INIT : NEG_NONE; - phi->var = var; - phi->ssa_var = -1; - phi->next = ssa->blocks[to].phis; - ssa->blocks[to].phis = phi; - } - return SUCCESS; + phi->pi = from; + phi->var = var; + phi->ssa_var = -1; + phi->next = ssa->blocks[to].phis; + ssa->blocks[to].phis = phi; + + return phi; } /* }}} */ +static void pi_range( + zend_ssa_phi *phi, int min_var, int max_var, zend_long min, zend_long max, + char underflow, char overflow, char negative) /* {{{ */ +{ + phi->constraint.min_var = min_var; + phi->constraint.max_var = max_var; + phi->constraint.min_ssa_var = -1; + phi->constraint.max_ssa_var = -1; + phi->constraint.range.min = min; + phi->constraint.range.max = max; + phi->constraint.range.underflow = underflow; + phi->constraint.range.overflow = overflow; + phi->constraint.negative = negative ? NEG_INIT : NEG_NONE; +} +/* }}} */ + +static inline void pi_range_equals(zend_ssa_phi *phi, int var, zend_long val) { + pi_range(phi, var, var, val, val, 0, 0, 0); +} +static inline void pi_range_not_equals(zend_ssa_phi *phi, int var, zend_long val) { + pi_range(phi, var, var, val, val, 0, 0, 1); +} +static inline void pi_range_min(zend_ssa_phi *phi, int var, zend_long val) { + pi_range(phi, var, -1, val, ZEND_LONG_MAX, 0, 1, 0); +} +static inline void pi_range_max(zend_ssa_phi *phi, int var, zend_long val) { + pi_range(phi, -1, var, ZEND_LONG_MIN, val, 1, 0, 0); +} + /* We can interpret $a + 5 == 0 as $a = 0 - 5, i.e. shift the adjustment to the other operand. * This negated adjustment is what is written into the "adjustment" parameter. */ static int find_adjusted_tmp_var(const zend_op_array *op_array, uint32_t build_flags, zend_op *opline, uint32_t var_num, zend_long *adjustment) @@ -577,6 +599,7 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b * Order of Phis is importent, Pis must be placed before Phis */ for (j = 0; j < blocks_count; j++) { + zend_ssa_phi *pi; zend_op *opline = op_array->opcodes + ssa->cfg.blocks[j].end; int bt; /* successor block number if a condition is true */ int bf; /* successor block number if a condition is false */ @@ -677,70 +700,70 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b if (var1 >= 0) { if ((opline-1)->opcode == ZEND_IS_EQUAL) { - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, var2, var2, val2, val2, 0, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var1))) { + pi_range_equals(pi, var2, val2); } - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, var2, val2, val2, 0, 0, 1) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var1))) { + pi_range_not_equals(pi, var2, val2); } } else if ((opline-1)->opcode == ZEND_IS_NOT_EQUAL) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, var2, val2, val2, 0, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var1))) { + pi_range_equals(pi, var2, val2); } - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, var2, var2, val2, val2, 0, 0, 1) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var1))) { + pi_range_not_equals(pi, var2, val2); } } else if ((opline-1)->opcode == ZEND_IS_SMALLER) { if (val2 > ZEND_LONG_MIN) { - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, -1, var2, ZEND_LONG_MIN, val2-1, 1, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var1))) { + pi_range_max(pi, var2, val2-1); } } - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, -1, val2, ZEND_LONG_MAX, 0, 1, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var1))) { + pi_range_min(pi, var2, val2); } } else if ((opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) { - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var1, -1, var2, ZEND_LONG_MIN, val2, 1, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var1))) { + pi_range_max(pi, var2, val2); } if (val2 < ZEND_LONG_MAX) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var1, var2, -1, val2+1, ZEND_LONG_MAX, 0, 1, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var1))) { + pi_range_min(pi, var2, val2+1); } } } } if (var2 >= 0) { if((opline-1)->opcode == ZEND_IS_EQUAL) { - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, var1, val1, val1, 0, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var2))) { + pi_range_equals(pi, var1, val1); } - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, var1, var1, val1, val1, 0, 0, 1) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var2))) { + pi_range_not_equals(pi, var1, val1); } } else if ((opline-1)->opcode == ZEND_IS_NOT_EQUAL) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, var1, var1, val1, val1, 0, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var2))) { + pi_range_equals(pi, var1, val1); } - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, var1, val1, val1, 0, 0, 1) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var2))) { + pi_range_not_equals(pi, var1, val1); } } else if ((opline-1)->opcode == ZEND_IS_SMALLER) { if (val1 < ZEND_LONG_MAX) { - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, -1, val1+1, ZEND_LONG_MAX, 0, 1, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var2))) { + pi_range_min(pi, var1, val1+1); } } - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, -1, var1, ZEND_LONG_MIN, val1, 1, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var2))) { + pi_range_max(pi, var1, val1); } } else if ((opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) { - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var2, var1, -1, val1, ZEND_LONG_MAX, 0 ,1, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var2))) { + pi_range_min(pi, var1, val1); } if (val1 > ZEND_LONG_MIN) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var2, -1, var1, ZEND_LONG_MIN, val1-1, 1, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var2))) { + pi_range_max(pi, var1, val1-1); } } } @@ -753,18 +776,18 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b int var = EX_VAR_TO_NUM((opline-1)->op1.var); if ((opline-1)->opcode == ZEND_POST_DEC) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, -1, -1, 0, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var))) { + pi_range_equals(pi, -1, -1); } - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, -1, -1, 0, 0, 1) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) { + pi_range_not_equals(pi, -1, -1); } } else if ((opline-1)->opcode == ZEND_POST_INC) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, 1, 1, 0, 0, 0) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var))) { + pi_range_equals(pi, -1, 1); } - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, 1, 1, 0, 0, 1) != SUCCESS) { - goto failure; + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) { + pi_range_not_equals(pi, -1, 1); } } } else if (opline->op1_type == IS_VAR && @@ -774,22 +797,12 @@ int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t b (opline-1)->op1_type == IS_CV) { int var = EX_VAR_TO_NUM((opline-1)->op1.var); - if ((opline-1)->opcode == ZEND_PRE_DEC) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, 0, 0, 0, 0, 0) != SUCCESS) { - goto failure; - } - /* speculative */ - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, 0, 0, 0, 0, 1) != SUCCESS) { - goto failure; - } - } else if ((opline-1)->opcode == ZEND_PRE_INC) { - if (add_pi(arena, op_array, &dfg, ssa, j, bf, var, -1, -1, 0, 0, 0, 0, 0) != SUCCESS) { - goto failure; - } - /* speculative */ - if (add_pi(arena, op_array, &dfg, ssa, j, bt, var, -1, -1, 0, 0, 0, 0, 1) != SUCCESS) { - goto failure; - } + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bf, var))) { + pi_range_equals(pi, -1, 0); + } + /* speculative */ + if ((pi = add_pi(arena, op_array, &dfg, ssa, j, bt, var))) { + pi_range_not_equals(pi, -1, 0); } } }