mirror of
https://github.com/php/php-src.git
synced 2026-04-01 21:22:13 +02:00
Replace BB end with BB len
And support empty blocks everywhere.
This commit is contained in:
@@ -90,8 +90,9 @@ static void strip_leading_nops(zend_op_array *op_array, zend_basic_block *b)
|
||||
{
|
||||
zend_op *opcodes = op_array->opcodes;
|
||||
|
||||
while (opcodes[b->start].opcode == ZEND_NOP && b->start < b->end) {
|
||||
while (b->len > 0 && opcodes[b->start].opcode == ZEND_NOP) {
|
||||
b->start++;
|
||||
b->len--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,10 +101,13 @@ static void strip_nops(zend_op_array *op_array, zend_basic_block *b)
|
||||
uint32_t i, j;
|
||||
|
||||
strip_leading_nops(op_array, b);
|
||||
if (b->len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* strip the inside NOPs */
|
||||
i = j = b->start + 1;
|
||||
while (i <= b->end) {
|
||||
while (i < b->start + b->len) {
|
||||
if (op_array->opcodes[i].opcode != ZEND_NOP) {
|
||||
if (i != j) {
|
||||
op_array->opcodes[j] = op_array->opcodes[i];
|
||||
@@ -112,7 +116,7 @@ static void strip_nops(zend_op_array *op_array, zend_basic_block *b)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
b->end = j - 1;
|
||||
b->len = j - b->start;
|
||||
while (j < i) {
|
||||
MAKE_NOP(op_array->opcodes + j);
|
||||
j++;
|
||||
@@ -128,9 +132,8 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
|
||||
strip_leading_nops(op_array, block);
|
||||
|
||||
opline = op_array->opcodes + block->start;
|
||||
end = op_array->opcodes + block->end + 1;
|
||||
end = opline + block->len;
|
||||
while (opline < end) {
|
||||
|
||||
/* Constant Propagation: strip X = QM_ASSIGN(const) */
|
||||
if ((opline->op1_type & (IS_TMP_VAR|IS_VAR)) &&
|
||||
opline->opcode != ZEND_FREE) {
|
||||
@@ -769,34 +772,32 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
|
||||
int n;
|
||||
|
||||
for (b = blocks; b < end; b++) {
|
||||
if (b->len == 0) {
|
||||
continue;
|
||||
}
|
||||
if (b->flags & ZEND_BB_REACHABLE) {
|
||||
ZEND_ASSERT(b->start <= b->end);
|
||||
opline = op_array->opcodes + b->end;
|
||||
opline = op_array->opcodes + b->start + b->len - 1;
|
||||
if (opline->opcode == ZEND_JMP) {
|
||||
zend_basic_block *next = b + 1;
|
||||
|
||||
while (next < end && (!(next->flags & ZEND_BB_REACHABLE) || next->start > next->end)) {
|
||||
while (next < end && !(next->flags & ZEND_BB_REACHABLE)) {
|
||||
next++;
|
||||
}
|
||||
if (next < end && next == blocks + b->successors[0]) {
|
||||
/* JMP to the next block - strip it */
|
||||
MAKE_NOP(opline);
|
||||
if (b->end == 0) {
|
||||
b->start++;
|
||||
} else {
|
||||
b->end--;
|
||||
}
|
||||
b->len--;
|
||||
}
|
||||
} else if (b->start == b->end && opline->opcode == ZEND_NOP) {
|
||||
} else if (b->len == 1 && opline->opcode == ZEND_NOP) {
|
||||
/* skip empty block */
|
||||
b->start++;
|
||||
b->len--;
|
||||
}
|
||||
len += b->end - b->start + 1;
|
||||
} else if (b->start <= b->end) {
|
||||
len += b->len;
|
||||
} else {
|
||||
/* this block will not be used, delete all constants there */
|
||||
zend_op *op;
|
||||
zend_op *end = op_array->opcodes + b->end ;
|
||||
for (op = op_array->opcodes + b->start; op <= end; op++) {
|
||||
zend_op *op = op_array->opcodes + b->start;
|
||||
zend_op *end = op + b->len;
|
||||
for (; op < end; op++) {
|
||||
if (ZEND_OP1_TYPE(op) == IS_CONST) {
|
||||
literal_dtor(&ZEND_OP1_LITERAL(op));
|
||||
}
|
||||
@@ -813,16 +814,9 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
|
||||
/* Copy code of reachable blocks into a single buffer */
|
||||
for (b = blocks; b < end; b++) {
|
||||
if (b->flags & ZEND_BB_REACHABLE) {
|
||||
if (b->start <= b->end) {
|
||||
uint32_t n = b->end - b->start + 1;
|
||||
memcpy(opline, op_array->opcodes + b->start, n * sizeof(zend_op));
|
||||
b->start = opline - new_opcodes;
|
||||
b->end = opline - new_opcodes + n - 1;
|
||||
opline += n;
|
||||
} else {
|
||||
b->flags |= ZEND_BB_EMPTY;
|
||||
b->start = b->end = opline - new_opcodes;
|
||||
}
|
||||
memcpy(opline, op_array->opcodes + b->start, b->len * sizeof(zend_op));
|
||||
b->start = opline - new_opcodes;
|
||||
opline += b->len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,10 +826,10 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
|
||||
op_array->last = len;
|
||||
|
||||
for (b = blocks; b < end; b++) {
|
||||
if (!(b->flags & ZEND_BB_REACHABLE) || b->start > b->end) {
|
||||
if (!(b->flags & ZEND_BB_REACHABLE) || b->len == 0) {
|
||||
continue;
|
||||
}
|
||||
opline = op_array->opcodes + b->end;
|
||||
opline = op_array->opcodes + b->start + b->len - 1;
|
||||
switch (opline->opcode) {
|
||||
case ZEND_FAST_CALL:
|
||||
case ZEND_JMP:
|
||||
@@ -1002,8 +996,11 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
|
||||
zend_basic_block *blocks = cfg->blocks;
|
||||
zend_op *last_op;
|
||||
|
||||
ZEND_ASSERT(block->start <= block->end);
|
||||
last_op = op_array->opcodes + block->end;
|
||||
if (block->len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_op = op_array->opcodes + block->start + block->len - 1;
|
||||
switch (last_op->opcode) {
|
||||
case ZEND_JMP:
|
||||
{
|
||||
@@ -1019,9 +1016,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
|
||||
/* JMP(next) -> NOP */
|
||||
if (block->successors[0] == next) {
|
||||
MAKE_NOP(last_op);
|
||||
if (block->start != block->end) {
|
||||
block->end--;
|
||||
}
|
||||
block->len--;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1165,7 +1160,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
|
||||
|
||||
next_target:
|
||||
target = op_array->opcodes + target_block->start;
|
||||
target_end = op_array->opcodes + target_block->end + 1;
|
||||
target_end = target + target_block->len;
|
||||
while (target < target_end && target->opcode == ZEND_NOP) {
|
||||
target++;
|
||||
}
|
||||
@@ -1301,7 +1296,7 @@ next_target:
|
||||
target_block = blocks + block->successors[0];
|
||||
next_target_ex:
|
||||
target = op_array->opcodes + target_block->start;
|
||||
target_end = op_array->opcodes + target_block->end + 1;
|
||||
target_end = target + target_block->len;
|
||||
while (target < target_end && target->opcode == ZEND_NOP) {
|
||||
target++;
|
||||
}
|
||||
@@ -1424,7 +1419,7 @@ next_target_ex:
|
||||
|
||||
next_target_znz:
|
||||
target = op_array->opcodes + target_block->start;
|
||||
target_end = op_array->opcodes + target_block->end + 1;
|
||||
target_end = target + target_block->len;
|
||||
while (target < target_end && target->opcode == ZEND_NOP) {
|
||||
target++;
|
||||
}
|
||||
@@ -1497,7 +1492,7 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
|
||||
}
|
||||
|
||||
opline = op_array->opcodes + block->start;
|
||||
end = op_array->opcodes + block->end + 1;
|
||||
end = opline + block->len;
|
||||
if (!(block->flags & ZEND_BB_FOLLOW) ||
|
||||
(block->flags & ZEND_BB_TARGET)) {
|
||||
/* Skip continuation of "extended" BB */
|
||||
@@ -1572,12 +1567,12 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
|
||||
for (n = cfg->blocks_count; n > 0;) {
|
||||
block = cfg->blocks + (--n);
|
||||
|
||||
if (!(block->flags & ZEND_BB_REACHABLE)) {
|
||||
if (!(block->flags & ZEND_BB_REACHABLE) || block->len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
opline = op_array->opcodes + block->end;
|
||||
end = op_array->opcodes + block->start;
|
||||
opline = end + block->len - 1;
|
||||
if (!next_block ||
|
||||
!(next_block->flags & ZEND_BB_FOLLOW) ||
|
||||
(next_block->flags & ZEND_BB_TARGET)) {
|
||||
@@ -1697,16 +1692,17 @@ static void zend_merge_blocks(zend_op_array *op_array, zend_cfg *cfg)
|
||||
if ((b->flags & ZEND_BB_FOLLOW) &&
|
||||
!(b->flags & (ZEND_BB_TARGET | ZEND_BB_PROTECTED)) &&
|
||||
prev &&
|
||||
prev->successors[0] == i && prev->successors[1] == -1) {
|
||||
|
||||
if (op_array->opcodes[prev->end].opcode == ZEND_JMP) {
|
||||
MAKE_NOP(op_array->opcodes + prev->end);
|
||||
prev->successors[0] == i && prev->successors[1] == -1)
|
||||
{
|
||||
zend_op *last_op = op_array->opcodes + prev->start + prev->len - 1;
|
||||
if (prev->len != 0 && last_op->opcode == ZEND_JMP) {
|
||||
MAKE_NOP(last_op);
|
||||
}
|
||||
|
||||
for (bb = prev + 1; bb != b; bb++) {
|
||||
zend_op *op = op_array->opcodes + bb->start;
|
||||
zend_op *end = op_array->opcodes + bb->end;
|
||||
while (op <= end) {
|
||||
zend_op *end = op + bb->len;
|
||||
while (op < end) {
|
||||
if (ZEND_OP1_TYPE(op) == IS_CONST) {
|
||||
literal_dtor(&ZEND_OP1_LITERAL(op));
|
||||
}
|
||||
@@ -1717,18 +1713,18 @@ static void zend_merge_blocks(zend_op_array *op_array, zend_cfg *cfg)
|
||||
op++;
|
||||
}
|
||||
/* make block empty */
|
||||
bb->start = bb->end + 1;
|
||||
bb->len = 0;
|
||||
}
|
||||
|
||||
/* re-link */
|
||||
prev->flags |= (b->flags & ZEND_BB_EXIT);
|
||||
prev->end = b->end;
|
||||
prev->flags |= (b->flags & ZEND_BB_EXIT);
|
||||
prev->len = b->start + b->len - prev->start;
|
||||
prev->successors[0] = b->successors[0];
|
||||
prev->successors[1] = b->successors[1];
|
||||
|
||||
/* unlink & make block empty and unreachable */
|
||||
b->flags = 0;
|
||||
b->start = b->end + 1;
|
||||
b->len = 0;
|
||||
b->successors[0] = -1;
|
||||
b->successors[1] = -1;
|
||||
} else {
|
||||
|
||||
@@ -129,16 +129,18 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||
memset(shiftlist, 0, sizeof(uint32_t) * op_array->last);
|
||||
for (b = blocks; b < end; b++) {
|
||||
if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) {
|
||||
uint32_t end;
|
||||
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;
|
||||
b->len = 1;
|
||||
}
|
||||
|
||||
end = b->start + b->len;
|
||||
i = b->start;
|
||||
b->start = target;
|
||||
while (i <= b->end) {
|
||||
while (i < end) {
|
||||
if (EXPECTED(op_array->opcodes[i].opcode != ZEND_NOP) ||
|
||||
/*keep NOP to support ZEND_VM_SMART_BRANCH */
|
||||
(i > 0 &&
|
||||
@@ -168,13 +170,13 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (b->end != target - 1) {
|
||||
if (target != end && b->len != 0) {
|
||||
zend_op *opline;
|
||||
zend_op *new_opline;
|
||||
|
||||
opline = op_array->opcodes + b->end;
|
||||
b->end = target - 1;
|
||||
new_opline = op_array->opcodes + b->end;
|
||||
opline = op_array->opcodes + end - 1;
|
||||
b->len = target - b->start;
|
||||
new_opline = op_array->opcodes + target - 1;
|
||||
switch (new_opline->opcode) {
|
||||
case ZEND_JMP:
|
||||
case ZEND_FAST_CALL:
|
||||
@@ -239,8 +241,8 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||
|
||||
/* update branch targets */
|
||||
for (b = blocks; b < end; b++) {
|
||||
if (b->flags & ZEND_BB_REACHABLE) {
|
||||
zend_op *opline = op_array->opcodes + b->end;
|
||||
if ((b->flags & ZEND_BB_REACHABLE) && b->len != 0) {
|
||||
zend_op *opline = op_array->opcodes + b->start + b->len - 1;
|
||||
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMP:
|
||||
|
||||
@@ -39,15 +39,17 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
if (!(b0->flags & ZEND_BB_REACHABLE)) {
|
||||
zend_mark_reachable(opcodes, blocks, b0);
|
||||
}
|
||||
opcode = opcodes[b->end].opcode;
|
||||
|
||||
ZEND_ASSERT(b->len != 0);
|
||||
opcode = opcodes[b->start + b->len - 1].opcode;
|
||||
b = blocks + successor_1;
|
||||
if (opcode == ZEND_JMPZNZ) {
|
||||
b->flags |= ZEND_BB_TARGET;
|
||||
} else {
|
||||
b->flags |= ZEND_BB_FOLLOW;
|
||||
}
|
||||
} else {
|
||||
opcode = opcodes[b->end].opcode;
|
||||
} else if (b->len != 0) {
|
||||
opcode = opcodes[b->start + b->len - 1].opcode;
|
||||
b = blocks + successor_0;
|
||||
if (opcode == ZEND_JMP) {
|
||||
b->flags |= ZEND_BB_TARGET;
|
||||
@@ -67,6 +69,9 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
b = blocks + successor_0;
|
||||
b->flags |= ZEND_BB_FOLLOW;
|
||||
}
|
||||
if (b->flags & ZEND_BB_REACHABLE) return;
|
||||
} else {
|
||||
@@ -94,24 +99,24 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
|
||||
/* Add live range paths */
|
||||
for (j = 0; j < op_array->last_live_range; j++) {
|
||||
if (op_array->live_range[j].var == (uint32_t)-1) {
|
||||
zend_live_range *live_range = &op_array->live_range[j];
|
||||
if (live_range->var == (uint32_t)-1) {
|
||||
/* this live range already removed */
|
||||
continue;
|
||||
}
|
||||
b = blocks + block_map[op_array->live_range[j].start];
|
||||
b = blocks + block_map[live_range->start];
|
||||
if (b->flags & ZEND_BB_REACHABLE) {
|
||||
while (op_array->opcodes[b->start].opcode == ZEND_NOP && b->start != b->end) {
|
||||
while (b->len > 0 && op_array->opcodes[b->start].opcode == ZEND_NOP) {
|
||||
b->start++;
|
||||
b->len--;
|
||||
}
|
||||
if (op_array->opcodes[b->start].opcode == ZEND_NOP &&
|
||||
b->start == b->end &&
|
||||
b->successors[0] == block_map[op_array->live_range[j].end]) {
|
||||
if (b->len == 0 && b->successors[0] == block_map[live_range->end]) {
|
||||
/* mark as removed (empty live range) */
|
||||
op_array->live_range[j].var = (uint32_t)-1;
|
||||
live_range->var = (uint32_t)-1;
|
||||
continue;
|
||||
}
|
||||
b->flags |= ZEND_BB_GEN_VAR;
|
||||
b = blocks + block_map[op_array->live_range[j].end];
|
||||
b = blocks + block_map[live_range->end];
|
||||
b->flags |= ZEND_BB_KILL_VAR;
|
||||
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
||||
if (cfg->split_at_live_ranges) {
|
||||
@@ -119,12 +124,12 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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);
|
||||
ZEND_ASSERT(b->start == live_range->end);
|
||||
b->flags |= ZEND_BB_UNREACHABLE_FREE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ZEND_ASSERT(!(blocks[block_map[op_array->live_range[j].end]].flags & ZEND_BB_REACHABLE));
|
||||
ZEND_ASSERT(!(blocks[block_map[live_range->end]].flags & ZEND_BB_REACHABLE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,7 +440,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
for (i = 0, blocks_count = -1; i < op_array->last; i++) {
|
||||
if (block_map[i]) {
|
||||
if (blocks_count >= 0) {
|
||||
blocks[blocks_count].end = i - 1;
|
||||
blocks[blocks_count].len = i - blocks[blocks_count].start;
|
||||
}
|
||||
blocks_count++;
|
||||
blocks[blocks_count].flags = 0;
|
||||
@@ -453,13 +458,19 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
block_map[i] = blocks_count;
|
||||
}
|
||||
|
||||
blocks[blocks_count].end = i - 1;
|
||||
blocks[blocks_count].len = i - blocks[blocks_count].start;
|
||||
blocks_count++;
|
||||
|
||||
/* Build CFG, Step 3: Calculate successors */
|
||||
for (j = 0; j < blocks_count; j++) {
|
||||
zend_op *opline = op_array->opcodes + blocks[j].end;
|
||||
switch(opline->opcode) {
|
||||
zend_op *opline;
|
||||
if (blocks[j].len == 0) {
|
||||
record_successor(blocks, j, 0, j + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1;
|
||||
switch (opline->opcode) {
|
||||
case ZEND_FAST_RET:
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#define ZEND_BB_FINALLY_END (1<<8) /* end of finally block */
|
||||
#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_EMPTY (1<<11)
|
||||
#define ZEND_BB_UNREACHABLE_FREE (1<<12) /* unreachable loop free */
|
||||
#define ZEND_BB_UNREACHABLE_FREE (1<<11) /* unreachable loop free */
|
||||
|
||||
#define ZEND_BB_LOOP_HEADER (1<<16)
|
||||
#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
|
||||
@@ -44,7 +43,7 @@
|
||||
typedef struct _zend_basic_block {
|
||||
uint32_t flags;
|
||||
uint32_t start; /* first opcode number */
|
||||
uint32_t end; /* last opcode number */
|
||||
uint32_t len; /* number of opcodes */
|
||||
int successors[2]; /* up to 2 successor blocks */
|
||||
int predecessors_count; /* number of predecessors */
|
||||
int predecessor_offset; /* offset of 1-st predecessor */
|
||||
|
||||
@@ -26,7 +26,6 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
|
||||
zend_basic_block *blocks = cfg->blocks;
|
||||
int blocks_count = cfg->blocks_count;
|
||||
zend_bitset tmp, def, use, in, out;
|
||||
zend_op *opline;
|
||||
uint32_t k, var_num;
|
||||
int j;
|
||||
|
||||
@@ -39,15 +38,17 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
|
||||
|
||||
/* Collect "def" and "use" sets */
|
||||
for (j = 0; j < blocks_count; j++) {
|
||||
zend_op *opline, *end;
|
||||
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
|
||||
continue;
|
||||
}
|
||||
for (k = blocks[j].start; k <= blocks[j].end; k++) {
|
||||
opline = op_array->opcodes + k;
|
||||
|
||||
opline = op_array->opcodes + blocks[j].start;
|
||||
end = opline + blocks[j].len;
|
||||
for (; opline < end; opline++) {
|
||||
if (opline->opcode != ZEND_OP_DATA) {
|
||||
zend_op *next = opline + 1;
|
||||
if (k < blocks[j].end &&
|
||||
next->opcode == ZEND_OP_DATA) {
|
||||
if (next < end && next->opcode == ZEND_OP_DATA) {
|
||||
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
var_num = EX_VAR_TO_NUM(next->op1.var);
|
||||
if (!DFG_ISSET(def, set_size, j, var_num)) {
|
||||
|
||||
@@ -722,7 +722,11 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags
|
||||
if (b->flags & ZEND_BB_IRREDUCIBLE_LOOP) {
|
||||
fprintf(stderr, " irreducible");
|
||||
}
|
||||
fprintf(stderr, " lines=[%d-%d]", b->start, b->end);
|
||||
if (b->len != 0) {
|
||||
fprintf(stderr, " lines=[%d-%d]", b->start, b->start + b->len - 1);
|
||||
} else {
|
||||
fprintf(stderr, " empty");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (b->predecessors_count) {
|
||||
@@ -936,13 +940,11 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons
|
||||
const zend_op *end;
|
||||
|
||||
zend_dump_block_header(cfg, op_array, ssa, n, dump_flags);
|
||||
if (!(b->flags & ZEND_BB_EMPTY)) {
|
||||
opline = op_array->opcodes + b->start;
|
||||
end = op_array->opcodes + b->end + 1;
|
||||
while (opline < end) {
|
||||
zend_dump_op(op_array, b, opline, dump_flags, data);
|
||||
opline++;
|
||||
}
|
||||
opline = op_array->opcodes + b->start;
|
||||
end = opline + b->len;
|
||||
while (opline < end) {
|
||||
zend_dump_op(op_array, b, opline, dump_flags, data);
|
||||
opline++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3613,8 +3613,8 @@ void zend_func_return_info(const zend_op_array *op_array,
|
||||
}
|
||||
|
||||
for (j = 0; j < blocks_count; j++) {
|
||||
if (blocks[j].flags & ZEND_BB_REACHABLE) {
|
||||
zend_op *opline = op_array->opcodes + blocks[j].end;
|
||||
if ((blocks[j].flags & ZEND_BB_REACHABLE) && blocks[j].len != 0) {
|
||||
zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1;
|
||||
|
||||
if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) {
|
||||
if (!recursive &&
|
||||
|
||||
@@ -225,11 +225,11 @@ static void place_essa_pis(
|
||||
int j, blocks_count = ssa->cfg.blocks_count;
|
||||
for (j = 0; j < blocks_count; j++) {
|
||||
zend_ssa_phi *pi;
|
||||
zend_op *opline = op_array->opcodes + ssa->cfg.blocks[j].end;
|
||||
zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1;
|
||||
int bt; /* successor block number if a condition is true */
|
||||
int bf; /* successor block number if a condition is false */
|
||||
|
||||
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
|
||||
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0 || blocks[j].len == 0) {
|
||||
continue;
|
||||
}
|
||||
/* the last instruction of basic block is conditional branch,
|
||||
@@ -238,12 +238,12 @@ static void place_essa_pis(
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMPZ:
|
||||
case ZEND_JMPZNZ:
|
||||
bf = ssa->cfg.blocks[j].successors[0];
|
||||
bt = ssa->cfg.blocks[j].successors[1];
|
||||
bf = blocks[j].successors[0];
|
||||
bt = blocks[j].successors[1];
|
||||
break;
|
||||
case ZEND_JMPNZ:
|
||||
bt = ssa->cfg.blocks[j].successors[0];
|
||||
bf = ssa->cfg.blocks[j].successors[1];
|
||||
bt = blocks[j].successors[0];
|
||||
bf = blocks[j].successors[1];
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
@@ -493,8 +493,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
|
||||
zend_ssa_op *ssa_ops = ssa->ops;
|
||||
int ssa_vars_count = ssa->vars_count;
|
||||
int i, j;
|
||||
uint32_t k;
|
||||
zend_op *opline;
|
||||
zend_op *opline, *end;
|
||||
int *tmp = NULL;
|
||||
ALLOCA_FLAG(use_heap);
|
||||
|
||||
@@ -519,12 +518,13 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
|
||||
} while (phi);
|
||||
}
|
||||
|
||||
for (k = blocks[n].start; k <= blocks[n].end; k++) {
|
||||
opline = op_array->opcodes + k;
|
||||
opline = op_array->opcodes + blocks[n].start;
|
||||
end = opline + blocks[n].len;
|
||||
for (; opline < end; opline++) {
|
||||
uint32_t k = opline - op_array->opcodes;
|
||||
if (opline->opcode != ZEND_OP_DATA) {
|
||||
zend_op *next = opline + 1;
|
||||
if (k < blocks[n].end &&
|
||||
next->opcode == ZEND_OP_DATA) {
|
||||
if (next < end && next->opcode == ZEND_OP_DATA) {
|
||||
if (next->op1_type == IS_CV) {
|
||||
ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
|
||||
//USE_SSA_VAR(next->op1.var);
|
||||
|
||||
Reference in New Issue
Block a user