#include "zend_optimizer.h"
#include "zend_optimizer_internal.h"
-static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend_basic_block *b) /* {{{ */
+static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_block *b) /* {{{ */
{
zend_uchar opcode;
zend_basic_block *b0;
int successor_0, successor_1;
+ zend_basic_block *blocks = cfg->blocks;
while (1) {
b->flags |= ZEND_BB_REACHABLE;
b0 = blocks + successor_0;
b0->flags |= ZEND_BB_TARGET;
if (!(b0->flags & ZEND_BB_REACHABLE)) {
- zend_mark_reachable(opcodes, blocks, b0);
+ zend_mark_reachable(opcodes, cfg, b0);
}
ZEND_ASSERT(b->len != 0);
} else {
b->flags |= ZEND_BB_FOLLOW;
- //TODO: support for stackless CFG???
- if (0/*stackless*/) {
+ if (cfg->split_at_calls) {
if (opcode == ZEND_INCLUDE_OR_EVAL ||
opcode == ZEND_GENERATOR_CREATE ||
opcode == ZEND_YIELD ||
zend_basic_block *blocks = cfg->blocks;
blocks[start].flags = ZEND_BB_START;
- zend_mark_reachable(op_array->opcodes, blocks, blocks + start);
+ zend_mark_reachable(op_array->opcodes, cfg, blocks + start);
if (op_array->last_live_range || op_array->last_try_catch) {
zend_basic_block *b;
if (!(b->flags & ZEND_BB_REACHABLE)) {
if (cfg->split_at_live_ranges) {
changed = 1;
- zend_mark_reachable(op_array->opcodes, blocks, b);
+ zend_mark_reachable(op_array->opcodes, cfg, b);
} else {
ZEND_ASSERT(!(b->flags & ZEND_BB_UNREACHABLE_FREE));
ZEND_ASSERT(b->start == live_range->end);
if (b->flags & ZEND_BB_REACHABLE) {
op_array->try_catch_array[j].try_op = op_array->try_catch_array[j].catch_op;
changed = 1;
- zend_mark_reachable(op_array->opcodes, blocks, blocks + block_map[op_array->try_catch_array[j].try_op]);
+ zend_mark_reachable(op_array->opcodes, cfg, blocks + block_map[op_array->try_catch_array[j].try_op]);
break;
}
b++;
b->flags |= ZEND_BB_CATCH;
if (!(b->flags & ZEND_BB_REACHABLE)) {
changed = 1;
- zend_mark_reachable(op_array->opcodes, blocks, b);
+ zend_mark_reachable(op_array->opcodes, cfg, b);
}
}
if (op_array->try_catch_array[j].finally_op) {
b->flags |= ZEND_BB_FINALLY;
if (!(b->flags & ZEND_BB_REACHABLE)) {
changed = 1;
- zend_mark_reachable(op_array->opcodes, blocks, b);
+ zend_mark_reachable(op_array->opcodes, cfg, b);
}
}
if (op_array->try_catch_array[j].finally_end) {
b->flags |= ZEND_BB_FINALLY_END;
if (!(b->flags & ZEND_BB_REACHABLE)) {
changed = 1;
- zend_mark_reachable(op_array->opcodes, blocks, b);
+ zend_mark_reachable(op_array->opcodes, cfg, b);
}
}
} else {
zend_bool extra_entry_block = 0;
cfg->split_at_live_ranges = (build_flags & ZEND_CFG_SPLIT_AT_LIVE_RANGES) != 0;
+ cfg->split_at_calls = (build_flags & ZEND_CFG_STACKLESS) != 0;
+
cfg->map = block_map = zend_arena_calloc(arena, op_array->last, sizeof(uint32_t));
if (!block_map) {
return FAILURE;