mirror of
https://github.com/php/php-src.git
synced 2025-08-18 06:58:55 +02:00
Various SSA-related tweaks
* Add FETCH_LIST to inference * Restrict JMP_SET/COALESCE result type * Fix typos in range inference * Add const annotations in zend_ssa.h * For pi statements dump the associated predecessor block * If type can be both true and false, dump bool instead
This commit is contained in:
parent
ff1f178d84
commit
a1c48d5e3a
3 changed files with 23 additions and 10 deletions
|
@ -182,11 +182,13 @@ static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_inst
|
|||
if (first) first = 0; else fprintf(stderr, ", ");
|
||||
fprintf(stderr, "null");
|
||||
}
|
||||
if (info & MAY_BE_FALSE) {
|
||||
if ((info & MAY_BE_FALSE) && (info & MAY_BE_TRUE)) {
|
||||
if (first) first = 0; else fprintf(stderr, ", ");
|
||||
fprintf(stderr, "bool");
|
||||
} else if (info & MAY_BE_FALSE) {
|
||||
if (first) first = 0; else fprintf(stderr, ", ");
|
||||
fprintf(stderr, "false");
|
||||
}
|
||||
if (info & MAY_BE_TRUE) {
|
||||
} else if (info & MAY_BE_TRUE) {
|
||||
if (first) first = 0; else fprintf(stderr, ", ");
|
||||
fprintf(stderr, "true");
|
||||
}
|
||||
|
@ -788,7 +790,7 @@ static void zend_dump_block_header(const zend_cfg *cfg, const zend_op_array *op_
|
|||
}
|
||||
fprintf(stderr, ")\n");
|
||||
} else {
|
||||
fprintf(stderr, " = Pi(");
|
||||
fprintf(stderr, " = Pi<BB%d>(", p->pi);
|
||||
zend_dump_ssa_var(op_array, ssa, p->sources[0], 0, p->var, dump_flags);
|
||||
fprintf(stderr, " &");
|
||||
zend_dump_pi_constraint(op_array, ssa, &p->constraint, dump_flags);
|
||||
|
|
|
@ -962,7 +962,7 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
|
|||
op2_max = OP2_MAX_RANGE();
|
||||
|
||||
tmp->min = (op1_min == op1_max &&
|
||||
op2_min == op2_min &&
|
||||
op2_min == op2_max &&
|
||||
op1_min == op2_max);
|
||||
tmp->max = (op1_min <= op2_max && op1_max >= op2_min);
|
||||
return 1;
|
||||
|
@ -984,7 +984,7 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
|
|||
|
||||
tmp->min = (op1_min > op2_max || op1_max < op2_min);
|
||||
tmp->max = (op1_min != op1_max ||
|
||||
op2_min != op2_min ||
|
||||
op2_min != op2_max ||
|
||||
op1_min != op2_max);
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -2359,6 +2359,14 @@ static void zend_update_type_info(const zend_op_array *op_array,
|
|||
if (opline->op1_type & (IS_CV|IS_VAR)) {
|
||||
tmp |= MAY_BE_RCN;
|
||||
}
|
||||
if (opline->opcode != ZEND_QM_ASSIGN) {
|
||||
/* COALESCE and JMP_SET result can't be null */
|
||||
tmp &= ~MAY_BE_NULL;
|
||||
if (opline->opcode == ZEND_JMP_SET) {
|
||||
/* JMP_SET result can't be false either */
|
||||
tmp &= ~MAY_BE_FALSE;
|
||||
}
|
||||
}
|
||||
UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
|
||||
if ((t1 & MAY_BE_OBJECT) && ssa_ops[i].op1_use >= 0 && ssa_var_info[ssa_ops[i].op1_use].ce) {
|
||||
UPDATE_SSA_OBJ_TYPE(ssa_var_info[ssa_ops[i].op1_use].ce, ssa_var_info[ssa_ops[i].op1_use].is_instanceof, ssa_ops[i].result_def);
|
||||
|
@ -3438,6 +3446,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
|
|||
case ZEND_FETCH_DIM_W:
|
||||
case ZEND_FETCH_DIM_UNSET:
|
||||
case ZEND_FETCH_DIM_FUNC_ARG:
|
||||
case ZEND_FETCH_LIST:
|
||||
if (ssa_ops[i].op1_def >= 0) {
|
||||
tmp = t1;
|
||||
if (opline->opcode == ZEND_FETCH_DIM_W ||
|
||||
|
@ -3520,9 +3529,11 @@ static void zend_update_type_info(const zend_op_array *op_array,
|
|||
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_ops[i].op1_def);
|
||||
}
|
||||
}
|
||||
/* FETCH_LIST on a string behaves like FETCH_R on null */
|
||||
tmp = zend_array_element_type(
|
||||
t1,
|
||||
(opline->opcode != ZEND_FETCH_DIM_R && opline->opcode != ZEND_FETCH_DIM_IS),
|
||||
opline->opcode != ZEND_FETCH_LIST ? t1 : ((t1 & ~MAY_BE_STRING) | MAY_BE_NULL),
|
||||
opline->opcode != ZEND_FETCH_DIM_R && opline->opcode != ZEND_FETCH_DIM_IS
|
||||
&& opline->opcode != ZEND_FETCH_LIST,
|
||||
opline->op2_type == IS_UNUSED);
|
||||
if (opline->opcode == ZEND_FETCH_DIM_W ||
|
||||
opline->opcode == ZEND_FETCH_DIM_RW ||
|
||||
|
|
|
@ -122,7 +122,7 @@ int zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var);
|
|||
|
||||
END_EXTERN_C()
|
||||
|
||||
static zend_always_inline int zend_ssa_next_use(zend_ssa_op *ssa_op, int var, int use)
|
||||
static zend_always_inline int zend_ssa_next_use(const zend_ssa_op *ssa_op, int var, int use)
|
||||
{
|
||||
ssa_op += use;
|
||||
if (ssa_op->result_use == var) {
|
||||
|
@ -131,7 +131,7 @@ static zend_always_inline int zend_ssa_next_use(zend_ssa_op *ssa_op, int var, in
|
|||
return (ssa_op->op1_use == var) ? ssa_op->op1_use_chain : ssa_op->op2_use_chain;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(zend_ssa *ssa, int var, zend_ssa_phi *p)
|
||||
static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(const zend_ssa *ssa, int var, const zend_ssa_phi *p)
|
||||
{
|
||||
if (p->pi >= 0) {
|
||||
return p->use_chains[0];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue