mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Improve previous fix
Do not mark loop var free blocks as reachable after all -- as we can't construct SSA for unreachable blocks, this would cause issues down the line. Instead add an extra UNREACHABLE_FREE flag and retain only the FREE instruction during NOP removal. (If we retain all instructions in the BB we might leave a jump instruction that goes into the nowhere.)
This commit is contained in:
parent
fa9566627b
commit
0d62dfdf81
4 changed files with 18 additions and 5 deletions
|
@ -128,7 +128,14 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||||
shiftlist = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last, use_heap);
|
shiftlist = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last, use_heap);
|
||||||
memset(shiftlist, 0, sizeof(uint32_t) * op_array->last);
|
memset(shiftlist, 0, sizeof(uint32_t) * op_array->last);
|
||||||
for (b = blocks; b < end; b++) {
|
for (b = blocks; b < end; b++) {
|
||||||
if (b->flags & ZEND_BB_REACHABLE) {
|
if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) {
|
||||||
|
if (b->flags & ZEND_BB_UNREACHABLE_FREE) {
|
||||||
|
/* Only keep the FREE for the loop var */
|
||||||
|
ZEND_ASSERT(op_array->opcodes[b->start].opcode == ZEND_FREE
|
||||||
|
|| op_array->opcodes[b->start].opcode == ZEND_FE_FREE);
|
||||||
|
b->end = b->start;
|
||||||
|
}
|
||||||
|
|
||||||
i = b->start;
|
i = b->start;
|
||||||
b->start = target;
|
b->start = target;
|
||||||
while (i <= b->end) {
|
while (i <= b->end) {
|
||||||
|
|
|
@ -114,8 +114,14 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||||
b = blocks + block_map[op_array->live_range[j].end];
|
b = blocks + block_map[op_array->live_range[j].end];
|
||||||
b->flags |= ZEND_BB_KILL_VAR;
|
b->flags |= ZEND_BB_KILL_VAR;
|
||||||
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
||||||
changed = 1;
|
if (cfg->split_at_live_ranges) {
|
||||||
zend_mark_reachable(op_array->opcodes, blocks, b);
|
changed = 1;
|
||||||
|
zend_mark_reachable(op_array->opcodes, blocks, b);
|
||||||
|
} else {
|
||||||
|
ZEND_ASSERT(!(b->flags & ZEND_BB_UNREACHABLE_FREE));
|
||||||
|
ZEND_ASSERT(b->start == op_array->live_range[j].end);
|
||||||
|
b->flags |= ZEND_BB_UNREACHABLE_FREE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZEND_ASSERT(!(blocks[block_map[op_array->live_range[j].end]].flags & ZEND_BB_REACHABLE));
|
ZEND_ASSERT(!(blocks[block_map[op_array->live_range[j].end]].flags & ZEND_BB_REACHABLE));
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define ZEND_BB_GEN_VAR (1<<9) /* start of live range */
|
#define ZEND_BB_GEN_VAR (1<<9) /* start of live range */
|
||||||
#define ZEND_BB_KILL_VAR (1<<10) /* end of live range */
|
#define ZEND_BB_KILL_VAR (1<<10) /* end of live range */
|
||||||
#define ZEND_BB_EMPTY (1<<11)
|
#define ZEND_BB_EMPTY (1<<11)
|
||||||
|
#define ZEND_BB_UNREACHABLE_FREE (1<<12) /* unreachable loop free */
|
||||||
|
|
||||||
#define ZEND_BB_LOOP_HEADER (1<<16)
|
#define ZEND_BB_LOOP_HEADER (1<<16)
|
||||||
#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
|
#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
|
||||||
|
|
|
@ -399,9 +399,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
|
||||||
|
|
||||||
if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) {
|
if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) {
|
||||||
if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||||
if (ssa && ssa->ops) {
|
if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_def >= 0) {
|
||||||
int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def;
|
int ssa_var_num = ssa->ops[opline - op_array->opcodes].result_def;
|
||||||
ZEND_ASSERT(ssa_var_num >= 0);
|
|
||||||
zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
|
zend_dump_ssa_var(op_array, ssa, ssa_var_num, opline->result_type, EX_VAR_TO_NUM(opline->result.var), dump_flags);
|
||||||
} else {
|
} else {
|
||||||
zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));
|
zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue