]> granicus.if.org Git - php/commitdiff
Make QM_ASSIGN, JMP_SET and CAST return IS_TMP_VAR.
authorDmitry Stogov <dmitry@zend.com>
Tue, 23 Sep 2014 21:57:40 +0000 (01:57 +0400)
committerDmitry Stogov <dmitry@zend.com>
Tue, 23 Sep 2014 21:57:40 +0000 (01:57 +0400)
Zend/zend_compile.c
ext/opcache/Optimizer/pass1_5.c
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/Optimizer/zend_optimizer_internal.h

index 3714b94a8f656b10b787b4cabf03bbe392f52dec..8ad65587ca321d94c5125e4635c795f0fc7dbbcd 100644 (file)
@@ -483,8 +483,7 @@ void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
                        && opline->result.var == op1->u.op.var) {
                        if (opline->opcode == ZEND_FETCH_R ||
                            opline->opcode == ZEND_FETCH_DIM_R ||
-                           opline->opcode == ZEND_FETCH_OBJ_R ||
-                           opline->opcode == ZEND_QM_ASSIGN) {
+                           opline->opcode == ZEND_FETCH_OBJ_R) {
                                /* It's very rare and useless case. It's better to use
                                   additional FREE opcode and simplify the FETCH handlers
                                   their selves */
@@ -1708,7 +1707,9 @@ static zend_op *zend_emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, z
                SET_NODE(opline->op2, op2);
        }
 
-       zend_make_tmp_result(result, opline TSRMLS_CC);
+       if (result) {
+               zend_make_tmp_result(result, opline TSRMLS_CC);
+       }
 
        return opline;
 }
@@ -5259,7 +5260,7 @@ void zend_compile_cast(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
 
        zend_compile_expr(&expr_node, expr_ast TSRMLS_CC);
 
-       opline = zend_emit_op(result, ZEND_CAST, &expr_node, NULL TSRMLS_CC);
+       opline = zend_emit_op_tmp(result, ZEND_CAST, &expr_node, NULL TSRMLS_CC);
        opline->extended_value = ast->attr;
 }
 /* }}} */
@@ -5278,13 +5279,13 @@ static void zend_compile_shorthand_conditional(znode *result, zend_ast *ast TSRM
        zend_compile_expr(&cond_node, cond_ast TSRMLS_CC);
 
        opnum_jmp_set = get_next_op_number(CG(active_op_array));
-       zend_emit_op(result, ZEND_JMP_SET, &cond_node, NULL TSRMLS_CC);
+       zend_emit_op_tmp(result, ZEND_JMP_SET, &cond_node, NULL TSRMLS_CC);
 
        zend_compile_expr(&false_node, false_ast TSRMLS_CC);
 
        opline_jmp_set = &CG(active_op_array)->opcodes[opnum_jmp_set];
        opline_jmp_set->op2.opline_num = get_next_op_number(CG(active_op_array)) + 1;
-       opline_qm_assign = zend_emit_op(NULL, ZEND_QM_ASSIGN, &false_node, NULL TSRMLS_CC);
+       opline_qm_assign = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL TSRMLS_CC);
        SET_NODE(opline_qm_assign->result, result);
 }
 /* }}} */
@@ -5311,7 +5312,7 @@ void zend_compile_conditional(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
        zend_compile_expr(&true_node, true_ast TSRMLS_CC);
 
        opnum_qm_assign1 = get_next_op_number(CG(active_op_array));
-       zend_emit_op(result, ZEND_QM_ASSIGN, &true_node, NULL TSRMLS_CC);
+       zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &true_node, NULL TSRMLS_CC);
 
        opnum_jmp = zend_emit_jump(0 TSRMLS_CC);
 
index 3f3e72dc31c76bc5ee3b3f329a6a20216ead1aea..6a3f4e504d79beada8266f5677d217324222797a 100644 (file)
@@ -91,7 +91,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                literal_dtor(&ZEND_OP2_LITERAL(opline));
                                MAKE_NOP(opline);
 
-                               zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
+                               zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, tv, &result TSRMLS_CC);
                        }
                        break;
 
@@ -101,6 +101,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                opline->extended_value != IS_OBJECT &&
                                opline->extended_value != IS_RESOURCE) {
                                /* cast of constant operand */
+                               zend_uchar type = opline->result_type;
                                uint32_t tv = ZEND_RESULT(opline).var;          /* temporary variable */
                                zval res;
                                res = ZEND_OP1_LITERAL(opline);
@@ -126,11 +127,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                literal_dtor(&ZEND_OP1_LITERAL(opline));
                                MAKE_NOP(opline);
 
-                               if (opline->result_type == IS_TMP_VAR) {
-                                       zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
-                               } else /* if (opline->result_type == IS_VAR) */ {
-                                       zend_optimizer_replace_var_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
-                               }
+                               zend_optimizer_replace_by_const(op_array, opline + 1, type, tv, &res TSRMLS_CC);
                        } else if (opline->extended_value == _IS_BOOL) {
                                /* T = CAST(X, IS_BOOL) => T = BOOL(X) */
                                opline->opcode = ZEND_BOOL;
@@ -157,7 +154,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                literal_dtor(&ZEND_OP1_LITERAL(opline));
                                MAKE_NOP(opline);
 
-                               zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
+                               zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, tv, &result TSRMLS_CC);
                        }
                        break;
 
@@ -251,7 +248,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
 
                                        literal_dtor(&ZEND_OP2_LITERAL(opline));
                                        MAKE_NOP(opline);
-                                       zend_optimizer_replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC);
+                                       zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, offset TSRMLS_CC);
                                }
                                EG(current_execute_data) = orig_execute_data;
                                break;
@@ -271,7 +268,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                }
                                literal_dtor(&ZEND_OP2_LITERAL(opline));
                                MAKE_NOP(opline);
-                               zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
+                               zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &c TSRMLS_CC);
                        }
 
                        /* class constant */
@@ -332,7 +329,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                                }
                                                literal_dtor(&ZEND_OP2_LITERAL(opline));
                                                MAKE_NOP(opline);
-                                               zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &t TSRMLS_CC);
+                                               zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &t TSRMLS_CC);
                                        }
                                }
                        }
@@ -388,7 +385,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                                        func->module->type == MODULE_PERSISTENT) {
                                                zval t;
                                                ZVAL_BOOL(&t, 1);
-                                               if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
+                                               if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
                                                        literal_dtor(&ZEND_OP2_LITERAL(opline));
                                                        MAKE_NOP(opline);
                                                        literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@@ -421,7 +418,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                                }
                                        } 
 
-                                       if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
+                                       if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
                                                literal_dtor(&ZEND_OP2_LITERAL(opline));
                                                MAKE_NOP(opline);
                                                literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@@ -436,7 +433,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                        if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 0 TSRMLS_CC)) {
 
                                                ZVAL_BOOL(&t, 1);
-                                               if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
+                                               if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
                                                        literal_dtor(&ZEND_OP2_LITERAL(opline));
                                                        MAKE_NOP(opline);
                                                        literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@@ -450,7 +447,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                        zval t;
                                        
                                        if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 1 TSRMLS_CC)) {
-                                               if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
+                                               if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
                                                        literal_dtor(&ZEND_OP2_LITERAL(opline));
                                                        MAKE_NOP(opline);
                                                        literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@@ -465,7 +462,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                        zval t;
 
                                        ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)));
-                                       if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
+                                       if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
                                                literal_dtor(&ZEND_OP2_LITERAL(opline));
                                                MAKE_NOP(opline);
                                                literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@@ -481,7 +478,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                zval t;
 
                                ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline)));
-                               zend_optimizer_replace_tmp_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC);
+                               zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC);
                                literal_dtor(&ZEND_OP1_LITERAL(opline));
                                MAKE_NOP(opline);
                        }
@@ -494,7 +491,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
                                        break;
                                }
                                ZVAL_TRUE(&c);
-                               zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
+                               zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &c TSRMLS_CC);
                                literal_dtor(&ZEND_OP1_LITERAL(opline));
                                MAKE_NOP(opline);
                        }
index f31ce38cfec33b4e58e87e789b708256b232f08d..98030611ee251cab5f0ffd7ee68460025860c4c0 100644 (file)
@@ -262,15 +262,16 @@ check_numeric:
        }
 }
 
-int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
-                                        zend_op       *opline,
-                                        uint32_t      var,
-                                        zval          *val TSRMLS_DC)
+int zend_optimizer_replace_by_const(zend_op_array *op_array,
+                                    zend_op       *opline,
+                                    zend_uchar     type,
+                                    uint32_t       var,
+                                    zval          *val TSRMLS_DC)
 {
        zend_op *end = op_array->opcodes + op_array->last;
 
        while (opline < end) {
-               if (ZEND_OP1_TYPE(opline) == IS_VAR &&
+               if (ZEND_OP1_TYPE(opline) == type &&
                        ZEND_OP1(opline).var == var) {
                        switch (opline->opcode) {
                                case ZEND_FETCH_DIM_W:
@@ -292,6 +293,25 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
                                                opline->opcode = ZEND_SEND_VAL;
                                        }
                                        break;
+                               /* In most cases IS_TMP_VAR operand may be used only once.
+                                * The operands are usually destroyed by the opcode handler.
+                                * ZEND_CASE is an exception, that keeps operand unchanged,
+                                * and allows its reuse. The number of ZEND_CASE instructions
+                                * usually terminated by ZEND_FREE that finally kills the value.
+                                */
+                               case ZEND_CASE: {
+                                       zval old_val;
+                                       ZVAL_COPY_VALUE(&old_val, val);
+                                       zval_copy_ctor(val);
+                                       zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
+                                       zval_dtor(&old_val);
+                                       opline++;
+                                       continue;
+                               }
+                               case ZEND_FREE:
+                                       MAKE_NOP(opline);
+                                       zval_dtor(val);
+                                       return 1;
                                default:
                                        break;
                        } 
@@ -299,7 +319,7 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
                        break;
                }
                
-               if (ZEND_OP2_TYPE(opline) == IS_VAR &&
+               if (ZEND_OP2_TYPE(opline) == type &&
                        ZEND_OP2(opline).var == var) {
                        switch (opline->opcode) {
                                case ZEND_ASSIGN_REF:
@@ -316,55 +336,6 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
        return 1;
 }
 
-void zend_optimizer_replace_tmp_by_const(zend_op_array *op_array,
-                                         zend_op       *opline,
-                                         uint32_t      var,
-                                         zval          *val
-                                         TSRMLS_DC)
-{
-       zend_op *end = op_array->opcodes + op_array->last;
-
-       while (opline < end) {
-               if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
-                       ZEND_OP1(opline).var == var) {
-
-                       /* In most cases IS_TMP_VAR operand may be used only once.
-                        * The operands are usually destroyed by the opcode handler.
-                        * ZEND_CASE is an exception, that keeps operand unchanged,
-                        * and allows its reuse. The number of ZEND_CASE instructions
-                        * usually terminated by ZEND_FREE that finally kills the value.
-                        */
-                       if (opline->opcode == ZEND_CASE) {
-                               zval old_val;
-                               ZVAL_COPY_VALUE(&old_val, val);
-                               zval_copy_ctor(val);
-                               zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
-                               ZVAL_COPY_VALUE(val, &old_val);
-                       } else if (opline->opcode == ZEND_FREE) {
-                               MAKE_NOP(opline);
-                               break;
-                       } else {                                
-                               zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
-                               val = NULL;
-                               break;
-                       }
-               }
-
-               if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
-                       ZEND_OP2(opline).var == var) {
-
-                       zend_optimizer_update_op2_const(op_array, opline, val TSRMLS_CC);
-                       /* TMP_VAR may be used only once */
-                       val = NULL;
-                       break;
-               }
-               opline++;
-       }
-       if (val) {
-               zval_dtor(val);
-       }
-}
-
 static void zend_optimize(zend_op_array      *op_array,
                           zend_optimizer_ctx *ctx TSRMLS_DC)
 {
index ac87cf9f35f0d2c16804d5395fa5e2311f1cea98..ba91b147c9f404442464a317f6a0406db75d986d 100644 (file)
@@ -112,14 +112,11 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array,
 void zend_optimizer_update_op2_const(zend_op_array *op_array,
                                      zend_op       *opline,
                                      zval          *val TSRMLS_DC);
-int  zend_optimizer_replace_var_by_const(zend_op_array *op_array,
-                                         zend_op       *opline,
-                                         uint32_t      var,
-                                         zval          *val TSRMLS_DC);
-void zend_optimizer_replace_tmp_by_const(zend_op_array *op_array,
-                                         zend_op       *opline,
-                                         uint32_t      var,
-                                         zval          *val TSRMLS_DC);
+int  zend_optimizer_replace_by_const(zend_op_array *op_array,
+                                     zend_op       *opline,
+                                     zend_uchar     type,
+                                     uint32_t       var,
+                                     zval          *val TSRMLS_DC);
 
 void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC);
 void zend_optimizer_pass2(zend_op_array *op_array TSRMLS_DC);