summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-08-22 16:49:31 +0300
committerDmitry Stogov <dmitry@zend.com>2016-08-22 16:49:31 +0300
commitd79492c2184a07ecbf48cb0fe7a15769dd7aa2b1 (patch)
tree516878edd833fc04677734b94a8822cd21f9e113
parent7cb784fccad2578178bacec704548cc10ffdb770 (diff)
parentcaf890b29166c8a1c921b7f9d9fa4e6eec02c0dd (diff)
downloadphp-git-d79492c2184a07ecbf48cb0fe7a15769dd7aa2b1.tar.gz
Merge branch 'PHP-7.1'
* PHP-7.1: Fixed CFG construction for stackless execution (split basic blocks after calls)
-rw-r--r--ext/opcache/Optimizer/zend_cfg.c22
-rw-r--r--ext/opcache/Optimizer/zend_cfg.h1
2 files changed, 13 insertions, 10 deletions
diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c
index 335ad75827..92d648dc23 100644
--- a/ext/opcache/Optimizer/zend_cfg.c
+++ b/ext/opcache/Optimizer/zend_cfg.c
@@ -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;
diff --git a/ext/opcache/Optimizer/zend_cfg.h b/ext/opcache/Optimizer/zend_cfg.h
index da908fdbe3..0682629019 100644
--- a/ext/opcache/Optimizer/zend_cfg.h
+++ b/ext/opcache/Optimizer/zend_cfg.h
@@ -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 */