diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2019-07-05 12:16:30 +0300 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2019-07-05 12:16:30 +0300 |
| commit | 1b5b8175aff0fba41ce94d75d1ddf0f7be630b9c (patch) | |
| tree | 7fef7cefe333517cf9640eee34b198e865a4f9e5 /ext | |
| parent | 215e9d069c3dae40d94894d1a938d771cecc2549 (diff) | |
| parent | 48ca5a1e176c5301fedd1bc4f661969d6f9a49eb (diff) | |
| download | php-git-1b5b8175aff0fba41ce94d75d1ddf0f7be630b9c.tar.gz | |
Merge branch 'PHP-7.4'
* PHP-7.4:
Replace ZEND_ASSIGN_ADD (and others) by ZEND_ASSIGN_OP, ZEND_ASSIGN_DIM_OP, ZEND_ASSGIN_OBJ_OP and ZEND_ASSIGN_STATIC_PROP_OP
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 16 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/compact_literals.c | 112 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/dce.c | 32 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/dfa_pass.c | 30 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/escape_analysis.c | 38 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/pass2.c | 55 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/pass3.c | 43 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/sccp.c | 86 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_dfg.c | 16 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_dump.c | 10 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 211 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 79 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_optimizer_internal.h | 1 | ||||
| -rw-r--r-- | ext/opcache/Optimizer/zend_ssa.c | 16 | ||||
| -rw-r--r-- | ext/opcache/jit/zend_jit.c | 184 | ||||
| -rw-r--r-- | ext/opcache/jit/zend_jit_helpers.c | 44 | ||||
| -rw-r--r-- | ext/opcache/jit/zend_jit_x86.dasc | 248 |
17 files changed, 416 insertions, 805 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 505f004de3..b3014257ef 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1712,18 +1712,10 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use if (opline->result_type == IS_VAR) { if (!zend_bitset_in(usage, VAR_NUM(opline->result.var))) { switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_PRE_INC: case ZEND_PRE_DEC: case ZEND_ASSIGN: diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 50ccd7d256..b70f0cacd1 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -197,7 +197,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_PRE_DEC_STATIC_PROP: case ZEND_POST_INC_STATIC_PROP: case ZEND_POST_DEC_STATIC_PROP: -literals_handle_static_prop: + case ZEND_ASSIGN_STATIC_PROP_OP: if (opline->op2_type == IS_CONST) { LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2); } @@ -230,39 +230,11 @@ literals_handle_static_prop: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: case ZEND_ISSET_ISEMPTY_PROP_OBJ: + case ZEND_ASSIGN_OBJ_OP: if (opline->op2_type == IS_CONST) { LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1); } break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { - goto literals_handle_static_prop; - } - if (opline->op2_type == IS_CONST) { - if (opline->extended_value == ZEND_ASSIGN_OBJ) { - LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1); - } else if (opline->extended_value == ZEND_ASSIGN_DIM) { - if (Z_EXTRA(op_array->literals[opline->op2.constant]) == ZEND_EXTRA_VALUE) { - LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2); - } else { - LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1); - } - } else { - LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1); - } - } - break; case ZEND_BIND_GLOBAL: LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 1); break; @@ -290,6 +262,7 @@ literals_handle_static_prop: case ZEND_FETCH_DIM_UNSET: case ZEND_FETCH_LIST_R: case ZEND_FETCH_LIST_W: + case ZEND_ASSIGN_DIM_OP: if (opline->op1_type == IS_CONST) { LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1); } @@ -548,54 +521,41 @@ literals_handle_static_prop: cache_size += sizeof(void *); } break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { - if (opline->op1_type == IS_CONST) { - // op1 static property - if (opline->op2_type == IS_CONST) { - (opline+1)->extended_value = add_static_slot(&hash, op_array, - opline->op2.constant, - opline->op1.constant, - LITERAL_STATIC_PROPERTY, - &cache_size); - } else { - (opline+1)->extended_value = cache_size; - cache_size += 3 * sizeof(void *); - } - } else if (opline->op2_type == IS_CONST) { - // op2 class - if (class_slot[opline->op2.constant] >= 0) { - (opline+1)->extended_value = class_slot[opline->op2.constant]; - } else { - (opline+1)->extended_value = cache_size; - class_slot[opline->op2.constant] = cache_size; - cache_size += sizeof(void *); - } + case ZEND_ASSIGN_STATIC_PROP_OP: + if (opline->op1_type == IS_CONST) { + // op1 static property + if (opline->op2_type == IS_CONST) { + (opline+1)->extended_value = add_static_slot(&hash, op_array, + opline->op2.constant, + opline->op1.constant, + LITERAL_STATIC_PROPERTY, + &cache_size); + } else { + (opline+1)->extended_value = cache_size; + cache_size += 3 * sizeof(void *); + } + } else if (opline->op2_type == IS_CONST) { + // op2 class + if (class_slot[opline->op2.constant] >= 0) { + (opline+1)->extended_value = class_slot[opline->op2.constant]; + } else { + (opline+1)->extended_value = cache_size; + class_slot[opline->op2.constant] = cache_size; + cache_size += sizeof(void *); } } - if (opline->extended_value == ZEND_ASSIGN_OBJ) { - if (opline->op2_type == IS_CONST) { - // op2 property - if (opline->op1_type == IS_UNUSED && - property_slot[opline->op2.constant] >= 0) { - (opline+1)->extended_value = property_slot[opline->op2.constant]; - } else { - (opline+1)->extended_value = cache_size; - cache_size += 3 * sizeof(void *); - if (opline->op1_type == IS_UNUSED) { - property_slot[opline->op2.constant] = (opline+1)->extended_value; - } + break; + case ZEND_ASSIGN_OBJ_OP: + if (opline->op2_type == IS_CONST) { + // op2 property + if (opline->op1_type == IS_UNUSED && + property_slot[opline->op2.constant] >= 0) { + (opline+1)->extended_value = property_slot[opline->op2.constant]; + } else { + (opline+1)->extended_value = cache_size; + cache_size += 3 * sizeof(void *); + if (opline->op1_type == IS_UNUSED) { + property_slot[opline->op2.constant] = (opline+1)->extended_value; } } } diff --git a/ext/opcache/Optimizer/dce.c b/ext/opcache/Optimizer/dce.c index c9ef7111ca..8370bdc779 100644 --- a/ext/opcache/Optimizer/dce.c +++ b/ext/opcache/Optimizer/dce.c @@ -201,21 +201,9 @@ static inline zend_bool may_have_side_effects( case ZEND_PRE_DEC: case ZEND_POST_DEC: return is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def); - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: return is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def) - || (opline->extended_value - && ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE); + || ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE; case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_OBJ: if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def) @@ -349,18 +337,10 @@ static zend_bool try_remove_var_def(context *ctx, int free_var, int use_chain, z case ZEND_ASSIGN_OBJ_REF: case ZEND_ASSIGN_STATIC_PROP: case ZEND_ASSIGN_STATIC_PROP_REF: - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_PRE_INC: case ZEND_PRE_DEC: case ZEND_PRE_INC_OBJ: diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index c9528918e3..b0d58f9566 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -1180,8 +1180,8 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx } } - } else if (opline->opcode == ZEND_ASSIGN_ADD - && opline->extended_value == 0 + } else if (opline->opcode == ZEND_ASSIGN_OP + && opline->extended_value == ZEND_ADD && ssa->ops[op_1].op1_def == v && opline->op2_type == IS_CONST && Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG @@ -1192,10 +1192,11 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx // op_1: ASSIGN_ADD #?.CV [undef,null,int,foat] ->#v.CV, int(1) => PRE_INC #?.CV ->#v.CV opline->opcode = ZEND_PRE_INC; + opline->extended_value = 0; SET_UNUSED(opline->op2); - } else if (opline->opcode == ZEND_ASSIGN_SUB - && opline->extended_value == 0 + } else if (opline->opcode == ZEND_ASSIGN_OP + && opline->extended_value == ZEND_SUB && ssa->ops[op_1].op1_def == v && opline->op2_type == IS_CONST && Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG @@ -1206,6 +1207,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx // op_1: ASSIGN_SUB #?.CV [undef,null,int,foat] -> #v.CV, int(1) => PRE_DEC #?.CV ->#v.CV opline->opcode = ZEND_PRE_DEC; + opline->extended_value = 0; SET_UNUSED(opline->op2); } else if (opline->opcode == ZEND_VERIFY_RETURN_TYPE @@ -1240,26 +1242,18 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx && !RETURN_VALUE_USED(opline) && ssa->ops[op_1].op1_use >= 0 && !(ssa->var_info[ssa->ops[op_1].op1_use].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) - && (opline->opcode == ZEND_ASSIGN_ADD - || opline->opcode == ZEND_ASSIGN_SUB - || opline->opcode == ZEND_ASSIGN_MUL - || opline->opcode == ZEND_ASSIGN_DIV - || opline->opcode == ZEND_ASSIGN_MOD - || opline->opcode == ZEND_ASSIGN_SL - || opline->opcode == ZEND_ASSIGN_SR - || opline->opcode == ZEND_ASSIGN_BW_OR - || opline->opcode == ZEND_ASSIGN_BW_AND - || opline->opcode == ZEND_ASSIGN_BW_XOR) - && opline->extended_value == 0) { - -// op_1: ASSIGN_ADD #orig_var.CV [undef,null,bool,int,double] -> #v.CV, ? => #v.CV = ADD #orig_var.CV, ? + && opline->opcode == ZEND_ASSIGN_OP + && opline->extended_value != ZEND_CONCAT) { + +// op_1: ASSIGN_OP #orig_var.CV [undef,null,bool,int,double] -> #v.CV, ? => #v.CV = ADD #orig_var.CV, ? /* Reconstruct SSA */ ssa->ops[op_1].result_def = ssa->ops[op_1].op1_def; ssa->ops[op_1].op1_def = -1; /* Update opcode */ - opline->opcode -= (ZEND_ASSIGN_ADD - ZEND_ADD); + opline->opcode = opline->extended_value; + opline->extended_value = 0; opline->result_type = opline->op1_type; opline->result.var = opline->op1.var; diff --git a/ext/opcache/Optimizer/escape_analysis.c b/ext/opcache/Optimizer/escape_analysis.c index 948feeef84..c561bec9dc 100644 --- a/ext/opcache/Optimizer/escape_analysis.c +++ b/ext/opcache/Optimizer/escape_analysis.c @@ -257,24 +257,11 @@ static int is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var } else if (op->op1_def == var) { switch (opline->opcode) { case ZEND_ASSIGN: - return 1; case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_OBJ: case ZEND_ASSIGN_OBJ_REF: - return 1; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - return (opline->extended_value != 0); + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: case ZEND_PRE_INC_OBJ: case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: @@ -312,22 +299,11 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va case ZEND_FETCH_DIM_IS: case ZEND_FETCH_OBJ_IS: break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - if (!opline->extended_value) { - return 1; - } - /* break missing intentionally */ + case ZEND_ASSIGN_OP: + return 1; + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_OBJ: case ZEND_ASSIGN_OBJ_REF: diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c index 3613fd57de..01e118e7e3 100644 --- a/ext/opcache/Optimizer/pass2.c +++ b/ext/opcache/Optimizer/pass2.c @@ -53,16 +53,6 @@ void zend_optimizer_pass2(zend_op_array *op_array) } } } - /* break missing *intentionally* - the assign_op's may only optimize op2 */ - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - if (opline->extended_value != 0) { - /* object tristate op - don't attempt to optimize it! */ - break; - } if (opline->op2_type == IS_CONST) { if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { /* don't optimise if it should produce a runtime numeric string error */ @@ -85,14 +75,6 @@ void zend_optimizer_pass2(zend_op_array *op_array) } } } - /* break missing *intentionally - the assign_op's may only optimize op2 */ - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - if (opline->extended_value != 0) { - /* object tristate op - don't attempt to optimize it! */ - break; - } if (opline->op2_type == IS_CONST) { if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) { /* don't optimise if it should produce a runtime numeric string error */ @@ -111,12 +93,6 @@ void zend_optimizer_pass2(zend_op_array *op_array) convert_to_string(&ZEND_OP1_LITERAL(opline)); } } - /* break missing *intentionally - the assign_op's may only optimize op2 */ - case ZEND_ASSIGN_CONCAT: - if (opline->extended_value != 0) { - /* object tristate op - don't attempt to optimize it! */ - break; - } if (opline->op2_type == IS_CONST) { if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) { convert_to_string(&ZEND_OP2_LITERAL(opline)); @@ -124,6 +100,37 @@ void zend_optimizer_pass2(zend_op_array *op_array) } break; + case ZEND_ASSIGN_OP: + if (opline->op2_type == IS_CONST) { + if (opline->extended_value == ZEND_ADD + || opline->extended_value == ZEND_SUB + || opline->extended_value == ZEND_MUL + || opline->extended_value == ZEND_DIV + || opline->extended_value == ZEND_POW) { + if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { + /* don't optimise if it should produce a runtime numeric string error */ + if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) { + convert_scalar_to_number(&ZEND_OP2_LITERAL(opline)); + } + } + } else if (opline->extended_value == ZEND_MOD + || opline->extended_value == ZEND_SL + || opline->extended_value == ZEND_SR) { + if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) { + /* don't optimise if it should produce a runtime numeric string error */ + if (!(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING + && !is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0))) { + convert_to_long(&ZEND_OP2_LITERAL(opline)); + } + } + } else if (opline->extended_value == ZEND_CONCAT) { + if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) { + convert_to_string(&ZEND_OP2_LITERAL(opline)); + } + } + } + break; + case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: /* convert Ti = JMPZ_EX(Ti, L) to JMPZ(Ti, L) */ diff --git a/ext/opcache/Optimizer/pass3.c b/ext/opcache/Optimizer/pass3.c index a700893cee..5bbb2b0854 100644 --- a/ext/opcache/Optimizer/pass3.c +++ b/ext/opcache/Optimizer/pass3.c @@ -113,47 +113,12 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx) } } - if ((opline->op1_type & (IS_VAR | IS_CV)) + if (ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opline->opcode) + && (opline->op1_type & (IS_VAR | IS_CV)) && opline->op1.var == next_opline->op1.var && opline->op1_type == next_opline->op1_type) { - switch (opline->opcode) { - case ZEND_ADD: - opline->opcode = ZEND_ASSIGN_ADD; - break; - case ZEND_SUB: - opline->opcode = ZEND_ASSIGN_SUB; - break; - case ZEND_MUL: - opline->opcode = ZEND_ASSIGN_MUL; - break; - case ZEND_DIV: - opline->opcode = ZEND_ASSIGN_DIV; - break; - case ZEND_MOD: - opline->opcode = ZEND_ASSIGN_MOD; - break; - case ZEND_POW: - opline->opcode = ZEND_ASSIGN_POW; - break; - case ZEND_CONCAT: - opline->opcode = ZEND_ASSIGN_CONCAT; - break; - case ZEND_SL: - opline->opcode = ZEND_ASSIGN_SL; - break; - case ZEND_SR: - opline->opcode = ZEND_ASSIGN_SR; - break; - case ZEND_BW_OR: - opline->opcode = ZEND_ASSIGN_BW_OR; - break; - case ZEND_BW_AND: - opline->opcode = ZEND_ASSIGN_BW_AND; - break; - case ZEND_BW_XOR: - opline->opcode = ZEND_ASSIGN_BW_XOR; - break; - } + opline->extended_value = opline->opcode; + opline->opcode = ZEND_ASSIGN_OP; COPY_NODE(opline->result, next_opline->result); MAKE_NOP(next_opline); opline++; diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 9715f3e238..f5989dffdf 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -222,18 +222,10 @@ static zend_bool can_replace_op1( case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_OBJ: case ZEND_ASSIGN_OBJ_REF: - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_FETCH_DIM_W: case ZEND_FETCH_DIM_RW: case ZEND_FETCH_DIM_UNSET: @@ -1489,32 +1481,24 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o } SET_RESULT_BOT(result); break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: if (op1) { SKIP_IF_TOP(op1); } if (op2) { SKIP_IF_TOP(op2); } - if (opline->extended_value == 0) { - if (ct_eval_binary_op(&zv, zend_compound_assign_to_binary_op(opline->opcode), op1, op2) == SUCCESS) { + if (opline->opcode == ZEND_ASSIGN_OP) { + if (ct_eval_binary_op(&zv, opline->extended_value, op1, op2) == SUCCESS) { SET_RESULT(op1, &zv); SET_RESULT(result, &zv); zval_ptr_dtor_nogc(&zv); break; } - } else if (opline->extended_value == ZEND_ASSIGN_DIM) { + } else if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if ((IS_PARTIAL_ARRAY(op1) || Z_TYPE_P(op1) == IS_ARRAY) && ssa_op->op1_def >= 0 && op2) { zval tmp; @@ -1533,7 +1517,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o break; } - if (ct_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) { + if (ct_eval_binary_op(&tmp, opline->extended_value, &tmp, data) != SUCCESS) { SET_RESULT_BOT(result); SET_RESULT_BOT(op1); zval_ptr_dtor_nogc(&tmp); @@ -1558,7 +1542,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o zval_ptr_dtor_nogc(&zv); } } - } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { + } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { if (op1 && IS_PARTIAL_OBJECT(op1) && ssa_op->op1_def >= 0 && ctx->scdf.ssa->vars[ssa_op->op1_def].escape_state == ESCAPE_STATE_NO_ESCAPE) { @@ -1578,7 +1562,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o break; } - if (ct_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) { + if (ct_eval_binary_op(&tmp, opline->extended_value, &tmp, data) != SUCCESS) { SET_RESULT_BOT(result); SET_RESULT_BOT(op1); zval_ptr_dtor_nogc(&tmp); @@ -1599,11 +1583,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o zval_ptr_dtor_nogc(&zv); } } - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { - SET_RESULT_BOT(result); - break; - } else { - ZEND_ASSERT(0 && "Invalid compound assignment kind"); } SET_RESULT_BOT(result); SET_RESULT_BOT(op1); @@ -2347,18 +2326,10 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, switch (opline->opcode) { case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_OBJ: - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: if ((ssa_op->op2_use >= 0 && !value_known(&ctx->values[ssa_op->op2_use])) || ((ssa_op+1)->op1_use >= 0 &&!value_known(&ctx->values[(ssa_op+1)->op1_use]))) { return 0; @@ -2411,22 +2382,11 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, removed_ops++; zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1); break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - if (opline->extended_value) { - removed_ops++; - zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1); - } + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + removed_ops++; + zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1); break; default: break; diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c index a1104614f2..e995b673b7 100644 --- a/ext/opcache/Optimizer/zend_dfg.c +++ b/ext/opcache/Optimizer/zend_dfg.c @@ -107,18 +107,10 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg case ZEND_SEND_VAR_NO_REF: case ZEND_SEND_VAR_NO_REF_EX: case ZEND_FE_RESET_RW: - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_PRE_INC: case ZEND_PRE_DEC: case ZEND_POST_INC: diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c index cf1c1ccbee..8dcbd33b54 100644 --- a/ext/opcache/Optimizer/zend_dump.c +++ b/ext/opcache/Optimizer/zend_dump.c @@ -443,14 +443,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) { fprintf(stderr, " %u", opline->extended_value); - } else if (ZEND_VM_EXT_DIM_OBJ == (flags & ZEND_VM_EXT_MASK)) { - if (opline->extended_value == ZEND_ASSIGN_DIM) { - fprintf(stderr, " (dim)"); - } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { - fprintf(stderr, " (obj)"); - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { - fprintf(stderr, " (static prop)"); - } + } else if (ZEND_VM_EXT_OP == (flags & ZEND_VM_EXT_MASK)) { + fprintf(stderr, " (%s)", zend_get_opcode_name(opline->extended_value) + 5); } else if (ZEND_VM_EXT_TYPE == (flags & ZEND_VM_EXT_MASK)) { switch (opline->extended_value) { case IS_NULL: diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index f3c228f214..d2982e5cf5 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -548,25 +548,6 @@ static inline zend_bool shift_left_overflows(zend_long n, zend_long s) { } } -/* Get the normal op corresponding to a compound assignment op */ -static inline zend_uchar get_compound_assign_op(zend_uchar opcode) { - switch (opcode) { - case ZEND_ASSIGN_ADD: return ZEND_ADD; - case ZEND_ASSIGN_SUB: return ZEND_SUB; - case ZEND_ASSIGN_MUL: return ZEND_MUL; - case ZEND_ASSIGN_DIV: return ZEND_DIV; - case ZEND_ASSIGN_MOD: return ZEND_MOD; - case ZEND_ASSIGN_SL: return ZEND_SL; - case ZEND_ASSIGN_SR: return ZEND_SR; - case ZEND_ASSIGN_CONCAT: return ZEND_CONCAT; - case ZEND_ASSIGN_BW_OR: return ZEND_BW_OR; - case ZEND_ASSIGN_BW_AND: return ZEND_BW_AND; - case ZEND_ASSIGN_BW_XOR: return ZEND_BW_XOR; - case ZEND_ASSIGN_POW: return ZEND_POW; - EMPTY_SWITCH_DEFAULT_CASE() - } -} - static int zend_inference_calc_binary_op_range( const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op, zend_uchar opcode, zend_ssa_range *tmp) { @@ -1381,23 +1362,20 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int } } break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value == 0) { + case ZEND_ASSIGN_OP: + if (opline->extended_value != ZEND_CONCAT + && opline->extended_value != ZEND_POW) { if (ssa->ops[line].op1_def == var || ssa->ops[line].result_def == var) { return zend_inference_calc_binary_op_range( op_array, ssa, opline, &ssa->ops[line], - get_compound_assign_op(opline->opcode), tmp); + opline->extended_value, tmp); } - } else if ((opline+1)->opcode == ZEND_OP_DATA) { + } + break; + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + if ((opline+1)->opcode == ZEND_OP_DATA) { if (ssa->ops[line+1].op1_def == var) { opline++; if (OP1_HAS_RANGE()) { @@ -1410,13 +1388,13 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int } } break; -// case ZEND_ASSIGN_CONCAT: case ZEND_OP_DATA: if ((opline-1)->opcode == ZEND_ASSIGN_DIM || (opline-1)->opcode == ZEND_ASSIGN_OBJ || - (opline-1)->opcode == ZEND_ASSIGN_ADD || - (opline-1)->opcode == ZEND_ASSIGN_SUB || - (opline-1)->opcode == ZEND_ASSIGN_MUL) { + ((opline-1)->opcode == ZEND_ASSIGN_OP && + ((opline-1)->extended_value == ZEND_ADD || + (opline-1)->extended_value == ZEND_SUB || + (opline-1)->extended_value == ZEND_MUL))) { if (ssa->ops[line].op1_def == var) { if (OP1_HAS_RANGE()) { tmp->min = OP1_MIN_RANGE(); @@ -2599,34 +2577,27 @@ static int zend_update_type_info(const zend_op_array *op_array, UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def); COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].result_def); break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_CONCAT: { + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + { zend_property_info *prop_info = NULL; orig = 0; tmp = 0; - if (opline->extended_value == ZEND_ASSIGN_OBJ) { + if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { prop_info = zend_fetch_prop_info(op_array, ssa, opline, i); orig = t1; t1 = zend_fetch_prop_type(script, prop_info, &ce); t2 = OP1_DATA_INFO(); - } else if (opline->extended_value == ZEND_ASSIGN_DIM) { + } 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(); - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } 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(); @@ -2637,7 +2608,7 @@ static int zend_update_type_info(const zend_op_array *op_array, } tmp |= binary_op_result_type( - ssa, get_compound_assign_op(opline->opcode), t1, t2, ssa_ops[i].op1_def, optimization_level); + ssa, opline->extended_value, t1, t2, ssa_ops[i].op1_def, optimization_level); if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY)) { tmp |= MAY_BE_RC1; } @@ -2645,13 +2616,13 @@ static int zend_update_type_info(const zend_op_array *op_array, tmp |= MAY_BE_RC1 | MAY_BE_RCN; } - if (opline->extended_value == ZEND_ASSIGN_DIM) { + if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (opline->op1_type == IS_CV) { orig = assign_dim_result_type(orig, OP2_INFO(), tmp, opline->op2_type); UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def); COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def); } - } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { + } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { if (opline->op1_type == IS_CV) { if (!(orig & MAY_BE_REF)) { if (orig & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { @@ -2665,14 +2636,14 @@ static int zend_update_type_info(const zend_op_array *op_array, UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def); COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def); } - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP) { /* Nothing to do */ } else { UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def); } if (ssa_ops[i].result_def >= 0) { ce = NULL; - if (opline->extended_value == ZEND_ASSIGN_DIM) { + if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (opline->op2_type == IS_UNUSED) { /* When appending to an array and the LONG_MAX key is already used * null will be returned. */ @@ -2687,7 +2658,7 @@ static int zend_update_type_info(const zend_op_array *op_array, * results in a null return value. */ tmp |= MAY_BE_NULL; } - } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { + } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { if (orig & (MAY_BE_ANY - (MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT))) { /* null and false (and empty string) are implicitly converted to object, * anything else results in a null return value. */ @@ -2698,7 +2669,7 @@ static int zend_update_type_info(const zend_op_array *op_array, if (prop_info) { tmp &= zend_fetch_prop_type(script, prop_info, NULL); } - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) { /* The return value must also satisfy the property type */ if (prop_info) { tmp &= zend_fetch_prop_type(script, prop_info, NULL); @@ -3441,18 +3412,10 @@ static int zend_update_type_info(const zend_op_array *op_array, case ZEND_FETCH_DIM_RW: case ZEND_FETCH_DIM_FUNC_ARG: case ZEND_FETCH_LIST_W: - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_DIM: tmp |= MAY_BE_ARRAY | MAY_BE_ARRAY_OF_ARRAY; break; @@ -3957,13 +3920,19 @@ static zend_bool can_convert_to_double( return 0; } } else { + zend_uchar opcode = opline->opcode; + + if (opcode == ZEND_ASSIGN_OP) { + opcode = opline->extended_value; + } + /* Avoid division by zero */ - if (opline->opcode == ZEND_DIV && zval_get_double(&orig_op2) == 0.0) { + if (opcode == ZEND_DIV && zval_get_double(&orig_op2) == 0.0) { return 0; } - get_binary_op(opline->opcode)(&orig_result, &orig_op1, &orig_op2); - get_binary_op(opline->opcode)(&dval_result, &dval_op1, &dval_op2); + get_binary_op(opcode)(&orig_result, &orig_op1, &orig_op2); + get_binary_op(opcode)(&dval_result, &dval_op1, &dval_op2); ZEND_ASSERT(Z_TYPE(dval_result) == IS_DOUBLE); if (zval_get_double(&orig_result) != Z_DVAL(dval_result)) { return 0; @@ -4571,62 +4540,48 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa return 0; } return (t1 & (MAY_BE_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT)) || (t2 & (MAY_BE_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT)); - case ZEND_ASSIGN_ADD: - if (opline->extended_value != 0) { - return 1; - } - if ((t1 & MAY_BE_ANY) == MAY_BE_ARRAY - && (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) { - return 0; - } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - if (opline->extended_value != 0) { - return 1; - } - if (!OP2_HAS_RANGE() || - (OP2_MIN_RANGE() <= 0 && OP2_MAX_RANGE() >= 0)) { - /* Division by zero */ - return 1; - } - /* break missing intentionally */ - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_POW: - if (opline->extended_value != 0) { - return 1; - } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - if (opline->extended_value != 0) { - return 1; - } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - !OP2_HAS_RANGE() || - OP2_MIN_RANGE() < 0; - case ZEND_ASSIGN_CONCAT: - if (opline->extended_value != 0) { - return 1; - } - return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)); - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value != 0) { - return 1; - } - if ((t1 & MAY_BE_ANY) == MAY_BE_STRING - && (t2 & MAY_BE_ANY) == MAY_BE_STRING) { - return 0; + case ZEND_ASSIGN_OP: + if (opline->extended_value == ZEND_ADD) { + if ((t1 & MAY_BE_ANY) == MAY_BE_ARRAY + && (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) { + return 0; + } + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_DIV || + opline->extended_value == ZEND_MOD) { + if (!OP2_HAS_RANGE() || + (OP2_MIN_RANGE() <= 0 && OP2_MAX_RANGE() >= 0)) { + /* Division by zero */ + return 1; + } + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_SUB || + opline->extended_value == ZEND_MUL || + opline->extended_value == ZEND_POW) { + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_SL || + opline->extended_value == ZEND_SR) { + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + !OP2_HAS_RANGE() || + OP2_MIN_RANGE() < 0; + } else if (opline->extended_value == ZEND_CONCAT) { + return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_BW_OR || + opline->extended_value == ZEND_BW_AND || + opline->extended_value == ZEND_BW_XOR) { + if ((t1 & MAY_BE_ANY) == MAY_BE_STRING + && (t2 & MAY_BE_ANY) == MAY_BE_STRING) { + return 0; + } + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + return 1; case ZEND_ASSIGN: if (t1 & MAY_BE_REF) { return 1; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 1ed57ce3d8..4a2ef02513 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -53,25 +53,6 @@ void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* zend_hash_add(ctx->constants, Z_STR_P(name), &val); } -zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode) -{ - switch (opcode) { - case ZEND_ASSIGN_ADD: return ZEND_ADD; - case ZEND_ASSIGN_SUB: return ZEND_SUB; - case ZEND_ASSIGN_MUL: return ZEND_MUL; - case ZEND_ASSIGN_DIV: return ZEND_DIV; - case ZEND_ASSIGN_MOD: return ZEND_MOD; - case ZEND_ASSIGN_SL: return ZEND_SL; - case ZEND_ASSIGN_SR: return ZEND_SR; - case ZEND_ASSIGN_CONCAT: return ZEND_CONCAT; - case ZEND_ASSIGN_BW_OR: return ZEND_BW_OR; - case ZEND_ASSIGN_BW_AND: return ZEND_BW_AND; - case ZEND_ASSIGN_BW_XOR: return ZEND_BW_XOR; - case ZEND_ASSIGN_POW: return ZEND_POW; - EMPTY_SWITCH_DEFAULT_CASE() - } -} - int zend_optimizer_eval_binary_op(zval *result, zend_uchar opcode, zval *op1, zval *op2) /* {{{ */ { binary_op_type binary_op = get_binary_op(opcode); @@ -320,21 +301,11 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, } zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - if (opline->extended_value != ZEND_ASSIGN_STATIC_PROP) { - break; - } + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + break; + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_STATIC_PROP: case ZEND_ASSIGN_STATIC_PROP_REF: case ZEND_FETCH_STATIC_PROP_R: @@ -440,7 +411,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_PRE_DEC_STATIC_PROP: case ZEND_POST_INC_STATIC_PROP: case ZEND_POST_DEC_STATIC_PROP: -handle_static_prop: + case ZEND_ASSIGN_STATIC_PROP_OP: REQUIRES_STRING(val); drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); @@ -509,6 +480,7 @@ handle_static_prop: case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: + case ZEND_ASSIGN_OBJ_OP: TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); opline->extended_value = alloc_cache_slots(op_array, 3); @@ -518,42 +490,7 @@ handle_static_prop: opline->op2.constant = zend_optimizer_add_literal(op_array, val); opline->extended_value = alloc_cache_slots(op_array, 3) | (opline->extended_value & ZEND_ISEMPTY); break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value == ZEND_ASSIGN_OBJ) { - TO_STRING_NOWARN(val); - opline->op2.constant = zend_optimizer_add_literal(op_array, val); - (opline+1)->extended_value = alloc_cache_slots(op_array, 3); - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { - goto handle_static_prop; - } else if (opline->extended_value == ZEND_ASSIGN_DIM) { - if (Z_TYPE_P(val) == IS_STRING) { - zend_ulong index; - - if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) { - ZVAL_LONG(&tmp, index); - opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp); - zend_string_hash_val(Z_STR_P(val)); - zend_optimizer_add_literal(op_array, val); - Z_EXTRA(op_array->literals[opline->op2.constant]) = ZEND_EXTRA_VALUE; - break; - } - } - opline->op2.constant = zend_optimizer_add_literal(op_array, val); - } else { - opline->op2.constant = zend_optimizer_add_literal(op_array, val); - } - break; + case ZEND_ASSIGN_DIM_OP: case ZEND_ISSET_ISEMPTY_DIM_OBJ: case ZEND_ASSIGN_DIM: case ZEND_UNSET_DIM: diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h index 9997506bf0..9ab18f6398 100644 --- a/ext/opcache/Optimizer/zend_optimizer_internal.h +++ b/ext/opcache/Optimizer/zend_optimizer_internal.h @@ -110,7 +110,6 @@ zend_function *zend_optimizer_get_called_func( uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args); void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline); void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist); -zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode); int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map); int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reorder_dtor_effects); int zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa); diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index dca4781382..7520b719f1 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -716,18 +716,10 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, //NEW_SSA_VAR(opline->op1.var) } break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_PRE_INC: case ZEND_PRE_DEC: case ZEND_POST_INC: diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index f4fbcb28d0..ca0fb04a9c 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -123,12 +123,7 @@ static zend_bool zend_is_commutative(zend_uchar opcode) opcode == ZEND_MUL || opcode == ZEND_BW_OR || opcode == ZEND_BW_AND || - opcode == ZEND_BW_XOR || - opcode == ZEND_ASSIGN_ADD || - opcode == ZEND_ASSIGN_MUL|| - opcode == ZEND_ASSIGN_BW_OR || - opcode == ZEND_ASSIGN_BW_AND || - opcode == ZEND_ASSIGN_BW_XOR; + opcode == ZEND_BW_XOR; } static zend_bool zend_long_is_power_of_two(zend_long x) @@ -496,86 +491,79 @@ static int zend_may_overflow(const zend_op *opline, zend_op_array *op_array, zen !ssa->var_info[res].has_range || ssa->var_info[res].range.underflow || ssa->var_info[res].range.overflow); - case ZEND_ASSIGN_ADD: - if (opline->extended_value != 0) { - return 1; - } - num = opline - op_array->opcodes; - res = ssa->ops[num].op1_def; - if (res < 0 || - !ssa->var_info[res].has_range) { - return 1; - } - if (ssa->var_info[res].range.underflow) { - zend_long op1_min, op2_min; - - if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { - return 1; - } - op1_min = OP1_MIN_RANGE(); - op2_min = OP2_MIN_RANGE(); - if (zend_add_will_overflow(op1_min, op2_min)) { + case ZEND_ASSIGN_OP: + if (opline->extended_value == ZEND_ADD) { + num = opline - op_array->opcodes; + res = ssa->ops[num].op1_def; + if (res < 0 || + !ssa->var_info[res].has_range) { return 1; } - } - if (ssa->var_info[res].range.overflow) { - zend_long op1_max, op2_max; + if (ssa->var_info[res].range.underflow) { + zend_long op1_min, op2_min; - if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { - return 1; - } - op1_max = OP1_MAX_RANGE(); - op2_max = OP2_MAX_RANGE(); - if (zend_add_will_overflow(op1_max, op2_max)) { - return 1; + if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { + return 1; + } + op1_min = OP1_MIN_RANGE(); + op2_min = OP2_MIN_RANGE(); + if (zend_add_will_overflow(op1_min, op2_min)) { + return 1; + } } - } - return 0; - case ZEND_ASSIGN_SUB: - if (opline->extended_value != 0) { - return 1; - } - num = opline - op_array->opcodes; - res = ssa->ops[num].op1_def; - if (res < 0 || - !ssa->var_info[res].has_range) { - return 1; - } - if (ssa->var_info[res].range.underflow) { - zend_long op1_min, op2_max; + if (ssa->var_info[res].range.overflow) { + zend_long op1_max, op2_max; - if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { - return 1; + if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { + return 1; + } + op1_max = OP1_MAX_RANGE(); + op2_max = OP2_MAX_RANGE(); + if (zend_add_will_overflow(op1_max, op2_max)) { + return 1; + } } - op1_min = OP1_MIN_RANGE(); - op2_max = OP2_MAX_RANGE(); - if (zend_sub_will_overflow(op1_min, op2_max)) { + return 0; + } else if (opline->extended_value == ZEND_SUB) { + num = opline - op_array->opcodes; + res = ssa->ops[num].op1_def; + if (res < 0 || + !ssa->var_info[res].has_range) { return 1; } - } - if (ssa->var_info[res].range.overflow) { - zend_long op1_max, op2_min; + if (ssa->var_info[res].range.underflow) { + zend_long op1_min, op2_max; - if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { - return 1; + if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { + return 1; + } + op1_min = OP1_MIN_RANGE(); + op2_max = OP2_MAX_RANGE(); + if (zend_sub_will_overflow(op1_min, op2_max)) { + return 1; + } } - op1_max = OP1_MAX_RANGE(); - op2_min = OP2_MIN_RANGE(); - if (zend_sub_will_overflow(op1_max, op2_min)) { - return 1; + if (ssa->var_info[res].range.overflow) { + zend_long op1_max, op2_min; + + if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) { + return 1; + } + op1_max = OP1_MAX_RANGE(); + op2_min = OP2_MIN_RANGE(); + if (zend_sub_will_overflow(op1_max, op2_min)) { + return 1; + } } + return 0; + } else if (opline->extended_value == ZEND_MUL) { + num = opline - op_array->opcodes; + res = ssa->ops[num].op1_def; + return (res < 0 || + !ssa->var_info[res].has_range || + ssa->var_info[res].range.underflow || + ssa->var_info[res].range.overflow); } - return 0; - case ZEND_ASSIGN_MUL: - if (opline->extended_value != 0) { - return 1; - } - num = opline - op_array->opcodes; - res = ssa->ops[num].op1_def; - return (res < 0 || - !ssa->var_info[res].has_range || - ssa->var_info[res].range.underflow || - ssa->var_info[res].range.overflow); default: return 1; } @@ -1471,10 +1459,10 @@ static int zend_jit_try_allocate_free_reg(zend_op_array *op_array, zend_ssa *ssa case ZEND_MUL: hint = ssa->ops[current->start].op1_use; break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - if (opline->extended_value) { + case ZEND_ASSIGN_OP: + if (opline->extended_value == ZEND_ADD + || opline->extended_value == ZEND_SUB + || opline->extended_value == ZEND_MUL) { hint = ssa->ops[current->start].op1_use; } break; @@ -1920,21 +1908,7 @@ static void zend_calc_checked_this_r(zend_bitset checked_this, zend_op_array *op for (; opline < end; opline++) { switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - if (opline->extended_value != ZEND_ASSIGN_OBJ) { - break; - } + case ZEND_ASSIGN_OBJ_OP: case ZEND_PRE_INC_OBJ: case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: @@ -2232,21 +2206,17 @@ static int zend_jit(zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_op goto jit_failure; } goto done; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: -// case ZEND_ASSIGN_DIV: // TODO: check for division by zero ??? - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_MOD: - if (!zend_jit_assign_op(&dasm_state, opline, op_array, ssa)) { - goto jit_failure; + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + if (opline->extended_value != ZEND_POW + && opline->extended_value != ZEND_DIV) { + // TODO: check for division by zero ??? + if (!zend_jit_assign_op(&dasm_state, opline, op_array, ssa)) { + goto jit_failure; + } + goto done; } - goto done; + break; case ZEND_ASSIGN_DIM: if (!zend_jit_assign_dim(&dasm_state, opline, op_array, ssa)) { goto jit_failure; diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index cfad5786ac..f45bfa8a39 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -757,18 +757,10 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void) uint32_t var; switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: msg = "Cannot use assign-op operators with string offsets"; break; case ZEND_FETCH_DIM_W: @@ -783,25 +775,15 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void) while (opline < end) { if (opline->op1_type == IS_VAR && opline->op1.var == var) { switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - if (opline->extended_value == ZEND_ASSIGN_OBJ) { - msg = "Cannot use string offset as an object"; - } else if (opline->extended_value == ZEND_ASSIGN_DIM) { - msg = "Cannot use string offset as an array"; - } else { - msg = "Cannot use assign-op operators with string offsets"; - } + case ZEND_ASSIGN_OBJ_OP: + msg = "Cannot use string offset as an object"; + break; + case ZEND_ASSIGN_DIM_OP: + msg = "Cannot use string offset as an array"; + break; + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + msg = "Cannot use assign-op operators with string offsets"; break; case ZEND_PRE_INC_OBJ: case ZEND_PRE_DEC_OBJ: diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 7a46588e90..8e2c0f529b 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -533,19 +533,15 @@ static void* dasm_labels[zend_lb_MAX]; |.macro FPU_MATH, opcode, addr || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | FPU_OP fadd, addr || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | FPU_OP fsub, addr || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | FPU_OP fmul, addr || break; || case ZEND_DIV: -|| case ZEND_ASSIGN_DIV: | FPU_OP fdiv, addr || break; || } @@ -664,19 +660,15 @@ static void* dasm_labels[zend_lb_MAX]; |.macro SSE_MATH, opcode, reg, addr || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | SSE_OP addsd, reg, addr || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | SSE_OP subsd, reg, addr || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | SSE_OP mulsd, reg, addr || break; || case ZEND_DIV: -|| case ZEND_ASSIGN_DIV: | SSE_OP divsd, reg, addr || break; || } @@ -685,19 +677,15 @@ static void* dasm_labels[zend_lb_MAX]; |.macro SSE_MATH_REG, opcode, dst_reg, src_reg || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | addsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | subsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | mulsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || case ZEND_DIV: -|| case ZEND_ASSIGN_DIV: | divsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || } @@ -729,19 +717,15 @@ static void* dasm_labels[zend_lb_MAX]; |.macro AVX_MATH, opcode, reg, op1_reg, addr || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | AVX_OP vaddsd, reg, op1_reg, addr || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | AVX_OP vsubsd, reg, op1_reg, addr || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | AVX_OP vmulsd, reg, op1_reg, addr || break; || case ZEND_DIV: -|| case ZEND_ASSIGN_DIV: | AVX_OP vdivsd, reg, op1_reg, addr || break; || } @@ -750,19 +734,15 @@ static void* dasm_labels[zend_lb_MAX]; |.macro AVX_MATH_REG, opcode, dst_reg, op1_reg, src_reg || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | vaddsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | vsubsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | vmulsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || case ZEND_DIV: -|| case ZEND_ASSIGN_DIV: | vdivsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0) || break; || } @@ -851,27 +831,21 @@ static void* dasm_labels[zend_lb_MAX]; |.macro LONG_MATH, opcode, reg, addr || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | LONG_OP add, reg, addr || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | LONG_OP sub, reg, addr || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | LONG_OP imul, reg, addr || break; || case ZEND_BW_OR: -|| case ZEND_ASSIGN_BW_OR: | LONG_OP or, reg, addr || break; || case ZEND_BW_AND: -|| case ZEND_ASSIGN_BW_AND: | LONG_OP and, reg, addr || break; || case ZEND_BW_XOR: -|| case ZEND_ASSIGN_BW_XOR: | LONG_OP xor, reg, addr || break; || default: @@ -882,27 +856,21 @@ static void* dasm_labels[zend_lb_MAX]; |.macro LONG_MATH_REG, opcode, dst_reg, src_reg || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | add dst_reg, src_reg || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | sub dst_reg, src_reg || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | imul dst_reg, src_reg || break; || case ZEND_BW_OR: -|| case ZEND_ASSIGN_BW_OR: | or dst_reg, src_reg || break; || case ZEND_BW_AND: -|| case ZEND_ASSIGN_BW_AND: | and dst_reg, src_reg || break; || case ZEND_BW_XOR: -|| case ZEND_ASSIGN_BW_XOR: | xor dst_reg, src_reg || break; || default: @@ -938,19 +906,15 @@ static void* dasm_labels[zend_lb_MAX]; |.macro FPU_MATH_REG, opcode, reg || switch (opcode) { || case ZEND_ADD: -|| case ZEND_ASSIGN_ADD: | fadd reg || break; || case ZEND_SUB: -|| case ZEND_ASSIGN_SUB: | fsub reg || break; || case ZEND_MUL: -|| case ZEND_ASSIGN_MUL: | fmul reg || break; || case ZEND_DIV: -|| case ZEND_ASSIGN_DIV: | fdiv reg || break; || } @@ -2786,26 +2750,13 @@ static int zend_jit_handler(dasm_State **Dst, const zend_op *opline, int may_thr case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_OBJ: case ZEND_ASSIGN_STATIC_PROP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_STATIC_PROP_REF: case ZEND_ASSIGN_OBJ_REF: last_valid_opline++; break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: - if (opline->extended_value) { - last_valid_opline++; - } - break; default: break; } @@ -3261,6 +3212,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, + zend_uchar opcode, zend_jit_addr op1_addr, zend_jit_addr op2_addr, zend_jit_addr res_addr, @@ -3278,7 +3230,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, result_reg = ZREG_R0; } - if (opline->opcode == ZEND_MUL && + if (opcode == ZEND_MUL && ((Z_MODE(op2_addr) == IS_CONST_ZVAL && IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr))) && is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr)))) || @@ -3292,17 +3244,17 @@ static int zend_jit_math_long_long(dasm_State **Dst, | GET_ZVAL_LVAL result_reg, op2_addr | shl Ra(result_reg), floor_log2(Z_LVAL_P(Z_ZV(op1_addr))) } - } else if (opline->opcode == ZEND_DIV && + } else if (opcode == ZEND_DIV && (Z_MODE(op2_addr) == IS_CONST_ZVAL && is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr))))) { | GET_ZVAL_LVAL result_reg, op1_addr | shr Ra(result_reg), floor_log2(Z_LVAL_P(Z_ZV(op2_addr))) } else { | GET_ZVAL_LVAL result_reg, op1_addr - if (same_ops && opline->opcode != ZEND_DIV) { - | LONG_MATH_REG opline->opcode, Ra(result_reg), Ra(result_reg) + if (same_ops && opcode != ZEND_DIV) { + | LONG_MATH_REG opcode, Ra(result_reg), Ra(result_reg) } else { - | LONG_MATH opline->opcode, result_reg, op2_addr + | LONG_MATH opcode, result_reg, op2_addr } } if ((res_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, op_array, ssa)) { @@ -3316,15 +3268,15 @@ static int zend_jit_math_long_long(dasm_State **Dst, | SSE_GET_ZVAL_LVAL tmp_reg1, op1_addr | SSE_GET_ZVAL_LVAL tmp_reg2, op2_addr if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) { - | AVX_MATH_REG opline->opcode, tmp_reg1, tmp_reg1, tmp_reg2 + | AVX_MATH_REG opcode, tmp_reg1, tmp_reg1, tmp_reg2 } else { - | SSE_MATH_REG opline->opcode, tmp_reg1, tmp_reg2 + | SSE_MATH_REG opcode, tmp_reg1, tmp_reg2 } | SSE_SET_ZVAL_DVAL res_addr, tmp_reg1 |.else | FPU_GET_ZVAL_LVAL op2_addr | FPU_GET_ZVAL_LVAL op1_addr - | FPU_MATH_REG opline->opcode, st1 + | FPU_MATH_REG opcode, st1 | FPU_SET_ZVAL_DVAL res_addr |.endif if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_DOUBLE) { @@ -3355,6 +3307,7 @@ static int zend_jit_math_long_double(dasm_State **Dst, zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, + zend_uchar opcode, zend_jit_addr op1_addr, zend_jit_addr op2_addr, zend_jit_addr res_addr, @@ -3366,14 +3319,14 @@ static int zend_jit_math_long_double(dasm_State **Dst, | SSE_GET_ZVAL_LVAL result_reg, op1_addr if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) { - | AVX_MATH opline->opcode, result_reg, result_reg, op2_addr + | AVX_MATH opcode, result_reg, result_reg, op2_addr } else { - | SSE_MATH opline->opcode, result_reg, op2_addr + | SSE_MATH opcode, result_reg, op2_addr } | SSE_SET_ZVAL_DVAL res_addr, result_reg |.else | FPU_GET_ZVAL_LVAL op1_addr - | FPU_MATH opline->opcode, op2_addr + | FPU_MATH opcode, op2_addr | FPU_SET_ZVAL_DVAL res_addr |.endif @@ -3390,6 +3343,7 @@ static int zend_jit_math_double_long(dasm_State **Dst, zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, + zend_uchar opcode, zend_jit_addr op1_addr, zend_jit_addr op2_addr, zend_jit_addr res_addr, @@ -3398,7 +3352,7 @@ static int zend_jit_math_double_long(dasm_State **Dst, |.if SSE zend_reg result_reg; - if (zend_is_commutative(opline->opcode)) { + if (zend_is_commutative(opcode)) { if (Z_MODE(res_addr) == IS_REG) { result_reg = Z_REG(res_addr); } else { @@ -3406,9 +3360,9 @@ static int zend_jit_math_double_long(dasm_State **Dst, } | SSE_GET_ZVAL_LVAL result_reg, op2_addr if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) { - | AVX_MATH opline->opcode, result_reg, result_reg, op1_addr + | AVX_MATH opcode, result_reg, result_reg, op1_addr } else { - | SSE_MATH opline->opcode, result_reg, op1_addr + | SSE_MATH opcode, result_reg, op1_addr } } else { zend_reg tmp_reg; @@ -3433,21 +3387,21 @@ static int zend_jit_math_double_long(dasm_State **Dst, op1_reg = result_reg; } | SSE_GET_ZVAL_LVAL tmp_reg, op2_addr - | AVX_MATH_REG opline->opcode, result_reg, op1_reg, tmp_reg + | AVX_MATH_REG opcode, result_reg, op1_reg, tmp_reg } else { | SSE_GET_ZVAL_DVAL result_reg, op1_addr | SSE_GET_ZVAL_LVAL tmp_reg, op2_addr - | SSE_MATH_REG opline->opcode, result_reg, tmp_reg + | SSE_MATH_REG opcode, result_reg, tmp_reg } } | SSE_SET_ZVAL_DVAL res_addr, result_reg |.else | FPU_GET_ZVAL_LVAL op2_addr - if (zend_is_commutative(opline->opcode)) { - | FPU_MATH opline->opcode, op1_addr + if (zend_is_commutative(opcode)) { + | FPU_MATH opcode, op1_addr } else { | FPU_GET_ZVAL_DVAL op1_addr - | FPU_MATH_REG opline->opcode, st1 + | FPU_MATH_REG opcode, st1 } | FPU_SET_ZVAL_DVAL res_addr |.endif @@ -3467,6 +3421,7 @@ static int zend_jit_math_double_double(dasm_State **Dst, zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, + zend_uchar opcode, zend_jit_addr op1_addr, zend_jit_addr op2_addr, zend_jit_addr res_addr, @@ -3492,7 +3447,7 @@ static int zend_jit_math_double_double(dasm_State **Dst, if (Z_MODE(op1_addr) == IS_REG) { op1_reg = Z_REG(op1_addr); val_addr = op2_addr; - } else if (Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opline->opcode)) { + } else if (Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opcode)) { op1_reg = Z_REG(op2_addr); val_addr = op1_addr; } else { @@ -3500,16 +3455,16 @@ static int zend_jit_math_double_double(dasm_State **Dst, op1_reg = result_reg; val_addr = op2_addr; } - if ((opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) && + if ((opcode == ZEND_MUL) && Z_MODE(val_addr) == IS_CONST_ZVAL && Z_DVAL_P(Z_ZV(val_addr)) == 2.0) { | AVX_MATH_REG ZEND_ADD, result_reg, op1_reg, op1_reg } else { - | AVX_MATH opline->opcode, result_reg, op1_reg, val_addr + | AVX_MATH opcode, result_reg, op1_reg, val_addr } } else { zend_jit_addr val_addr; - if (Z_MODE(op1_addr) != IS_REG && Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opline->opcode)) { + if (Z_MODE(op1_addr) != IS_REG && Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opcode)) { | SSE_GET_ZVAL_DVAL result_reg, op2_addr val_addr = op1_addr; } else { @@ -3517,18 +3472,18 @@ static int zend_jit_math_double_double(dasm_State **Dst, val_addr = op2_addr; } if (same_ops) { - | SSE_MATH_REG opline->opcode, result_reg, result_reg - } else if ((opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) && + | SSE_MATH_REG opcode, result_reg, result_reg + } else if ((opcode == ZEND_MUL) && Z_MODE(val_addr) == IS_CONST_ZVAL && Z_DVAL_P(Z_ZV(val_addr)) == 2.0) { | SSE_MATH_REG ZEND_ADD, result_reg, result_reg } else { - | SSE_MATH opline->opcode, result_reg, val_addr + | SSE_MATH opcode, result_reg, val_addr } } | SSE_SET_ZVAL_DVAL res_addr, result_reg |.else | FPU_GET_ZVAL_DVAL op1_addr - | FPU_MATH opline->opcode, op2_addr + | FPU_MATH opcode, op2_addr | FPU_SET_ZVAL_DVAL res_addr |.endif @@ -3545,6 +3500,7 @@ static int zend_jit_math_double_double(dasm_State **Dst, static int zend_jit_math_helper(dasm_State **Dst, const zend_op *opline, + zend_uchar opcode, zend_op_array *op_array, zend_ssa *ssa, zend_uchar op1_type, @@ -3579,7 +3535,7 @@ static int zend_jit_math_helper(dasm_State **Dst, if (op2_info & (MAY_BE_ANY-(MAY_BE_LONG|MAY_BE_DOUBLE))) { | IF_NOT_ZVAL_TYPE op2_addr, IS_DOUBLE, >6 } - if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } | jmp >5 @@ -3588,7 +3544,7 @@ static int zend_jit_math_helper(dasm_State **Dst, | IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6 } } - if (!zend_jit_math_long_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_info, res_use_info)) { + if (!zend_jit_math_long_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_info, res_use_info)) { return 0; } if (op1_info & MAY_BE_DOUBLE) { @@ -3605,7 +3561,7 @@ static int zend_jit_math_helper(dasm_State **Dst, | IF_NOT_ZVAL_TYPE, op2_addr, IS_DOUBLE, >6 } } - if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } | jmp >5 @@ -3615,7 +3571,7 @@ static int zend_jit_math_helper(dasm_State **Dst, if (op2_info & (MAY_BE_ANY-(MAY_BE_LONG|MAY_BE_DOUBLE))) { | IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6 } - if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } | jmp >5 @@ -3636,7 +3592,7 @@ static int zend_jit_math_helper(dasm_State **Dst, | IF_NOT_ZVAL_TYPE op2_addr, IS_DOUBLE, >6 } } - if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } } @@ -3648,7 +3604,7 @@ static int zend_jit_math_helper(dasm_State **Dst, if (op2_info & (MAY_BE_ANY-(MAY_BE_DOUBLE|MAY_BE_LONG))) { | IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6 } - if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } if (op2_info & MAY_BE_DOUBLE) { @@ -3670,7 +3626,7 @@ static int zend_jit_math_helper(dasm_State **Dst, | IF_NOT_ZVAL_TYPE op1_addr, IS_DOUBLE, >6 } } - if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } } @@ -3682,7 +3638,7 @@ static int zend_jit_math_helper(dasm_State **Dst, if (op1_info & (MAY_BE_ANY-(MAY_BE_DOUBLE|MAY_BE_LONG))) { | IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6 } - if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) { + if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) { return 0; } if (op1_info & MAY_BE_DOUBLE) { @@ -3729,13 +3685,13 @@ static int zend_jit_math_helper(dasm_State **Dst, | sub r4, 12 | PUSH_ZVAL_ADDR op2_addr, r0 |.endif - if (opline->opcode == ZEND_ADD || opline->opcode == ZEND_ASSIGN_ADD) { + if (opcode == ZEND_ADD) { | EXT_CALL add_function, r0 - } else if (opline->opcode == ZEND_SUB || opline->opcode == ZEND_ASSIGN_SUB) { + } else if (opcode == ZEND_SUB) { | EXT_CALL sub_function, r0 - } else if (opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) { + } else if (opcode == ZEND_MUL) { | EXT_CALL mul_function, r0 - } else if (opline->opcode == ZEND_DIV || opline->opcode == ZEND_ASSIGN_DIV) { + } else if (opcode == ZEND_DIV) { | EXT_CALL div_function, r0 } else { ZEND_ASSERT(0); @@ -3806,7 +3762,7 @@ static int zend_jit_math(dasm_State **Dst, const zend_op *opline, int *opnum, ze res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, ra, ssa->ops[opline - op_array->opcodes].result_def); } - if (!zend_jit_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, RES_INFO(), res_use_info)) { + if (!zend_jit_math_helper(Dst, opline, opline->opcode, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, RES_INFO(), res_use_info)) { return 0; } if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) { @@ -3821,6 +3777,7 @@ fallback: static int zend_jit_long_math_helper(dasm_State **Dst, const zend_op *opline, + zend_uchar opcode, zend_op_array *op_array, zend_ssa *ssa, zend_uchar op1_type, @@ -3841,7 +3798,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst, { zend_bool same_ops = zend_jit_same_addr(op1_addr, op2_addr); zend_reg result_reg; - zend_uchar opcode = opline->opcode; zval tmp; if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) { @@ -3875,7 +3831,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, result_reg = ZREG_R0; } - if (opcode == ZEND_SL || opcode == ZEND_ASSIGN_SL) { + if (opcode == ZEND_SL) { if (Z_MODE(op2_addr) == IS_CONST_ZVAL) { zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr)); @@ -3913,7 +3869,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | shl Ra(result_reg), cl |1: } - } else if (opcode == ZEND_SR || opcode == ZEND_ASSIGN_SR) { + } else if (opcode == ZEND_SR) { | GET_ZVAL_LVAL result_reg, op1_addr if (Z_MODE(op2_addr) == IS_CONST_ZVAL) { zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr)); @@ -3950,7 +3906,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, |1: | sar Ra(result_reg), cl } - } else if (opcode == ZEND_MOD || opcode == ZEND_ASSIGN_MOD) { + } else if (opcode == ZEND_MOD) { if (Z_MODE(op2_addr) == IS_CONST_ZVAL) { zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr)); @@ -4056,17 +4012,17 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | sub r4, 12 | PUSH_ZVAL_ADDR op2_addr, r0 |.endif - if (opline->opcode == ZEND_BW_OR || opline->opcode == ZEND_ASSIGN_BW_OR) { + if (opcode == ZEND_BW_OR) { | EXT_CALL bitwise_or_function, r0 - } else if (opline->opcode == ZEND_BW_AND || opline->opcode == ZEND_ASSIGN_BW_AND) { + } else if (opcode == ZEND_BW_AND) { | EXT_CALL bitwise_and_function, r0 - } else if (opline->opcode == ZEND_BW_XOR || opline->opcode == ZEND_ASSIGN_BW_XOR) { + } else if (opcode == ZEND_BW_XOR) { | EXT_CALL bitwise_xor_function, r0 - } else if (opline->opcode == ZEND_SL || opline->opcode == ZEND_ASSIGN_SL) { + } else if (opcode == ZEND_SL) { | EXT_CALL shift_left_function, r0 - } else if (opline->opcode == ZEND_SR || opline->opcode == ZEND_ASSIGN_SR) { + } else if (opcode == ZEND_SR) { | EXT_CALL shift_right_function, r0 - } else if (opline->opcode == ZEND_MOD || opline->opcode == ZEND_ASSIGN_MOD) { + } else if (opcode == ZEND_MOD) { | EXT_CALL mod_function, r0 } else { ZEND_ASSERT(0); @@ -4140,7 +4096,7 @@ static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, int *opnu res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, ra, ssa->ops[opline - op_array->opcodes].result_def); } - if (!zend_jit_long_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->result.var, res_addr, RES_INFO(), res_use_info)) { + if (!zend_jit_long_math_helper(Dst, opline, opline->opcode, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->result.var, res_addr, RES_INFO(), res_use_info)) { return 0; } if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) { @@ -5186,26 +5142,26 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_ } var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); - switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - if (!zend_jit_math_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), 0, var_addr, var_def_info, var_info)) { + switch (opline->extended_value) { + case ZEND_ADD: + case ZEND_SUB: + case ZEND_MUL: + case ZEND_DIV: + if (!zend_jit_math_helper(Dst, opline, opline->extended_value, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), 0, var_addr, var_def_info, var_info)) { return 0; } break; - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_MOD: - if (!zend_jit_long_math_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), op3_ssa_var, 0, var_addr, OP1_DEF_INFO(), var_info)) { + case ZEND_BW_OR: + case ZEND_BW_AND: + case ZEND_BW_XOR: + case ZEND_SL: + case ZEND_SR: + case ZEND_MOD: + if (!zend_jit_long_math_helper(Dst, opline, opline->extended_value, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), op3_ssa_var, 0, var_addr, OP1_DEF_INFO(), var_info)) { return 0; } break; - case ZEND_ASSIGN_CONCAT: + case ZEND_CONCAT: if (!zend_jit_concat_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), var_addr, OP1_DEF_INFO())) { return 0; } @@ -5235,7 +5191,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_ } else { | LOAD_ZVAL_ADDR FCARG2a, op2_addr } - binary_op = get_binary_op(opline->opcode); + binary_op = get_binary_op(opline->extended_value); |.if X64 | LOAD_ZVAL_ADDR CARG3, op3_addr | LOAD_ADDR CARG4, binary_op @@ -5269,9 +5225,9 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a zend_jit_addr op1_addr, op2_addr; int op1_ssa_var, op2_ssa_var; - if (opline->extended_value == ZEND_ASSIGN_DIM) { + if (opline->opcode == ZEND_ASSIGN_DIM_OP) { return zend_jit_assign_dim_op(Dst, opline, op_array, ssa); - } else if (opline->extended_value == ZEND_ASSIGN_OBJ || opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP || opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) { goto fallback; } @@ -5295,28 +5251,28 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a goto fallback; } - switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: + switch (opline->extended_value) { + case ZEND_ADD: + case ZEND_SUB: + case ZEND_MUL: + case ZEND_DIV: if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) || !(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) { goto fallback; } break; - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_MOD: + case ZEND_BW_OR: + case ZEND_BW_AND: + case ZEND_BW_XOR: + case ZEND_SL: + case ZEND_SR: + case ZEND_MOD: if (!(op1_info & MAY_BE_LONG) || !(op2_info & MAY_BE_LONG)) { goto fallback; } break; - case ZEND_ASSIGN_CONCAT: + case ZEND_CONCAT: if (!(op1_info & MAY_BE_STRING) || !(op2_info & MAY_BE_STRING)) { goto fallback; @@ -5332,20 +5288,20 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); } - switch (opline->opcode) { - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - return zend_jit_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info); - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_MOD: - return zend_jit_long_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info); - case ZEND_ASSIGN_CONCAT: + switch (opline->extended_value) { + case ZEND_ADD: + case ZEND_SUB: + case ZEND_MUL: + case ZEND_DIV: + return zend_jit_math_helper(Dst, opline, opline->extended_value, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info); + case ZEND_BW_OR: + case ZEND_BW_AND: + case ZEND_BW_XOR: + case ZEND_SL: + case ZEND_SR: + case ZEND_MOD: + return zend_jit_long_math_helper(Dst, opline, opline->extended_value, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info); + case ZEND_CONCAT: return zend_jit_concat_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, op1_addr, OP1_DEF_INFO()); default: ZEND_ASSERT(0); |
