mirror of
https://github.com/php/php-src.git
synced 2026-04-26 01:18:19 +02:00
Merge branch 'PHP-7.1'
* PHP-7.1: Fixed CFG construction for stackless execution (split basic blocks after calls)
This commit is contained in:
@@ -24,11 +24,12 @@
|
||||
#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;
|
||||
@@ -39,7 +40,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
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);
|
||||
@@ -58,8 +59,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
} 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 ||
|
||||
@@ -89,7 +89,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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;
|
||||
@@ -123,7 +123,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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);
|
||||
@@ -161,7 +161,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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++;
|
||||
@@ -178,7 +178,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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) {
|
||||
@@ -186,7 +186,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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) {
|
||||
@@ -194,7 +194,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
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 {
|
||||
@@ -273,6 +273,8 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
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;
|
||||
|
||||
@@ -87,6 +87,7 @@ typedef struct _zend_cfg {
|
||||
int *predecessors;
|
||||
uint32_t *map;
|
||||
unsigned int split_at_live_ranges : 1;
|
||||
unsigned int split_at_calls : 1;
|
||||
} zend_cfg;
|
||||
|
||||
/* Build Flags */
|
||||
|
||||
Reference in New Issue
Block a user