mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Check if instruction may throw exception only for instructions without known side effects.
Always disable removing ASSIGN and UNSET_VAR that may throw.
This commit is contained in:
parent
c5aa1f47cd
commit
4b64dbb30d
2 changed files with 9 additions and 18 deletions
|
@ -69,13 +69,9 @@ static inline zend_bool is_bad_mod(const zend_ssa *ssa, int use, int def) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline zend_bool may_have_side_effects(
|
static inline zend_bool may_have_side_effects(
|
||||||
const context *ctx, const zend_op *opline, const zend_ssa_op *ssa_op) {
|
zend_op_array *op_array, zend_ssa *ssa,
|
||||||
zend_op_array *op_array = ctx->op_array;
|
const zend_op *opline, const zend_ssa_op *ssa_op,
|
||||||
zend_ssa *ssa = ctx->ssa;
|
zend_bool reorder_dtor_effects) {
|
||||||
if (zend_may_throw(opline, op_array, ssa)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (opline->opcode) {
|
switch (opline->opcode) {
|
||||||
case ZEND_NOP:
|
case ZEND_NOP:
|
||||||
case ZEND_IS_IDENTICAL:
|
case ZEND_IS_IDENTICAL:
|
||||||
|
@ -154,15 +150,10 @@ static inline zend_bool may_have_side_effects(
|
||||||
return 1;
|
return 1;
|
||||||
case ZEND_ASSIGN:
|
case ZEND_ASSIGN:
|
||||||
{
|
{
|
||||||
uint32_t t1 = OP1_INFO();
|
|
||||||
if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)) {
|
if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!ctx->reorder_dtor_effects) {
|
if (!reorder_dtor_effects) {
|
||||||
if (t1 & MAY_HAVE_DTOR) {
|
|
||||||
/* DCE might extend lifetime */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (opline->op2_type != IS_CONST && (OP2_INFO() & MAY_HAVE_DTOR)) {
|
if (opline->op2_type != IS_CONST && (OP2_INFO() & MAY_HAVE_DTOR)) {
|
||||||
/* DCE might shorten lifetime */
|
/* DCE might shorten lifetime */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -183,10 +174,6 @@ static inline zend_bool may_have_side_effects(
|
||||||
* is a reference, because unset breaks references. */
|
* is a reference, because unset breaks references. */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!ctx->reorder_dtor_effects && (t1 & MAY_HAVE_DTOR)) {
|
|
||||||
/* DCE might extend lifetime */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case ZEND_PRE_INC:
|
case ZEND_PRE_INC:
|
||||||
|
@ -481,7 +468,9 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reor
|
||||||
|
|
||||||
/* Mark instruction with side effects as live */
|
/* Mark instruction with side effects as live */
|
||||||
FOREACH_INSTR_NUM(i) {
|
FOREACH_INSTR_NUM(i) {
|
||||||
if (may_have_side_effects(&ctx, &op_array->opcodes[i], &ssa->ops[i]) || has_varargs) {
|
if (may_have_side_effects(op_array, ssa, &op_array->opcodes[i], &ssa->ops[i], ctx.reorder_dtor_effects)
|
||||||
|
|| zend_may_throw(&op_array->opcodes[i], op_array, ssa)
|
||||||
|
|| has_varargs) {
|
||||||
zend_bitset_excl(ctx.instr_dead, i);
|
zend_bitset_excl(ctx.instr_dead, i);
|
||||||
add_operands_to_worklists(&ctx, &op_array->opcodes[i], &ssa->ops[i]);
|
add_operands_to_worklists(&ctx, &op_array->opcodes[i], &ssa->ops[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4024,6 +4024,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
|
||||||
case ZEND_COALESCE:
|
case ZEND_COALESCE:
|
||||||
case ZEND_SWITCH_LONG:
|
case ZEND_SWITCH_LONG:
|
||||||
case ZEND_SWITCH_STRING:
|
case ZEND_SWITCH_STRING:
|
||||||
|
case ZEND_ISSET_ISEMPTY_VAR:
|
||||||
return 0;
|
return 0;
|
||||||
case ZEND_INIT_FCALL:
|
case ZEND_INIT_FCALL:
|
||||||
/* can't throw, because call is resolved at compile time */
|
/* can't throw, because call is resolved at compile time */
|
||||||
|
@ -4157,6 +4158,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
|
||||||
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
|
return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) ||
|
||||||
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
|
(t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT));
|
||||||
case ZEND_ASSIGN:
|
case ZEND_ASSIGN:
|
||||||
|
case ZEND_UNSET_VAR:
|
||||||
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY));
|
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY));
|
||||||
case ZEND_ASSIGN_DIM:
|
case ZEND_ASSIGN_DIM:
|
||||||
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)) || opline->op2_type == IS_UNUSED ||
|
return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)) || opline->op2_type == IS_UNUSED ||
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue