mirror of
https://github.com/php/php-src.git
synced 2025-08-19 17:04:47 +02:00
Collect all jump optimisations in a single optimization pass.
Run this pass twice (after SCCP and after DCE).
This commit is contained in:
parent
4d1ddeb02a
commit
f5ef1a83a8
3 changed files with 203 additions and 246 deletions
|
@ -423,112 +423,6 @@ static zend_bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// TODO Move this somewhere else (CFG simplification?)
|
||||
static int simplify_jumps(zend_ssa *ssa, zend_op_array *op_array) {
|
||||
int removed_ops = 0;
|
||||
zend_basic_block *block;
|
||||
FOREACH_BLOCK(block) {
|
||||
int block_num = block - ssa->cfg.blocks;
|
||||
zend_op *opline = &op_array->opcodes[block->start + block->len - 1];
|
||||
zend_ssa_op *ssa_op = &ssa->ops[block->start + block->len - 1];
|
||||
zval *op1;
|
||||
|
||||
if (block->len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Convert jump-and-set into jump if result is not used */
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMPZ_EX:
|
||||
ZEND_ASSERT(ssa_op->result_def >= 0);
|
||||
if (ssa->vars[ssa_op->result_def].use_chain < 0
|
||||
&& ssa->vars[ssa_op->result_def].phi_use_chain == NULL) {
|
||||
opline->opcode = ZEND_JMPZ;
|
||||
opline->result_type = IS_UNUSED;
|
||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
ZEND_ASSERT(ssa_op->result_def >= 0);
|
||||
if (ssa->vars[ssa_op->result_def].use_chain < 0
|
||||
&& ssa->vars[ssa_op->result_def].phi_use_chain == NULL) {
|
||||
opline->opcode = ZEND_JMPNZ;
|
||||
opline->result_type = IS_UNUSED;
|
||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert jump-and-set to QM_ASSIGN/BOOL if the "else" branch is not taken. */
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMPZ_EX:
|
||||
case ZEND_JMPNZ_EX:
|
||||
if (block->successors_count == 1 && block->successors[0] != block_num + 1) {
|
||||
opline->opcode = ZEND_BOOL;
|
||||
}
|
||||
break;
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
if (block->successors_count == 1 && block->successors[0] != block_num + 1) {
|
||||
opline->opcode = ZEND_QM_ASSIGN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (opline->op1_type != IS_CONST) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Convert constant conditional jump to unconditional jump */
|
||||
op1 = &ZEND_OP1_LITERAL(opline);
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMPZ:
|
||||
if (!zend_is_true(op1)) {
|
||||
literal_dtor(op1);
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->op1.num = opline->op2.num;
|
||||
opline->opcode = ZEND_JMP;
|
||||
} else {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPNZ:
|
||||
if (zend_is_true(op1)) {
|
||||
literal_dtor(op1);
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->op1.num = opline->op2.num;
|
||||
opline->opcode = ZEND_JMP;
|
||||
} else {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
}
|
||||
break;
|
||||
case ZEND_COALESCE:
|
||||
ZEND_ASSERT(ssa_op->result_def >= 0);
|
||||
if (ssa->vars[ssa_op->result_def].use_chain >= 0
|
||||
|| ssa->vars[ssa_op->result_def].phi_use_chain != NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||
if (Z_TYPE_P(op1) != IS_NULL) {
|
||||
literal_dtor(op1);
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->op1.num = opline->op2.num;
|
||||
opline->opcode = ZEND_JMP;
|
||||
opline->result_type = IS_UNUSED;
|
||||
} else {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} FOREACH_BLOCK_END();
|
||||
return removed_ops;
|
||||
}
|
||||
|
||||
static inline int get_common_phi_source(zend_ssa *ssa, zend_ssa_phi *phi) {
|
||||
int common_source = -1;
|
||||
int source;
|
||||
|
@ -772,7 +666,5 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reor
|
|||
}
|
||||
} FOREACH_PHI_END();
|
||||
|
||||
removed_ops += simplify_jumps(ssa, op_array);
|
||||
|
||||
return removed_ops;
|
||||
}
|
||||
|
|
|
@ -454,6 +454,27 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
|
|||
return removed_ops;
|
||||
}
|
||||
|
||||
static zend_always_inline void take_successor_0(zend_ssa *ssa, int block_num, zend_basic_block *block)
|
||||
{
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ssa, block_num, block->successors[1]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline void take_successor_1(zend_ssa *ssa, int block_num, zend_basic_block *block)
|
||||
{
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ssa, block_num, block->successors[0]);
|
||||
block->successors[0] = block->successors[1];
|
||||
}
|
||||
block->successors_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
|
||||
{
|
||||
int removed_ops = 0;
|
||||
|
@ -468,7 +489,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
|
|||
zend_basic_block *block = &ssa->cfg.blocks[block_num];
|
||||
uint32_t op_num;
|
||||
zend_op *opline;
|
||||
zend_ssa_op *op;
|
||||
zend_ssa_op *ssa_op;
|
||||
|
||||
while (next_block_num < ssa->cfg.blocks_count
|
||||
&& !(ssa->cfg.blocks[next_block_num].flags & ZEND_BB_REACHABLE)) {
|
||||
|
@ -476,54 +497,180 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa)
|
|||
}
|
||||
|
||||
if (block->len) {
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[0] == block->successors[1]) {
|
||||
op_num = block->start + block->len - 1;
|
||||
opline = op_array->opcodes + op_num;
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMPZ:
|
||||
case ZEND_JMPNZ:
|
||||
case ZEND_JMPZNZ:
|
||||
op = ssa->ops + op_num;
|
||||
op_num = block->start + block->len - 1;
|
||||
opline = op_array->opcodes + op_num;
|
||||
ssa_op = ssa->ops + op_num;
|
||||
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMP:
|
||||
optimize_jmp:
|
||||
if (block->successors[0] == next_block_num) {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPZ:
|
||||
optimize_jmpz:
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
if (zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
take_successor_1(ssa, block_num, block);
|
||||
} else {
|
||||
opline->opcode = ZEND_JMP;
|
||||
COPY_NODE(opline->op1, opline->op2);
|
||||
take_successor_0(ssa, block_num, block);
|
||||
goto optimize_jmp;
|
||||
}
|
||||
} else {
|
||||
if (block->successors[0] == next_block_num) {
|
||||
take_successor_0(ssa, block_num, block);
|
||||
if (opline->op1_type == IS_CV || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
|
||||
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
||||
removed_ops++;
|
||||
} else {
|
||||
opline->opcode = ZEND_FREE;
|
||||
opline->op2.num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPNZ:
|
||||
optimize_jmpnz:
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
if (zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) {
|
||||
opline->opcode = ZEND_JMP;
|
||||
COPY_NODE(opline->op1, opline->op2);
|
||||
take_successor_0(ssa, block_num, block);
|
||||
goto optimize_jmp;
|
||||
} else {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
take_successor_1(ssa, block_num, block);
|
||||
}
|
||||
} else {
|
||||
ZEND_ASSERT(block->successors_count == 2);
|
||||
if (block->successors[0] == next_block_num) {
|
||||
take_successor_0(ssa, block_num, block);
|
||||
if (opline->op1_type == IS_CV || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
|
||||
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
||||
removed_ops++;
|
||||
} else {
|
||||
opline->opcode = ZEND_FREE;
|
||||
opline->op2.num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPZNZ:
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
if (zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) {
|
||||
zend_op *target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline);
|
||||
take_successor_1(ssa, block_num, block);
|
||||
} else {
|
||||
zend_op *target_opline = ZEND_OP2_JMP_ADDR(opline);
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline);
|
||||
take_successor_0(ssa, block_num, block);
|
||||
}
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->extended_value = 0;
|
||||
opline->opcode = ZEND_JMP;
|
||||
goto optimize_jmp;
|
||||
} else {
|
||||
ZEND_ASSERT(block->successors_count == 2);
|
||||
if (block->successors[0] == block->successors[1]) {
|
||||
take_successor_0(ssa, block_num, block);
|
||||
if (block->successors[0] == next_block_num) {
|
||||
if (opline->op1_type & (IS_CV|IS_CONST)) {
|
||||
zend_ssa_remove_instr(ssa, opline, op);
|
||||
if (op->op1_use >= 0) {
|
||||
zend_ssa_unlink_use_chain(ssa, op_num, op->op1_use);
|
||||
op->op1_use = -1;
|
||||
op->op1_use_chain = -1;
|
||||
}
|
||||
MAKE_NOP(opline);
|
||||
if (opline->op1_type == IS_CV || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
|
||||
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
||||
removed_ops++;
|
||||
} else {
|
||||
opline->opcode = ZEND_FREE;
|
||||
opline->op2.num = 0;
|
||||
}
|
||||
} else {
|
||||
if (opline->op1_type & (IS_CV|IS_CONST)) {
|
||||
if (op->op1_use >= 0) {
|
||||
zend_ssa_unlink_use_chain(ssa, op_num, op->op1_use);
|
||||
op->op1_use = -1;
|
||||
op->op1_use_chain = -1;
|
||||
}
|
||||
opline->opcode = ZEND_JMP;
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->op1.num = opline->op2.num;
|
||||
}
|
||||
} else if (opline->op1_type == IS_CV || !(OP1_INFO() & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
|
||||
ZEND_ASSERT(ssa_op->op1_use >= 0);
|
||||
zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use);
|
||||
ssa_op->op1_use = -1;
|
||||
ssa_op->op1_use_chain = -1;
|
||||
opline->opcode = ZEND_JMP;
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->op1.num = opline->op2.num;
|
||||
goto optimize_jmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (block->successors_count == 1 && block->successors[0] == next_block_num) {
|
||||
op_num = block->start + block->len - 1;
|
||||
opline = op_array->opcodes + op_num;
|
||||
if (opline->opcode == ZEND_JMP) {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPZ_EX:
|
||||
if (ssa->vars[ssa_op->result_def].use_chain < 0
|
||||
&& ssa->vars[ssa_op->result_def].phi_use_chain == NULL) {
|
||||
opline->opcode = ZEND_JMPZ;
|
||||
opline->result_type = IS_UNUSED;
|
||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||
goto optimize_jmpz;
|
||||
} else if (opline->op1_type == IS_CONST) {
|
||||
if (zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) {
|
||||
opline->opcode = ZEND_QM_ASSIGN;
|
||||
take_successor_1(ssa, block_num, block);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPNZ_EX:
|
||||
if (ssa->vars[ssa_op->result_def].use_chain < 0
|
||||
&& ssa->vars[ssa_op->result_def].phi_use_chain == NULL) {
|
||||
opline->opcode = ZEND_JMPNZ;
|
||||
opline->result_type = IS_UNUSED;
|
||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||
goto optimize_jmpnz;
|
||||
} else if (opline->op1_type == IS_CONST) {
|
||||
if (!zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) {
|
||||
opline->opcode = ZEND_QM_ASSIGN;
|
||||
take_successor_1(ssa, block_num, block);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMP_SET:
|
||||
if (ssa->vars[ssa_op->result_def].use_chain < 0
|
||||
&& ssa->vars[ssa_op->result_def].phi_use_chain == NULL) {
|
||||
opline->opcode = ZEND_JMPNZ;
|
||||
opline->result_type = IS_UNUSED;
|
||||
zend_ssa_remove_result_def(ssa, ssa_op);
|
||||
goto optimize_jmpnz;
|
||||
} else if (opline->op1_type == IS_CONST) {
|
||||
if (!zend_is_true(CT_CONSTANT_EX(op_array, opline->op1.constant))) {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
take_successor_1(ssa, block_num, block);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_COALESCE:
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op1.constant)) == IS_NULL) {
|
||||
MAKE_NOP(opline);
|
||||
removed_ops++;
|
||||
take_successor_1(ssa, block_num, block);
|
||||
} else {
|
||||
zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
|
||||
if (var->use_chain < 0 && var->phi_use_chain == NULL) {
|
||||
ssa_op->result_def = -1;
|
||||
if (opline->result_type & (IS_TMP_VAR|IS_VAR)) {
|
||||
zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition);
|
||||
}
|
||||
zend_ssa_unlink_use_chain(ssa, opline - op_array->opcodes, ssa_op->op1_use);
|
||||
ssa_op->op1_use = -1;
|
||||
ssa_op->op1_use_chain = -1;
|
||||
opline->opcode = ZEND_JMP;
|
||||
COPY_NODE(opline->op1, opline->op2);
|
||||
take_successor_0(ssa, block_num, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
block_num = next_block_num;
|
||||
|
@ -574,6 +721,9 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
|
|||
if (dce_optimize_op_array(op_array, ssa, 0)) {
|
||||
remove_nops = 1;
|
||||
}
|
||||
if (zend_dfa_optimize_jmps(op_array, ssa)) {
|
||||
remove_nops = 1;
|
||||
}
|
||||
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_14) {
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA, "after dce pass", ssa);
|
||||
}
|
||||
|
|
|
@ -283,93 +283,6 @@ static zend_bool try_replace_op1(
|
|||
zval zv;
|
||||
ZVAL_COPY(&zv, value);
|
||||
if (zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, &zv)) {
|
||||
/* Reconstruct SSA */
|
||||
int num;
|
||||
zend_basic_block *block;
|
||||
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMPZ:
|
||||
if (zend_is_true(&zv)) {
|
||||
MAKE_NOP(opline);
|
||||
num = ctx->scdf.ssa->cfg.map[opline - ctx->scdf.op_array->opcodes];
|
||||
block = &ctx->scdf.ssa->cfg.blocks[num];
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ctx->scdf.ssa, num, block->successors[0]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
block->successors[0] = block->successors[1];
|
||||
}
|
||||
} else {
|
||||
opline->opcode = ZEND_JMP;
|
||||
COPY_NODE(opline->op1, opline->op2);
|
||||
num = ctx->scdf.ssa->cfg.map[opline - ctx->scdf.op_array->opcodes];
|
||||
block = &ctx->scdf.ssa->cfg.blocks[num];
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ctx->scdf.ssa, num, block->successors[1]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPNZ:
|
||||
if (zend_is_true(&zv)) {
|
||||
opline->opcode = ZEND_JMP;
|
||||
COPY_NODE(opline->op1, opline->op2);
|
||||
num = ctx->scdf.ssa->cfg.map[opline - ctx->scdf.op_array->opcodes];
|
||||
block = &ctx->scdf.ssa->cfg.blocks[num];
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ctx->scdf.ssa, num, block->successors[1]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
}
|
||||
} else {
|
||||
MAKE_NOP(opline);
|
||||
num = ctx->scdf.ssa->cfg.map[opline - ctx->scdf.op_array->opcodes];
|
||||
block = &ctx->scdf.ssa->cfg.blocks[num];
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ctx->scdf.ssa, num, block->successors[0]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
block->successors[0] = block->successors[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_JMPZNZ:
|
||||
if (zend_is_true(&zv)) {
|
||||
zend_op *target_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline);
|
||||
num = ctx->scdf.ssa->cfg.map[opline - ctx->scdf.op_array->opcodes];
|
||||
block = &ctx->scdf.ssa->cfg.blocks[num];
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ctx->scdf.ssa, num, block->successors[0]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
block->successors[0] = block->successors[1];
|
||||
}
|
||||
} else {
|
||||
zend_op *target_opline = ZEND_OP2_JMP_ADDR(opline);
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op1, target_opline);
|
||||
num = ctx->scdf.ssa->cfg.map[opline - ctx->scdf.op_array->opcodes];
|
||||
block = &ctx->scdf.ssa->cfg.blocks[num];
|
||||
if (block->successors_count == 2) {
|
||||
if (block->successors[1] != block->successors[0]) {
|
||||
zend_ssa_remove_predecessor(ctx->scdf.ssa, num, block->successors[1]);
|
||||
}
|
||||
block->successors_count = 1;
|
||||
}
|
||||
}
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->extended_value = 0;
|
||||
opline->opcode = ZEND_JMP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
// TODO: check the following special cases ???
|
||||
|
@ -2082,6 +1995,17 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
|
|||
|| ssa_op->op2_def >= 0) {
|
||||
/* we cannot remove instruction that defines other varibales */
|
||||
return 0;
|
||||
} else if (opline->opcode == ZEND_JMPZ_EX
|
||||
|| opline->opcode == ZEND_JMPNZ_EX
|
||||
|| opline->opcode == ZEND_JMP_SET
|
||||
|| opline->opcode == ZEND_COALESCE
|
||||
|| opline->opcode == ZEND_FE_RESET_R
|
||||
|| opline->opcode == ZEND_FE_RESET_RW
|
||||
|| opline->opcode == ZEND_FE_FETCH_R
|
||||
|| opline->opcode == ZEND_FE_FETCH_RW
|
||||
|| opline->opcode == ZEND_NEW) {
|
||||
/* we cannot simple remove jump instructions */
|
||||
return 0;
|
||||
} else if (var->use_chain >= 0
|
||||
|| var->phi_use_chain != NULL) {
|
||||
if (value
|
||||
|
@ -2090,16 +2014,7 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
|
|||
&& opline->opcode != ZEND_ROPE_INIT
|
||||
&& opline->opcode != ZEND_ROPE_ADD
|
||||
&& opline->opcode != ZEND_INIT_ARRAY
|
||||
&& opline->opcode != ZEND_ADD_ARRAY_ELEMENT
|
||||
&& opline->opcode != ZEND_JMPZ_EX
|
||||
&& opline->opcode != ZEND_JMPNZ_EX
|
||||
&& opline->opcode != ZEND_JMP_SET
|
||||
&& opline->opcode != ZEND_COALESCE
|
||||
&& opline->opcode != ZEND_FE_RESET_R
|
||||
&& opline->opcode != ZEND_FE_RESET_RW
|
||||
&& opline->opcode != ZEND_FE_FETCH_R
|
||||
&& opline->opcode != ZEND_FE_FETCH_RW
|
||||
&& opline->opcode != ZEND_NEW) {
|
||||
&& opline->opcode != ZEND_ADD_ARRAY_ELEMENT) {
|
||||
/* Replace with QM_ASSIGN */
|
||||
zend_uchar old_type = opline->result_type;
|
||||
zend_uchar old_var = opline->result.var;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue