com php-src: Fixed CFG construction for stackless execution (split basic blocks after calls): ext/opcache/Optimizer/zend_cfg.c ext
/opcache/Optimizer/zend_cfg.h
| From: | Dmitry Stogov | Date: | Mon, 22 Aug 2016 13:48:26 +0000 |
| Subject: | com php-src: Fixed CFG construction for stackless execution (split basic blocks after calls): ext/opcache/Optimizer/zend_cfg.c ext /opcache/Optimizer/zend_cfg.h |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-94042@lists.php.net to get a copy of this message | ||
Commit: caf890b29166c8a1c921b7f9d9fa4e6eec02c0dd
Author: Dmitry Stogov <dmitry@zend.com> Mon, 22 Aug 2016 16:48:26 +0300
Parents: 7d703a0060dcc6709304ca956c8aa5bdbfa7625c
Branches: PHP-7.1 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=caf890b29166c8a1c921b7f9d9fa4e6eec02c0dd
Log:
Fixed CFG construction for stackless execution (split basic blocks after calls)
Changed paths:
M ext/opcache/Optimizer/zend_cfg.c
M ext/opcache/Optimizer/zend_cfg.h
Diff:
diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c
index 335ad75..92d648d 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 da908fd..0682629 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 */