1
0
mirror of https://github.com/php/php-src.git synced 2026-03-25 16:52:18 +01:00

Allow optional splitting of basic blocks at RECV/RECV_INIT opcodes.

This commit is contained in:
Dmitry Stogov
2016-08-29 20:35:17 +03:00
parent 5c8aa478da
commit 94fbcbe172
3 changed files with 18 additions and 2 deletions

View File

@@ -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:

View File

@@ -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) ? \

View File

@@ -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) {