summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/opcache/Optimizer/block_pass.c102
-rw-r--r--ext/opcache/Optimizer/dfa_pass.c18
-rw-r--r--ext/opcache/Optimizer/zend_cfg.c45
-rw-r--r--ext/opcache/Optimizer/zend_cfg.h5
-rw-r--r--ext/opcache/Optimizer/zend_dfg.c11
-rw-r--r--ext/opcache/Optimizer/zend_dump.c18
-rw-r--r--ext/opcache/Optimizer/zend_inference.c4
-rw-r--r--ext/opcache/Optimizer/zend_ssa.c24
8 files changed, 119 insertions, 108 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 6ad5110999..2e84b73252 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -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 {
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c
index 40a3dc996b..f7cae772fb 100644
--- a/ext/opcache/Optimizer/dfa_pass.c
+++ b/ext/opcache/Optimizer/dfa_pass.c
@@ -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:
diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c
index 33c34b85c4..2bf43fe9c5 100644
--- a/ext/opcache/Optimizer/zend_cfg.c
+++ b/ext/opcache/Optimizer/zend_cfg.c
@@ -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:
diff --git a/ext/opcache/Optimizer/zend_cfg.h b/ext/opcache/Optimizer/zend_cfg.h
index cbf4225a31..244a2ade97 100644
--- a/ext/opcache/Optimizer/zend_cfg.h
+++ b/ext/opcache/Optimizer/zend_cfg.h
@@ -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 */
diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c
index c1972128d5..abc9b3a1f5 100644
--- a/ext/opcache/Optimizer/zend_dfg.c
+++ b/ext/opcache/Optimizer/zend_dfg.c
@@ -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)) {
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index 70abe4d317..d85fb82d83 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -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++;
}
}
}
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index fd39baf749..168609f9a0 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -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 &&
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index a008e1029b..3c3e758b0d 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -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);