]> granicus.if.org Git - php/commitdiff
Change LONG constants into DOUBLE, if they are going to be used as DOUBLE.
authorDmitry Stogov <dmitry@zend.com>
Thu, 17 Mar 2016 06:58:15 +0000 (09:58 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 17 Mar 2016 06:58:15 +0000 (09:58 +0300)
ext/opcache/Optimizer/dfa_pass.c

index 6a346c48466d1758ccbdf763691ee89835bd6cdd..760e2e6e810593e9f2b21762148b4c845cf3a598 100644 (file)
@@ -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);
+                                               }
+
+                                       }
                                }
                        }
                }