From 372398505840210f0cb3c33d40e44b3274bcd0b8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Mar 2020 13:02:16 +0100 Subject: [PATCH] Merge EX variants of INFO macros --- ext/opcache/Optimizer/dfa_pass.c | 2 + ext/opcache/Optimizer/escape_analysis.c | 20 ++--- ext/opcache/Optimizer/zend_func_info.c | 11 ++- ext/opcache/Optimizer/zend_inference.c | 68 ++++++++-------- ext/opcache/Optimizer/zend_inference.h | 43 +++------- ext/opcache/Optimizer/zend_optimizer.c | 1 + ext/opcache/jit/zend_jit_trace.c | 102 ++++++++++++------------ ext/opcache/jit/zend_jit_x86.dasc | 14 ++-- 8 files changed, 124 insertions(+), 137 deletions(-) diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index e27826b632..3474649e3e 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -989,6 +989,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx int v; int remove_nops = 0; zend_op *opline; + zend_ssa_op *ssa_op; zval tmp; #if ZEND_DEBUG_DFA @@ -1044,6 +1045,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx } opline = op_array->opcodes + op_1; + ssa_op = &ssa->ops[op_1]; /* Convert LONG constants to DOUBLE */ if (ssa->var_info[v].use_as_double) { diff --git a/ext/opcache/Optimizer/escape_analysis.c b/ext/opcache/Optimizer/escape_analysis.c index 3b8733eaae..b27e12ec4d 100644 --- a/ext/opcache/Optimizer/escape_analysis.c +++ b/ext/opcache/Optimizer/escape_analysis.c @@ -166,10 +166,10 @@ static inline zend_class_entry *get_class_entry(const zend_script *script, zend_ static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */ { - zend_ssa_op *op = ssa->ops + def; + zend_ssa_op *ssa_op = ssa->ops + def; zend_op *opline = op_array->opcodes + def; - if (op->result_def == var) { + if (ssa_op->result_def == var) { switch (opline->opcode) { case ZEND_INIT_ARRAY: return 1; @@ -204,7 +204,7 @@ static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, in } break; } - } else if (op->op1_def == var) { + } else if (ssa_op->op1_def == var) { switch (opline->opcode) { case ZEND_ASSIGN: if (opline->op2_type == IS_CONST @@ -275,10 +275,10 @@ static int is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int var) /* {{{ */ { - zend_ssa_op *op = ssa->ops + use; + zend_ssa_op *ssa_op = ssa->ops + use; zend_op *opline = op_array->opcodes + use; - if (op->op1_use == var) { + if (ssa_op->op1_use == var) { switch (opline->opcode) { case ZEND_ASSIGN: /* no_val */ @@ -333,10 +333,10 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va return 1; } opline--; - op--; + ssa_op--; if (opline->op1_type != IS_CV || (OP1_INFO() & MAY_BE_REF) - || (op->op1_def >= 0 && ssa->vars[op->op1_def].alias)) { + || (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias)) { /* assignment into escaping structure */ return 1; } @@ -347,12 +347,12 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va } } - if (op->op2_use == var) { + if (ssa_op->op2_use == var) { switch (opline->opcode) { case ZEND_ASSIGN: if (opline->op1_type != IS_CV || (OP1_INFO() & MAY_BE_REF) - || (op->op1_def >= 0 && ssa->vars[op->op1_def].alias)) { + || (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias)) { /* assignment into escaping variable */ return 1; } @@ -368,7 +368,7 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va } } - if (op->result_use == var) { + if (ssa_op->result_use == var) { switch (opline->opcode) { case ZEND_ASSIGN: case ZEND_QM_ASSIGN: diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 477f46adf1..4fe614be39 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -55,14 +55,17 @@ typedef struct _func_info_t { static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa *ssa) { if (call_info->num_args == 2 || call_info->num_args == 3) { - - uint32_t t1 = _ssa_op1_info(call_info->caller_op_array, ssa, call_info->arg_info[0].opline); - uint32_t t2 = _ssa_op1_info(call_info->caller_op_array, ssa, call_info->arg_info[1].opline); + zend_op_array *op_array = call_info->caller_op_array; + uint32_t t1 = _ssa_op1_info(op_array, ssa, call_info->arg_info[0].opline, + &ssa->ops[call_info->arg_info[0].opline - op_array->opcodes]); + uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline, + &ssa->ops[call_info->arg_info[1].opline - op_array->opcodes]); uint32_t t3 = 0; uint32_t tmp = MAY_BE_RC1 | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG; if (call_info->num_args == 3) { - t3 = _ssa_op1_info(call_info->caller_op_array, ssa, call_info->arg_info[2].opline); + t3 = _ssa_op1_info(op_array, ssa, call_info->arg_info[2].opline, + &ssa->ops[call_info->arg_info[2].opline - op_array->opcodes]); } if ((t1 & MAY_BE_STRING) && (t2 & MAY_BE_STRING)) { tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING; diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 336a817671..8db27f86e6 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2325,8 +2325,8 @@ static zend_always_inline int _zend_update_type_info( ssa_op--; } - t1 = OP1_INFO_EX(); - t2 = OP2_INFO_EX(); + t1 = OP1_INFO(); + t2 = OP2_INFO(); /* If one of the operands cannot have any type, this means the operand derives from * unreachable code. Propagate the empty result early, so that that the following @@ -2490,18 +2490,18 @@ static zend_always_inline int _zend_update_type_info( prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op); orig = t1; t1 = zend_fetch_prop_type(script, prop_info, &ce); - t2 = OP1_DATA_INFO_EX(); + t2 = OP1_DATA_INFO(); } else if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (t1 & MAY_BE_ARRAY_OF_REF) { tmp |= MAY_BE_REF; } orig = t1; t1 = zend_array_element_type(t1, 1, 0); - t2 = OP1_DATA_INFO_EX(); + t2 = OP1_DATA_INFO(); } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) { prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline); t1 = zend_fetch_prop_type(script, prop_info, &ce); - t2 = OP1_DATA_INFO_EX(); + t2 = OP1_DATA_INFO(); } else { if (t1 & MAY_BE_REF) { tmp |= MAY_BE_REF; @@ -2519,7 +2519,7 @@ static zend_always_inline int _zend_update_type_info( if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (opline->op1_type == IS_CV) { - orig = assign_dim_result_type(orig, OP2_INFO_EX(), tmp, opline->op2_type); + orig = assign_dim_result_type(orig, OP2_INFO(), tmp, opline->op2_type); UPDATE_SSA_TYPE(orig, ssa_op->op1_def); COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def); } @@ -2693,7 +2693,7 @@ static zend_always_inline int _zend_update_type_info( break; case ZEND_ASSIGN_DIM: if (opline->op1_type == IS_CV) { - tmp = assign_dim_result_type(t1, t2, OP1_DATA_INFO_EX(), opline->op2_type); + tmp = assign_dim_result_type(t1, t2, OP1_DATA_INFO(), opline->op2_type); UPDATE_SSA_TYPE(tmp, ssa_op->op1_def); COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def); } @@ -2703,7 +2703,7 @@ static zend_always_inline int _zend_update_type_info( tmp |= MAY_BE_STRING; } if (t1 & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_STRING)) { - tmp |= (OP1_DATA_INFO_EX() & (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF)); + tmp |= (OP1_DATA_INFO() & (MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF)); if (opline->op2_type == IS_UNUSED) { /* When appending to an array and the LONG_MAX key is already used @@ -2729,7 +2729,7 @@ static zend_always_inline int _zend_update_type_info( if ((ssa_op+1)->op1_def >= 0) { opline++; ssa_op++; - tmp = OP1_INFO_EX(); + tmp = OP1_INFO(); if (tmp & (MAY_BE_ANY | MAY_BE_REF)) { if (tmp & MAY_BE_RC1) { tmp |= MAY_BE_RCN; @@ -2763,7 +2763,7 @@ static zend_always_inline int _zend_update_type_info( if ((ssa_op+1)->op1_def >= 0) { opline++; ssa_op++; - tmp = OP1_INFO_EX(); + tmp = OP1_INFO(); if (tmp & MAY_BE_RC1) { tmp |= MAY_BE_RCN; } @@ -2778,7 +2778,7 @@ static zend_always_inline int _zend_update_type_info( if ((ssa_op+1)->op1_def >= 0) { opline++; ssa_op++; - tmp = OP1_INFO_EX(); + tmp = OP1_INFO(); if (tmp & MAY_BE_RC1) { tmp |= MAY_BE_RCN; } @@ -2881,7 +2881,7 @@ static zend_always_inline int _zend_update_type_info( COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def); } - t2 = OP1_DATA_INFO_EX(); + t2 = OP1_DATA_INFO(); if ((opline+1)->op1_type == IS_VAR && (opline->extended_value & ZEND_RETURNS_FUNCTION)) { tmp = (MAY_BE_REF | MAY_BE_RCN | MAY_BE_RC1 | t2) & ~MAY_BE_UNDEF; } else { @@ -3240,7 +3240,7 @@ static zend_always_inline int _zend_update_type_info( } UPDATE_SSA_TYPE(tmp, ssa_op->op2_def); if (ssa_op->result_def >= 0) { - tmp = (ssa_op->result_use >= 0) ? RES_USE_INFO_EX() : 0; + tmp = (ssa_op->result_use >= 0) ? RES_USE_INFO() : 0; if (t1 & MAY_BE_OBJECT) { tmp |= MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; } @@ -3987,11 +3987,10 @@ void zend_func_return_info(const zend_op_array *op_array, zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1; if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) { - if (!recursive && - info->ssa.ops && - info->ssa.var_info && - info->ssa.ops[opline - op_array->opcodes].op1_use >= 0 && - info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].recursive) { + zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[opline - op_array->opcodes] : NULL; + if (!recursive && ssa_op && info->ssa.var_info && + ssa_op->op1_use >= 0 && + info->ssa.var_info[ssa_op->op1_use].recursive) { continue; } if (is_recursive_tail_call(op_array, opline)) { @@ -4012,12 +4011,11 @@ void zend_func_return_info(const zend_op_array *op_array, } tmp |= t1; - if (info->ssa.ops && - info->ssa.var_info && - info->ssa.ops[opline - op_array->opcodes].op1_use >= 0 && - info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].ce) { - arg_ce = info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].ce; - arg_is_instanceof = info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].is_instanceof; + if (ssa_op && info->ssa.var_info && + ssa_op->op1_use >= 0 && + info->ssa.var_info[ssa_op->op1_use].ce) { + arg_ce = info->ssa.var_info[ssa_op->op1_use].ce; + arg_is_instanceof = info->ssa.var_info[ssa_op->op1_use].is_instanceof; } else { arg_ce = NULL; arg_is_instanceof = 0; @@ -4101,26 +4099,24 @@ void zend_func_return_info(const zend_op_array *op_array, } else { tmp_has_range = 0; } - } else if (info->ssa.ops && - info->ssa.var_info && - info->ssa.ops[opline - op_array->opcodes].op1_use >= 0) { - if (info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].has_range) { + } else if (ssa_op && info->ssa.var_info && ssa_op->op1_use >= 0) { + if (info->ssa.var_info[ssa_op->op1_use].has_range) { if (tmp_has_range < 0) { tmp_has_range = 1; - tmp_range = info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].range; + tmp_range = info->ssa.var_info[ssa_op->op1_use].range; } else if (tmp_has_range) { /* union */ - if (info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].range.underflow) { + if (info->ssa.var_info[ssa_op->op1_use].range.underflow) { tmp_range.underflow = 1; tmp_range.min = ZEND_LONG_MIN; } else { - tmp_range.min = MIN(tmp_range.min, info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].range.min); + tmp_range.min = MIN(tmp_range.min, info->ssa.var_info[ssa_op->op1_use].range.min); } - if (info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].range.overflow) { + if (info->ssa.var_info[ssa_op->op1_use].range.overflow) { tmp_range.overflow = 1; tmp_range.max = ZEND_LONG_MAX; } else { - tmp_range.max = MAX(tmp_range.max, info->ssa.var_info[info->ssa.ops[opline - op_array->opcodes].op1_use].range.max); + tmp_range.max = MAX(tmp_range.max, info->ssa.var_info[ssa_op->op1_use].range.max); } } } else if (!widening) { @@ -4260,8 +4256,8 @@ void zend_inference_check_recursive_dependencies(zend_op_array *op_array) int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, zend_ssa *ssa) { - uint32_t t1 = OP1_INFO_EX(); - uint32_t t2 = OP2_INFO_EX(); + uint32_t t1 = OP1_INFO(); + uint32_t t2 = OP2_INFO(); if (opline->op1_type == IS_CV) { if (t1 & MAY_BE_UNDEF) { @@ -4490,7 +4486,7 @@ int zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_ return (t1 & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY)); case ZEND_ASSIGN_DIM: if ((opline+1)->op1_type == IS_CV) { - if (_ssa_op1_info_ex(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) { + if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) { return 1; } } diff --git a/ext/opcache/Optimizer/zend_inference.h b/ext/opcache/Optimizer/zend_inference.h index 8e3096ae05..da103e4bb5 100644 --- a/ext/opcache/Optimizer/zend_inference.h +++ b/ext/opcache/Optimizer/zend_inference.h @@ -200,7 +200,7 @@ static zend_always_inline uint32_t get_ssa_var_info(const zend_ssa *ssa, int ssa } #define DEFINE_SSA_OP_INFO(opN) \ - static zend_always_inline uint32_t _ssa_##opN##_info_ex(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \ + static zend_always_inline uint32_t _ssa_##opN##_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \ { \ if (opline->opN##_type == IS_CONST) { \ return _const_op_type(CRT_CONSTANT(opline->opN)); \ @@ -208,20 +208,12 @@ static zend_always_inline uint32_t get_ssa_var_info(const zend_ssa *ssa, int ssa return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \ } \ } \ - static zend_always_inline uint32_t _ssa_##opN##_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \ - { \ - return _ssa_##opN##_info_ex(op_array, ssa, opline, ssa->ops + (opline - op_array->opcodes)); \ - } #define DEFINE_SSA_OP_DEF_INFO(opN) \ - static zend_always_inline uint32_t _ssa_##opN##_def_info_ex(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \ + static zend_always_inline uint32_t _ssa_##opN##_def_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \ { \ return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_def : -1); \ } \ - static zend_always_inline uint32_t _ssa_##opN##_def_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \ - { \ - return _ssa_##opN##_def_info_ex(op_array, ssa, opline, ssa->ops + (opline - op_array->opcodes)); \ - } DEFINE_SSA_OP_INFO(op1) @@ -231,27 +223,16 @@ DEFINE_SSA_OP_DEF_INFO(op1) DEFINE_SSA_OP_DEF_INFO(op2) DEFINE_SSA_OP_DEF_INFO(result) -#define OP1_INFO() (_ssa_op1_info(op_array, ssa, opline)) -#define OP2_INFO() (_ssa_op2_info(op_array, ssa, opline)) -#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1))) -#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1))) -#define RES_USE_INFO() (_ssa_result_info(op_array, ssa, opline)) -#define OP1_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, opline)) -#define OP2_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, opline)) -#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1))) -#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1))) -#define RES_INFO() (_ssa_result_def_info(op_array, ssa, opline)) - -#define OP1_INFO_EX() (_ssa_op1_info_ex(op_array, ssa, opline, ssa_op)) -#define OP2_INFO_EX() (_ssa_op2_info_ex(op_array, ssa, opline, ssa_op)) -#define OP1_DATA_INFO_EX() (_ssa_op1_info_ex(op_array, ssa, (opline+1), (ssa_op+1))) -#define OP2_DATA_INFO_EX() (_ssa_op2_info_ex(op_array, ssa, (opline+1), (ssa_op+1))) -#define RES_USE_INFO_EX() (_ssa_result_info_ex(op_array, ssa, opline, ssa_op)) -#define OP1_DEF_INFO_EX() (_ssa_op1_def_info_ex(op_array, ssa, opline, ssa_op)) -#define OP2_DEF_INFO_EX() (_ssa_op2_def_info_ex(op_array, ssa, opline, ssa_op)) -#define OP1_DATA_DEF_INFO_EX() (_ssa_op1_def_info_ex(op_array, ssa, (opline+1), (ssa_op+1))) -#define OP2_DATA_DEF_INFO_EX() (_ssa_op2_def_info_ex(op_array, ssa, (opline+1), (ssa_op+1))) -#define RES_INFO_EX() (_ssa_result_def_info_ex(op_array, ssa, opline, ssa_op)) +#define OP1_INFO() (_ssa_op1_info(op_array, ssa, opline, ssa_op)) +#define OP2_INFO() (_ssa_op2_info(op_array, ssa, opline, ssa_op)) +#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), (ssa_op+1))) +#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), (ssa_op+1))) +#define RES_USE_INFO() (_ssa_result_info(op_array, ssa, opline, ssa_op)) +#define OP1_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, opline, ssa_op)) +#define OP2_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, opline, ssa_op)) +#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), (ssa_op+1))) +#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), (ssa_op+1))) +#define RES_INFO() (_ssa_result_def_info(op_array, ssa, opline, ssa_op)) static zend_always_inline zend_bool zend_add_will_overflow(zend_long a, zend_long b) { return (b > 0 && a > ZEND_LONG_MAX - b) diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 05221b1587..678d435a9a 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -1214,6 +1214,7 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; uint32_t op1_info = opline->op1_type == IS_UNUSED ? 0 : (OP1_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)); uint32_t op2_info = opline->op1_type == IS_UNUSED ? 0 : (OP2_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)); uint32_t res_info = diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 54f8d3e5b3..1e29abf954 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1820,22 +1820,22 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (opline->op1_type != IS_CV) { break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); if (!(op1_info & MAY_BE_LONG)) { break; } if (opline->result_type != IS_UNUSED) { - res_use_info = RES_USE_INFO_EX(); + res_use_info = RES_USE_INFO(); USE_RES_TRACE_TYPE(); - res_info = RES_INFO_EX(); + res_info = RES_INFO(); res_addr = RES_REG_ADDR(); } else { res_use_info = -1; res_info = -1; res_addr = 0; } - op1_def_info = OP1_DEF_INFO_EX(); + op1_def_info = OP1_DEF_INFO(); if (!zend_jit_inc_dec(&dasm_state, opline, op_array, op1_info, OP1_REG_ADDR(), op1_def_info, OP1_DEF_REG_ADDR(), @@ -1857,9 +1857,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_SL: case ZEND_SR: case ZEND_MOD: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { break; @@ -1893,11 +1893,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par res_addr = 0; /* set inside backend */ } else { send_result = 0; - res_use_info = RES_USE_INFO_EX(); + res_use_info = RES_USE_INFO(); USE_RES_TRACE_TYPE(); res_addr = RES_REG_ADDR(); } - res_info = RES_INFO_EX(); + res_info = RES_INFO(); if (!zend_jit_long_math(&dasm_state, opline, op_array, op1_info, OP1_RANGE_EX(), OP1_REG_ADDR(), op2_info, OP2_RANGE_EX(), OP2_REG_ADDR(), @@ -1911,9 +1911,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_SUB: case ZEND_MUL: // case ZEND_DIV: // TODO: check for division by zero ??? - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { break; @@ -1948,11 +1948,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par res_addr = 0; /* set inside backend */ } else { send_result = 0; - res_use_info = RES_USE_INFO_EX(); + res_use_info = RES_USE_INFO(); USE_RES_TRACE_TYPE(); res_addr = RES_REG_ADDR(); } - res_info = RES_INFO_EX(); + res_info = RES_INFO(); if (!zend_jit_math(&dasm_state, opline, op_array, op1_info, OP1_REG_ADDR(), op2_info, OP2_REG_ADDR(), @@ -1968,9 +1968,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_CONCAT: case ZEND_FAST_CONCAT: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { break; @@ -2004,7 +2004,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { send_result = 0; } - res_info = RES_INFO_EX(); + res_info = RES_INFO(); if (!zend_jit_concat(&dasm_state, opline, op_array, op1_info, op2_info, res_info, send_result, zend_may_throw(opline, ssa_op, op_array, ssa))) { @@ -2020,9 +2020,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) { break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { break; @@ -2051,7 +2051,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par break; } } - op1_def_info = OP1_DEF_INFO_EX(); + op1_def_info = OP1_DEF_INFO(); if (!zend_jit_assign_op(&dasm_state, opline, op_array, op1_info, op1_def_info, OP1_RANGE_EX(), op2_info, OP2_RANGE_EX(), @@ -2075,13 +2075,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) { break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); - op1_data_info = OP1_DATA_INFO_EX(); + op1_data_info = OP1_DATA_INFO(); CHECK_OP1_DATA_TRACE_TYPE(); - op1_def_info = OP1_DEF_INFO_EX(); + op1_def_info = OP1_DEF_INFO(); if (!zend_jit_assign_dim_op(&dasm_state, opline, op_array, op1_info, op1_def_info, op2_info, op1_data_info, OP1_DATA_RANGE(), @@ -2093,11 +2093,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (opline->op1_type != IS_CV) { break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); - op1_data_info = OP1_DATA_INFO_EX(); + op1_data_info = OP1_DATA_INFO(); CHECK_OP1_DATA_TRACE_TYPE(); if (!zend_jit_assign_dim(&dasm_state, opline, op_array, op1_info, op2_info, op1_data_info, @@ -2114,7 +2114,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par res_info = -1; } else { res_addr = RES_REG_ADDR(); - res_info = RES_INFO_EX(); + res_info = RES_INFO(); } op2_addr = OP2_REG_ADDR(); if (ra @@ -2124,10 +2124,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { op2_def_addr = op2_addr; } - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); - op1_info = OP1_INFO_EX(); - op1_def_info = OP1_DEF_INFO_EX(); + op1_info = OP1_INFO(); + op1_def_info = OP1_DEF_INFO(); USE_OP1_TRACE_TYPE(); if (!zend_jit_assign(&dasm_state, opline, op_array, op1_info, OP1_REG_ADDR(), @@ -2147,9 +2147,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { op1_def_addr = op1_addr; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE();//???USE_OP1_TRACE_TYPE(); - res_info = RES_INFO_EX(); + res_info = RES_INFO(); if (!zend_jit_qm_assign(&dasm_state, opline, op_array, op1_info, op1_addr, op1_def_addr, res_info, RES_REG_ADDR())) { @@ -2168,7 +2168,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par && opline->op2.num > MAX_ARG_FLAG_NUM) { break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); //???USE_OP1_TRACE_TYPE(); if (!zend_jit_send_val(&dasm_state, opline, op_array, op1_info, OP1_REG_ADDR())) { @@ -2184,7 +2184,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } goto done; case ZEND_SEND_REF: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); USE_OP1_TRACE_TYPE(); if (!zend_jit_send_ref(&dasm_state, opline, op_array, op1_info, 0)) { @@ -2208,7 +2208,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { op1_def_addr = op1_addr; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); //???USE_OP1_TRACE_TYPE(); if (!zend_jit_send_var(&dasm_state, opline, op_array, op1_info, op1_addr, op1_def_addr)) { @@ -2239,9 +2239,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: case ZEND_CASE: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { zend_bool exit_if_true = 0; @@ -2268,9 +2268,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { zend_bool exit_if_true = 0; @@ -2322,7 +2322,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par // TODO: support for is_resource() ??? break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); USE_OP1_TRACE_TYPE(); if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { zend_bool exit_if_true = 0; @@ -2343,7 +2343,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } goto done; case ZEND_RETURN: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); if (opline->op1_type == IS_CONST) { res_type = Z_TYPE_P(RT_CONSTANT(opline, opline->op1)); @@ -2387,7 +2387,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_BOOL: case ZEND_BOOL_NOT: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); if (!zend_jit_bool_jmpznz(&dasm_state, opline, op_array, op1_info, OP1_REG_ADDR(), RES_REG_ADDR(), @@ -2414,7 +2414,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { res_addr = RES_REG_ADDR(); } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); if ((p+1)->op == ZEND_JIT_TRACE_VM || (p+1)->op == ZEND_JIT_TRACE_END) { const zend_op *exit_opline = NULL; @@ -2463,11 +2463,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_FETCH_DIM_R: case ZEND_FETCH_DIM_IS: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); - res_info = RES_INFO_EX(); + res_info = RES_INFO(); if (!zend_jit_fetch_dim_read(&dasm_state, opline, op_array, op1_info, op2_info, res_info, ( @@ -2489,9 +2489,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par // TODO: support for empty() ??? break; } - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); - op2_info = OP2_INFO_EX(); + op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { zend_bool exit_if_true = 0; @@ -2527,7 +2527,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; ce = op_array->scope; } else { - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); if (ssa->var_info && ssa->ops) { if (ssa_op->op1_use >= 0) { zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; @@ -2553,7 +2553,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (!ssa->ops || !ssa->var_info) { op1_info = MAY_BE_ANY|MAY_BE_REF; } else { - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); } if (!zend_jit_bind_global(&dasm_state, opline, op_array, op1_info)) { goto jit_failure; @@ -2594,7 +2594,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_FREE: case ZEND_FE_FREE: - op1_info = OP1_INFO_EX(); + op1_info = OP1_INFO(); USE_OP1_TRACE_TYPE(); if (!zend_jit_free(&dasm_state, opline, op_array, op1_info, zend_may_throw(opline, ssa_op, op_array, ssa))) { @@ -2726,7 +2726,7 @@ done: && has_concrete_type(ssa->var_info[ssa_op->op1_def].type)) { type = concrete_type(ssa->var_info[ssa_op->op1_def].type); } else if (opline->opcode == ZEND_ASSIGN) { - if (!(OP1_INFO_EX() & MAY_BE_REF) + if (!(OP1_INFO() & MAY_BE_REF) || STACK_VAR_TYPE(opline->op1.var) != IS_UNKNOWN) { if (opline->op2_type != IS_CONST) { /* copy */ diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 5285a6a46d..f4d0330363 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -7802,9 +7802,10 @@ static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ss if (ZEND_TYPE_IS_SET(arg_info->type)) { if (ZEND_TYPE_IS_ONLY_MASK(arg_info->type)) { + zend_op *opline = call_info->arg_info[num_args].opline; + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type); - uint32_t info = _ssa_op1_info(op_array, ssa, call_info->arg_info[num_args].opline); - if ((info & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) { + if ((OP1_INFO() & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) { break; } } else { @@ -10505,6 +10506,7 @@ static int zend_jit_switch(dasm_State **Dst, const zend_op *opline, const zend_o ZEND_ASSERT(0); } } else { + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; uint32_t op1_info = OP1_INFO(); zend_jit_addr op1_addr = OP1_ADDR(); int b = ssa->cfg.map[ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value) - op_array->opcodes]; @@ -10739,7 +10741,7 @@ static zend_bool zend_jit_may_reuse_reg(const zend_op_array *op_array, zend_ssa return 0; } -static zend_bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, int var) +static zend_bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, const zend_ssa_op *ssa_op, int var) { uint32_t op1_info, op2_info; @@ -10837,7 +10839,8 @@ static zend_bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa } if (ssa->vars[var].definition >= 0) { - if (!zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + ssa->vars[var].definition, var)) { + uint32_t def = ssa->vars[var].definition; + if (!zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + def, ssa->ops + def, var)) { return 0; } } @@ -10847,7 +10850,7 @@ static zend_bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa do { if (!zend_ssa_is_no_val_use(op_array->opcodes + use, ssa->ops + use, var) && - !zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + use, var)) { + !zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + use, ssa->ops + use, var)) { return 0; } use = zend_ssa_next_use(ssa->ops, var, use); @@ -10873,6 +10876,7 @@ static zend_bool zend_needs_extra_reg_for_const(const zend_op_array *op_array, c static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, zend_ssa *ssa, uint32_t line, int current_var) { const zend_op *opline = op_array->opcodes + line; + const zend_ssa_op *ssa_op = ssa->ops + line; uint32_t op1_info, op2_info, res_info; zend_regset regset = ZEND_REGSET_SCRATCH; -- 2.49.0