int i;
int removed_ops = 0;
+ if (!(ssa->cfg.flags & ZEND_FUNC_FREE_LOOP_VAR)) {
+ return 0;
+ }
for (i = 0; i < ssa->cfg.blocks_count; i++) {
if (!zend_bitset_in(scdf->executable_blocks, i)
&& (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE)
blocks[start].flags = ZEND_BB_START;
zend_mark_reachable(op_array->opcodes, cfg, blocks + start);
- if (op_array->last_live_range || op_array->last_try_catch) {
+ if (op_array->last_try_catch) {
zend_basic_block *b;
int j, changed;
uint32_t *block_map = cfg->map;
}
}
} while (changed);
+ }
+
+ if (cfg->flags & ZEND_FUNC_FREE_LOOP_VAR) {
+ zend_basic_block *b;
+ int j;
+ uint32_t *block_map = cfg->map;
/* Mark blocks that are unreachable, but free a loop var created in a reachable block. */
for (b = blocks; b < blocks + cfg->blocks_count; b++) {
case ZEND_EXT_FCALL_END:
flags |= ZEND_FUNC_HAS_EXTENDED_INFO;
break;
+ case ZEND_FREE:
+ if (opline->extended_value == ZEND_FREE_SWITCH) {
+ flags |= ZEND_FUNC_FREE_LOOP_VAR;
+ }
+ break;
+ case ZEND_FE_FREE:
+ flags |= ZEND_FUNC_FREE_LOOP_VAR;
+ break;
}
}
#define ZEND_FUNC_VARARG (1<<2) /* uses func_get_args() */
#define ZEND_FUNC_NO_LOOPS (1<<3)
#define ZEND_FUNC_IRREDUCIBLE (1<<4)
+#define ZEND_FUNC_FREE_LOOP_VAR (1<<5)
#define ZEND_FUNC_RECURSIVE (1<<7)
#define ZEND_FUNC_RECURSIVE_DIRECTLY (1<<8)
#define ZEND_FUNC_RECURSIVE_INDIRECTLY (1<<9)