]> granicus.if.org Git - php/commitdiff
Make operator swapping depend on IGNORE_OVERLOADING flag
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Jan 2019 08:26:49 +0000 (09:26 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 9 Jan 2019 08:27:56 +0000 (09:27 +0100)
Add MUL back to the list and instead make the entire optimization
depend on IGNORE_OVERLOADING, which is there exactly so we can make
these kinds of assumptions.

ext/opcache/Optimizer/pass3.c
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/Optimizer/zend_optimizer_internal.h

index 9f391408ec2206e2db9ab0e518c73bdbaa800edb..d382d37e112403ac28c09a48fb0fcbdab5781358 100644 (file)
@@ -50,7 +50,7 @@
        }                                                                               \
        jmp_hitlist[jmp_hitlist_count++] = ZEND_OP2_JMP_ADDR(target);
 
-void zend_optimizer_pass3(zend_op_array *op_array)
+void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
 {
        zend_op *opline;
        zend_op *end = op_array->opcodes + op_array->last;
@@ -90,15 +90,17 @@ void zend_optimizer_pass3(zend_op_array *op_array)
                                                break;
                                        }
 
-                                       if ((opline->op2_type & (IS_VAR | IS_CV))
+                                       /* change $i=expr+$i to $i=$i+expr so that the following optimization
+                                        * works on it. Only do this if we are ignoring operator overloading,
+                                        * as operand order might be significant otherwise. */
+                                       if ((ctx->optimization_level & ZEND_OPTIMIZER_IGNORE_OVERLOADING)
+                                               && (opline->op2_type & (IS_VAR | IS_CV))
                                                && opline->op2.var == next_opline->op1.var &&
                                                (opline->opcode == ZEND_ADD ||
+                                                opline->opcode == ZEND_MUL ||
                                                 opline->opcode == ZEND_BW_OR ||
                                                 opline->opcode == ZEND_BW_AND ||
                                                 opline->opcode == ZEND_BW_XOR)) {
-                                               /* change $i=expr+$i to $i=$i+expr so that the next
-                                               * optimization works on it
-                                               */
                                                zend_uchar tmp_type = opline->op1_type;
                                                znode_op tmp = opline->op1;
 
@@ -110,6 +112,7 @@ void zend_optimizer_pass3(zend_op_array *op_array)
                                                        COPY_NODE(opline->op2, tmp);
                                                }
                                        }
+
                                        if ((opline->op1_type & (IS_VAR | IS_CV))
                                                && opline->op1.var == next_opline->op1.var
                                                && opline->op1_type == next_opline->op1_type) {
index cb6cdf61d9d027be859a4180f29b3e47f8f0d031..4bbc3429525e738d59713a72c4a99a760b7868ab 100644 (file)
@@ -1131,7 +1131,7 @@ static void zend_optimize(zend_op_array      *op_array,
         * - change $i++ to ++$i where possible
         */
        if (ZEND_OPTIMIZER_PASS_3 & ctx->optimization_level) {
-               zend_optimizer_pass3(op_array);
+               zend_optimizer_pass3(op_array, ctx);
                if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_3) {
                        zend_dump_op_array(op_array, 0, "after pass 3", NULL);
                }
index 7bb5144ff4a3c487f11fe84fb62c295ed2158cbf..6c12a0d828452feaa705d209e3c6db4502997a6e 100644 (file)
@@ -95,7 +95,7 @@ void zend_optimizer_remove_live_range(zend_op_array *op_array, uint32_t var);
 void zend_optimizer_remove_live_range_ex(zend_op_array *op_array, uint32_t var, uint32_t start);
 void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 void zend_optimizer_pass2(zend_op_array *op_array);
-void zend_optimizer_pass3(zend_op_array *op_array);
+void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 void zend_optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx);