62static inline bool is_bad_mod(
const zend_ssa *ssa,
int use,
int def) {
74static inline bool may_have_side_effects(
77 bool reorder_dtor_effects) {
189 if (!reorder_dtor_effects) {
227 if (!reorder_dtor_effects) {
280 if (!check || zend_bitset_in(ctx->
phi_dead, var_num)) {
286static inline void add_to_phi_worklist_no_val(
context *ctx,
int var_num) {
295 add_to_worklists(ctx, ssa_op->
result_use, check);
298 if (!zend_ssa_is_no_val_use(opline, ssa_op, ssa_op->
op1_use)
301 add_to_worklists(ctx, ssa_op->
op1_use, check);
303 add_to_phi_worklist_no_val(ctx, ssa_op->
op1_use);
307 if (!zend_ssa_is_no_val_use(opline, ssa_op, ssa_op->
op2_use)
310 add_to_worklists(ctx, ssa_op->
op2_use, check);
312 add_to_phi_worklist_no_val(ctx, ssa_op->
op2_use);
321 add_to_worklists(ctx, source, check);
325static inline bool is_var_dead(
context *ctx,
int var_num) {
328 return zend_bitset_in(ctx->
phi_dead, var_num);
340static bool try_remove_var_def(
context *ctx,
int free_var,
int use_chain,
zend_op *opline) {
341 if (use_chain >= 0) {
355 switch (def_opline->
opcode) {
406 return !is_var_dead(ctx, ssa_op->
op1_use);
416 uint8_t free_var_type;
423 if (is_free_of_live_var(ctx, opline, ssa_op)) {
450 zend_ssa_rename_defs_of_instr(ctx->
ssa, ssa_op);
467 int common_source = -1;
473 if (common_source == -1) {
474 common_source = source;
475 }
else if (common_source != source) {
483 return common_source;
490 int common_source = get_common_phi_source(ssa, phi);
491 if (common_source >= 0) {
522static inline bool may_throw_dce_exception(
const zend_op *opline) {
539 void *checkpoint = zend_arena_checkpoint(optimizer_ctx->
arena);
559 add_phi_sources_to_worklists(&ctx, phi, 0);
573 i = block->
start + block->len;
574 while (i > block->start) {
584 add_operands_to_worklists(&ctx, &op_array->
opcodes[i], &ssa->
ops[i], ssa, 0);
586 add_operands_to_worklists(&ctx, &op_array->
opcodes[op_data], &ssa->
ops[op_data], ssa, 0);
590 && !may_throw_dce_exception(&op_array->
opcodes[i]))
591 || (has_varargs && may_break_varargs(op_array, ssa, &ssa->
ops[i]))) {
599 add_operands_to_worklists(&ctx, &op_array->
opcodes[i], &ssa->
ops[i], ssa, 0);
601 add_operands_to_worklists(&ctx, &op_array->
opcodes[op_data], &ssa->
ops[op_data], ssa, 0);
619 add_operands_to_worklists(&ctx, &op_array->
opcodes[i], &ssa->
ops[i], ssa, 1);
620 if (i < op_array->
last
625 add_operands_to_worklists(&ctx, &op_array->
opcodes[i+1], &ssa->
ops[i+1], ssa, 1);
637 removed_ops += dce_instr(&ctx, &op_array->
opcodes[i], &ssa->
ops[i]);
649 add_to_phi_worklist_no_val(&ctx, source);
660 try_remove_trivial_phi(&ctx, phi);
664 zend_arena_release(&optimizer_ctx->
arena, checkpoint);
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects)
memset(ptr, 0, type->size)
zend_basic_block * blocks
HashTable * static_variables
unsigned int escape_state
zend_ssa_phi * definition_phi
zend_ssa_phi * phi_use_chain
zend_ssa_var_info * var_info
unsigned reorder_dtor_effects
zend_bitset instr_worklist
zend_bitset phi_worklist_no_val
uint32_t instr_worklist_len
uint32_t phi_worklist_len
#define ZEND_BITSET_FOREACH_END()
#define ZEND_BITSET_FOREACH(set, len, bit)
struct _zend_basic_block zend_basic_block
#define ZEND_BB_REACHABLE
struct _zend_op_array zend_op_array
#define ZEND_BIND_IMPLICIT
#define ZEND_BIND_EXPLICIT
ZEND_API bool zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, const zend_ssa *ssa)
struct _zend_optimizer_ctx zend_optimizer_ctx
#define zend_always_inline
void zend_ssa_remove_uses_of_var(zend_ssa *ssa, int var_num)
void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op)
void zend_ssa_remove_phi(zend_ssa *ssa, zend_ssa_phi *phi)
void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types)
#define FOREACH_PHI_END()
struct _zend_ssa zend_ssa
struct _zend_ssa_var zend_ssa_var
struct _zend_ssa_phi zend_ssa_phi
#define FOREACH_PHI_SOURCE(phi, source)
struct _zend_ssa_op zend_ssa_op
#define FOREACH_PHI_SOURCE_END()
#define ZEND_IS_IDENTICAL
#define ZEND_ASSIGN_DIM_OP
#define ZEND_ASSIGN_STATIC_PROP_REF
#define ZEND_EXT_FCALL_END
#define ZEND_ISSET_ISEMPTY_CV
#define ZEND_FUNC_NUM_ARGS
#define ZEND_INCLUDE_OR_EVAL
#define ZEND_FRAMELESS_ICALL_0
#define ZEND_ASSERT_CHECK
#define ZEND_ASSIGN_STATIC_PROP_OP
#define ZEND_EXT_FCALL_BEGIN
#define ZEND_FRAMELESS_ICALL_1
#define ZEND_IS_NOT_EQUAL
#define ZEND_IS_NOT_IDENTICAL
#define ZEND_POST_DEC_OBJ
#define ZEND_FRAMELESS_ICALL_3
#define ZEND_ADD_ARRAY_ELEMENT
#define ZEND_ASSIGN_STATIC_PROP
#define ZEND_IS_SMALLER_OR_EQUAL
#define ZEND_FRAMELESS_ICALL_2
#define ZEND_ISSET_ISEMPTY_DIM_OBJ
#define ZEND_ISSET_ISEMPTY_VAR
#define ZEND_BIND_INIT_STATIC_OR_JMP
#define ZEND_BEGIN_SILENCE
#define ZEND_FUNC_GET_ARGS
#define ZEND_ARRAY_KEY_EXISTS
#define ZEND_JMP_FRAMELESS
#define ZEND_ASSIGN_OBJ_OP
#define ZEND_ASSIGN_OBJ_REF
#define ZEND_FETCH_DIM_IS
#define ZEND_VERIFY_NEVER_TYPE
#define ZEND_POST_INC_OBJ
#define ZEND_DO_FCALL_BY_NAME
#define ZEND_ISSET_ISEMPTY_THIS