From 3f1e35756ce05c0963cf8d706c1b8d845193c61a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 17 Mar 2016 09:58:15 +0300 Subject: [PATCH] Change LONG constants into DOUBLE, if they are going to be used as DOUBLE. --- ext/opcache/Optimizer/dfa_pass.c | 54 +++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 14 deletions(-) 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); + } + + } } } } -- 2.50.1