From: Dmitry Stogov Date: Thu, 17 Mar 2016 06:58:15 +0000 (+0300) Subject: Change LONG constants into DOUBLE, if they are going to be used as DOUBLE. X-Git-Tag: php-7.1.0alpha1~471 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3f1e35756ce05c0963cf8d706c1b8d845193c61a;p=php Change LONG constants into DOUBLE, if they are going to be used as DOUBLE. --- diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 6a346c4846..760e2e6e81 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -413,27 +413,53 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx if (ssa->var_info) { int i; zend_op *opline, *end; - uint32_t op1_info, op2_info, res_info; zval tmp; /* Convert LONG constants to DOUBLE */ for (i = 0; i < ssa->vars_count; i++) { - if (ssa->var_info[i].use_as_double && ssa->vars[i].definition >= 0) { + if (ssa->vars[i].definition >= 0) { int op = ssa->vars[i].definition; opline = op_array->opcodes + op; - if (opline->opcode == ZEND_ASSIGN && - opline->op2_type == IS_CONST) { - zval *zv = CT_CONSTANT_EX(op_array, opline->op2.constant); - ZEND_ASSERT(Z_TYPE_INFO_P(zv) == IS_LONG); - ZVAL_DOUBLE(&tmp, zval_get_double(zv)); - opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp); - } else if (opline->opcode == ZEND_QM_ASSIGN && - opline->op1_type == IS_CONST) { - zval *zv = CT_CONSTANT_EX(op_array, opline->op1.constant); - ZEND_ASSERT(Z_TYPE_INFO_P(zv) == IS_LONG); - ZVAL_DOUBLE(&tmp, zval_get_double(zv)); - opline->op1.constant = zend_optimizer_add_literal(op_array, &tmp); + if (ssa->var_info[i].use_as_double) { + if (opline->opcode == ZEND_ASSIGN && + opline->op2_type == IS_CONST) { + zval *zv = CT_CONSTANT_EX(op_array, opline->op2.constant); + ZEND_ASSERT(Z_TYPE_INFO_P(zv) == IS_LONG); + ZVAL_DOUBLE(&tmp, zval_get_double(zv)); + opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp); + } else if (opline->opcode == ZEND_QM_ASSIGN && + opline->op1_type == IS_CONST) { + zval *zv = CT_CONSTANT_EX(op_array, opline->op1.constant); + ZEND_ASSERT(Z_TYPE_INFO_P(zv) == IS_LONG); + ZVAL_DOUBLE(&tmp, zval_get_double(zv)); + opline->op1.constant = zend_optimizer_add_literal(op_array, &tmp); + } + } else { + if (opline->opcode == ZEND_ADD || + opline->opcode == ZEND_SUB || + opline->opcode == ZEND_MUL || + opline->opcode == ZEND_IS_EQUAL || + opline->opcode == ZEND_IS_NOT_EQUAL || + opline->opcode == ZEND_IS_SMALLER || + opline->opcode == ZEND_IS_SMALLER_OR_EQUAL) { + if (opline->op1_type == IS_CONST && + opline->op2_type != IS_CONST && + (OP2_INFO() & MAY_BE_ANY) == MAY_BE_DOUBLE && + Z_TYPE_INFO_P(CT_CONSTANT_EX(op_array, opline->op1.constant)) == IS_LONG) { + zval *zv = CT_CONSTANT_EX(op_array, opline->op1.constant); + ZVAL_DOUBLE(&tmp, zval_get_double(zv)); + opline->op1.constant = zend_optimizer_add_literal(op_array, &tmp); + } else if (opline->op1_type != IS_CONST && + opline->op2_type == IS_CONST && + (OP1_INFO() & MAY_BE_ANY) == MAY_BE_DOUBLE && + Z_TYPE_INFO_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG) { + zval *zv = CT_CONSTANT_EX(op_array, opline->op2.constant); + ZVAL_DOUBLE(&tmp, zval_get_double(zv)); + opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp); + } + + } } } }