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;
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) {
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:
#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;
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 */
#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) ? \
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) {