summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-08-29 20:35:17 +0300
committerDmitry Stogov <dmitry@zend.com>2016-08-29 20:35:17 +0300
commit94fbcbe17265b11e26dee6cfaf2bb7913beef461 (patch)
treed9f2976b58c9f15f28c6225512dce5aaa85c81f1
parent5c8aa478da029879950650cc89cd830fb0876ed4 (diff)
downloadphp-git-94fbcbe17265b11e26dee6cfaf2bb7913beef461.tar.gz
Allow optional splitting of basic blocks at RECV/RECV_INIT opcodes.
-rw-r--r--ext/opcache/Optimizer/zend_cfg.c13
-rw-r--r--ext/opcache/Optimizer/zend_cfg.h5
-rw-r--r--ext/opcache/Optimizer/zend_dump.c2
3 files changed, 18 insertions, 2 deletions
diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c
index 04be6a2e26..f39f9650ae 100644
--- a/ext/opcache/Optimizer/zend_cfg.c
+++ b/ext/opcache/Optimizer/zend_cfg.c
@@ -70,6 +70,12 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
b->flags |= ZEND_BB_ENTRY;
}
}
+ if (cfg->split_at_recv) {
+ if (opcode == ZEND_RECV ||
+ opcode == ZEND_RECV_INIT) {
+ b->flags |= ZEND_BB_RECV_ENTRY;
+ }
+ }
}
} else {
b = blocks + successor_0;
@@ -283,6 +289,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
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->split_at_recv = (build_flags & ZEND_CFG_RECV_ENTRY) != 0 && (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0;
cfg->map = block_map = zend_arena_calloc(arena, op_array->last, sizeof(uint32_t));
if (!block_map) {
@@ -294,6 +301,12 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
for (i = 0; i < op_array->last; i++) {
zend_op *opline = op_array->opcodes + i;
switch(opline->opcode) {
+ case ZEND_RECV:
+ case ZEND_RECV_INIT:
+ if (build_flags & ZEND_CFG_RECV_ENTRY) {
+ BB_START(i + 1);
+ }
+ break;
case ZEND_RETURN:
case ZEND_RETURN_BY_REF:
case ZEND_GENERATOR_RETURN:
diff --git a/ext/opcache/Optimizer/zend_cfg.h b/ext/opcache/Optimizer/zend_cfg.h
index 0682629019..1ffb62add0 100644
--- a/ext/opcache/Optimizer/zend_cfg.h
+++ b/ext/opcache/Optimizer/zend_cfg.h
@@ -32,13 +32,14 @@
#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_UNREACHABLE_FREE (1<<11) /* unreachable loop free */
+#define ZEND_BB_RECV_ENTRY (1<<12) /* RECV entry */
#define ZEND_BB_LOOP_HEADER (1<<16)
#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
#define ZEND_BB_REACHABLE (1<<31)
-#define ZEND_BB_PROTECTED (ZEND_BB_ENTRY|ZEND_BB_TRY|ZEND_BB_CATCH|ZEND_BB_FINALLY|ZEND_BB_FINALLY_END|ZEND_BB_GEN_VAR|ZEND_BB_KILL_VAR)
+#define ZEND_BB_PROTECTED (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY|ZEND_BB_TRY|ZEND_BB_CATCH|ZEND_BB_FINALLY|ZEND_BB_FINALLY_END|ZEND_BB_GEN_VAR|ZEND_BB_KILL_VAR)
typedef struct _zend_basic_block {
uint32_t flags;
@@ -88,6 +89,7 @@ typedef struct _zend_cfg {
uint32_t *map;
unsigned int split_at_live_ranges : 1;
unsigned int split_at_calls : 1;
+ unsigned int split_at_recv : 1;
} zend_cfg;
/* Build Flags */
@@ -98,6 +100,7 @@ typedef struct _zend_cfg {
#define ZEND_SSA_RC_INFERENCE (1<<27)
#define ZEND_CFG_SPLIT_AT_LIVE_RANGES (1<<26)
#define ZEND_CFG_NO_ENTRY_PREDECESSORS (1<<25)
+#define ZEND_CFG_RECV_ENTRY (1<<24)
#define CRT_CONSTANT_EX(op_array, node, rt_constants) \
((rt_constants) ? \
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index a611b55cd5..ed9b6a59d9 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -669,7 +669,7 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags
if (b->flags & ZEND_BB_EXIT) {
fprintf(stderr, " exit");
}
- if (b->flags & ZEND_BB_ENTRY) {
+ if (b->flags & (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) {
fprintf(stderr, " entry");
}
if (b->flags & ZEND_BB_TRY) {