]> granicus.if.org Git - php/commitdiff
Clenup BINARY_OP + SEND_VAL optimization
authorDmitry Stogov <dmitry@zend.com>
Thu, 1 Oct 2020 19:39:58 +0000 (22:39 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 1 Oct 2020 19:39:58 +0000 (22:39 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 111b5f47e9075811e179931fb6f1d7232f17f6f2..91f1a5d458bdc130fdfec28e3cbfa9a27bbbd9b2 100644 (file)
@@ -2034,7 +2034,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
        zend_uchar smart_branch_opcode;
        uint32_t target_label, target_label2;
        uint32_t op1_info, op1_def_info, op2_info, res_info, res_use_info;
-       zend_bool send_result;
        zend_jit_addr op1_addr, op1_def_addr, op2_addr, op2_def_addr, res_addr;
        zend_class_entry *ce;
        zend_bool ce_is_instanceof;
@@ -2306,11 +2305,12 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                 && (opline+1)->op1_type == IS_TMP_VAR
                                                 && (opline+1)->op1.var == opline->result.var) {
                                                        i++;
-                                                       send_result = 1;
                                                        res_use_info = -1;
-                                                       res_addr = 0; /* set inside backend */
+                                                       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
+                                                       if (!zend_jit_reuse_ip(&dasm_state)) {
+                                                               goto jit_failure;
+                                                       }
                                                } else {
-                                                       send_result = 0;
                                                        res_use_info = RES_USE_INFO();
                                                        res_addr = RES_REG_ADDR();
                                                }
@@ -2318,7 +2318,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                                op1_info, OP1_RANGE(), OP1_REG_ADDR(),
                                                                op2_info, OP2_RANGE(), OP2_REG_ADDR(),
                                                                res_use_info, RES_INFO(), res_addr,
-                                                               send_result,
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
@@ -2353,11 +2352,12 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                 && (opline+1)->op1_type == IS_TMP_VAR
                                                 && (opline+1)->op1.var == opline->result.var) {
                                                        i++;
-                                                       send_result = 1;
                                                        res_use_info = -1;
-                                                       res_addr = 0; /* set inside backend */
+                                                       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
+                                                       if (!zend_jit_reuse_ip(&dasm_state)) {
+                                                               goto jit_failure;
+                                                       }
                                                } else {
-                                                       send_result = 0;
                                                        res_use_info = RES_USE_INFO();
                                                        res_addr = RES_REG_ADDR();
                                                }
@@ -2366,7 +2366,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                                op1_info, OP1_REG_ADDR(),
                                                                op2_info, OP2_REG_ADDR(),
                                                                res_use_info, res_info, res_addr,
-                                                               send_result,
                                                                (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG) && (res_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, ssa_op, op_array, ssa),
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
@@ -2392,12 +2391,15 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                 && (opline+1)->op1_type == IS_TMP_VAR
                                                 && (opline+1)->op1.var == opline->result.var) {
                                                        i++;
-                                                       send_result = 1;
+                                                       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
+                                                       if (!zend_jit_reuse_ip(&dasm_state)) {
+                                                               goto jit_failure;
+                                                       }
                                                } else {
-                                                       send_result = 0;
+                                                       res_addr = RES_REG_ADDR();
                                                }
                                                if (!zend_jit_concat(&dasm_state, opline,
-                                                               op1_info, op2_info, send_result,
+                                                               op1_info, op2_info, res_addr,
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
index caf162e44d48049813787ac6254e5da32c8aa817..27ff183ba487e2bd64037a63fba63d9e8e19b5e9 100644 (file)
@@ -3524,7 +3524,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                        }
                                                        send_result = 1;
                                                        res_use_info = -1;
-                                                       res_addr = 0; /* set inside backend */
+                                                       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
+                                                       if (!zend_jit_reuse_ip(&dasm_state)) {
+                                                               goto jit_failure;
+                                                       }
                                                } else {
                                                        send_result = 0;
                                                        if (opline->result_type == IS_CV) {
@@ -3543,7 +3546,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                op1_info, OP1_RANGE(), OP1_REG_ADDR(),
                                                                op2_info, OP2_RANGE(), OP2_REG_ADDR(),
                                                                res_use_info, res_info, res_addr,
-                                                               send_result,
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
@@ -3595,7 +3597,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                        }
                                                        send_result = 1;
                                                        res_use_info = -1;
-                                                       res_addr = 0; /* set inside backend */
+                                                       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
+                                                       if (!zend_jit_reuse_ip(&dasm_state)) {
+                                                               goto jit_failure;
+                                                       }
                                                } else {
                                                        send_result = 0;
                                                        if (opline->result_type == IS_CV) {
@@ -3614,7 +3619,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                op1_info, OP1_REG_ADDR(),
                                                                op2_info, OP2_REG_ADDR(),
                                                                res_use_info, res_info, res_addr,
-                                                               send_result,
                                                                (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG) && (res_info & (MAY_BE_DOUBLE|MAY_BE_GUARD)) && zend_may_overflow(opline, ssa_op, op_array, ssa),
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
@@ -3659,11 +3663,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                p++;
                                                        }
                                                        send_result = 1;
+                                                       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
+                                                       if (!zend_jit_reuse_ip(&dasm_state)) {
+                                                               goto jit_failure;
+                                                       }
                                                } else {
                                                        send_result = 0;
+                                                       res_addr = RES_REG_ADDR();
                                                }
                                                if (!zend_jit_concat(&dasm_state, opline,
-                                                               op1_info, op2_info, send_result,
+                                                               op1_info, op2_info, res_addr,
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
index fd04435818516ad889f1fc91d829fa4124844ed0..09143b21197fd75851bdbd35212101e002efedb1 100644 (file)
@@ -1656,6 +1656,16 @@ static void zend_jit_start_reuse_ip(void)
        reuse_ip = 1;
 }
 
+static int zend_jit_reuse_ip(dasm_State **Dst)
+{
+       if (!reuse_ip) {
+               zend_jit_start_reuse_ip();
+               |       // call = EX(call);
+               |       mov RX, EX->call
+       }
+       return 1;
+}
+
 static void zend_jit_stop_reuse_ip(void)
 {
        reuse_ip = 0;
@@ -4709,21 +4719,12 @@ static int zend_jit_math_helper(dasm_State    **Dst,
        return 1;
 }
 
-static int zend_jit_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, zend_bool send_result, int may_overflow, int may_throw)
+static int zend_jit_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, int may_overflow, int may_throw)
 {
        ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF));
        ZEND_ASSERT((op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) &&
            (op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE)));
 
-       if (send_result) {
-               if (!reuse_ip) {
-                       zend_jit_start_reuse_ip();
-                       |       // call = EX(call);
-                       |       mov RX, EX->call
-               }
-               res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
-       }
-
        if (!zend_jit_math_helper(Dst, opline, opline->opcode, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, res_info, res_use_info, may_overflow, may_throw)) {
                return 0;
        }
@@ -5049,20 +5050,11 @@ static int zend_jit_long_math_helper(dasm_State    **Dst,
        return 1;
 }
 
-static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_ssa_range *op1_range, zend_jit_addr op1_addr, uint32_t op2_info, zend_ssa_range *op2_range, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, zend_bool send_result, int may_throw)
+static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_ssa_range *op1_range, zend_jit_addr op1_addr, uint32_t op2_info, zend_ssa_range *op2_range, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, int may_throw)
 {
        ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF));
        ZEND_ASSERT((op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG));
 
-       if (send_result) {
-               if (!reuse_ip) {
-                       zend_jit_start_reuse_ip();
-                       |       // call = EX(call);
-                       |       mov RX, EX->call
-               }
-               res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
-       }
-
        if (!zend_jit_long_math_helper(Dst, opline, opline->opcode,
                        opline->op1_type, opline->op1, op1_addr, op1_info, op1_range,
                        opline->op2_type, opline->op2, op2_addr, op2_info, op2_range,
@@ -5160,9 +5152,9 @@ static int zend_jit_concat_helper(dasm_State    **Dst,
        return 1;
 }
 
-static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op2_info, zend_bool send_result, int may_throw)
+static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op2_info, zend_jit_addr res_addr, int may_throw)
 {
-       zend_jit_addr op1_addr, op2_addr, res_addr;
+       zend_jit_addr op1_addr, op2_addr;
 
        ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF));
        ZEND_ASSERT((op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING));
@@ -5170,16 +5162,6 @@ static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1
        op1_addr = OP1_ADDR();
        op2_addr = OP2_ADDR();
 
-       if (send_result) {
-               if (!reuse_ip) {
-                       zend_jit_start_reuse_ip();
-                       |       // call = EX(call);
-                       |       mov RX, EX->call
-               }
-               res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var);
-       } else {
-               res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
-       }
        return zend_jit_concat_helper(Dst, opline, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr, may_throw);
 }
 
@@ -10011,10 +9993,8 @@ static int zend_jit_send_val(dasm_State **Dst, const zend_op *opline, uint32_t o
 
        ZEND_ASSERT(opline->opcode == ZEND_SEND_VAL || arg_num <= MAX_ARG_FLAG_NUM);
 
-       if (!reuse_ip) {
-               zend_jit_start_reuse_ip();
-               |       // call = EX(call);
-               |       mov RX, EX->call
+       if (!zend_jit_reuse_ip(Dst)) {
+               return 0;
        }
 
        if (opline->opcode == ZEND_SEND_VAL_EX) {
@@ -10093,10 +10073,8 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend
        op1_addr = OP1_ADDR();
        arg_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, opline->result.var);
 
-       if (!reuse_ip) {
-               zend_jit_start_reuse_ip();
-               |       // call = EX(call);
-               |       mov RX, EX->call
+       if (!zend_jit_reuse_ip(Dst)) {
+               return 0;
        }
 
        if (opline->op1_type == IS_VAR) {
@@ -10180,10 +10158,8 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend
 
        arg_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, opline->result.var);
 
-       if (!reuse_ip) {
-               zend_jit_start_reuse_ip();
-               |       // call = EX(call);
-               |       mov RX, EX->call
+       if (!zend_jit_reuse_ip(Dst)) {
+               return 0;
        }
 
        if (opline->opcode == ZEND_SEND_VAR_EX) {
@@ -10427,11 +10403,10 @@ static int zend_jit_check_func_arg(dasm_State **Dst, const zend_op *opline)
                // if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
                uint32_t mask = (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF) << ((arg_num + 3) * 2);
 
-               if (!reuse_ip) {
-                       zend_jit_start_reuse_ip();
-                       |       // call = EX(call);
-                       |       mov RX, EX->call
+               if (!zend_jit_reuse_ip(Dst)) {
+                       return 0;
                }
+
                |       mov r0, EX:RX->func
                |       test dword [r0 + offsetof(zend_function, quick_arg_flags)], mask
                |       jnz >1