]> granicus.if.org Git - php/commitdiff
Allow keeping result of FETCH_DIM_R in CPU register
authorDmitry Stogov <dmitry@zend.com>
Thu, 23 Jul 2020 14:08:28 +0000 (17:08 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 23 Jul 2020 14:08:28 +0000 (17:08 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 48a04735da552b56c894c68b243e959a7e7d5771..0115ef78017effc5ee33e007feb0a7d25268f958 100644 (file)
@@ -2732,7 +2732,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        break;
                                                }
                                                if (!zend_jit_fetch_dim_read(&dasm_state, opline, op_array, ssa, ssa_op,
-                                                               OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), RES_INFO(),
+                                                               OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
index 310dacd840d566103f194c222027c5fcf8d1edf7..c651606c5e6b5cd7fb5833f8f52530dbf246eb67 100644 (file)
@@ -2067,7 +2067,7 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
                        zend_bool support_opline;
 
                        support_opline =
-                               zend_jit_opline_supports_reg(op_array, ssa, opline, ssa_op);
+                               zend_jit_opline_supports_reg(op_array, ssa, opline, ssa_op, p);
                        if (ssa_op->op1_use >= 0
                         && start[ssa_op->op1_use] >= 0
                         && !zend_ssa_is_no_val_use(opline, ssa_op, ssa_op->op1_use)) {
@@ -2131,7 +2131,8 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
                                         || opline->opcode == ZEND_POST_DEC
                                         || opline->opcode == ZEND_ADD
                                         || opline->opcode == ZEND_SUB
-                                        || opline->opcode == ZEND_MUL) {
+                                        || opline->opcode == ZEND_MUL
+                                        || opline->opcode == ZEND_FETCH_DIM_R) {
                                                if (!(ssa->var_info[ssa_op->result_def].type & MAY_BE_DOUBLE)
                                                 || (opline->opcode != ZEND_PRE_INC && opline->opcode != ZEND_PRE_DEC)) {
                                                        start[ssa_op->result_def] = idx;
@@ -3850,7 +3851,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                CHECK_OP2_TRACE_TYPE();
                                                res_info = RES_INFO();
                                                if (!zend_jit_fetch_dim_read(&dasm_state, opline, op_array, ssa, ssa_op,
-                                                               op1_info, op1_addr, op2_info, res_info,
+                                                               op1_info, op1_addr, op2_info, res_info, RES_REG_ADDR(),
                                                                (
                                                                        (op1_info & MAY_BE_ANY) != MAY_BE_ARRAY ||
                                                                        (op2_info & (MAY_BE_ANY - (MAY_BE_LONG|MAY_BE_STRING))) != 0 ||
index ae0067dc82b2c2e9196208a2bddd32ef6480280d..0100e18725d1709970ad7092471f3ce76e4dc2af 100644 (file)
@@ -10386,16 +10386,15 @@ static zend_bool zend_jit_may_avoid_refcounting(const zend_op *opline)
        return 0;
 }
 
-static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t res_info, int may_throw)
+static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t res_info, zend_jit_addr res_addr, int may_throw)
 {
-       zend_jit_addr orig_op1_addr, op2_addr, res_addr;
+       zend_jit_addr orig_op1_addr, op2_addr;
        const void *exit_addr = NULL;
        const void *not_found_exit_addr = NULL;
        const void *res_exit_addr = NULL;
 
        orig_op1_addr = OP1_ADDR();
        op2_addr = OP2_ADDR();
-       res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
 
        if (opline->opcode != ZEND_FETCH_DIM_IS
         && JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
@@ -12221,7 +12220,7 @@ static zend_bool zend_jit_may_reuse_reg(const zend_op *opline, const zend_ssa_op
        return 0;
 }
 
-static zend_bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op)
+static zend_bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op, zend_jit_trace_rec *trace)
 {
        uint32_t op1_info, op2_info;
 
@@ -12275,6 +12274,19 @@ static zend_bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zen
                case ZEND_JMPZ_EX:
                case ZEND_JMPNZ_EX:
                        return 1;
+               case ZEND_FETCH_DIM_R:
+                       op1_info = OP1_INFO();
+                       op2_info = OP2_INFO();
+                       if (trace
+                        && trace->op1_type != IS_UNKNOWN
+                        && (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) == IS_ARRAY) {
+                               op1_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY);
+                       }
+                       return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&
+                               (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || !(op1_info & MAY_BE_RC1)) &&
+                                       (((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) ||
+                                        (((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING) &&
+                                                (!(opline->op2_type & (IS_TMP_VAR|IS_VAR)) || !(op2_info & MAY_BE_RC1))));
        }
        return 0;
 }
@@ -12321,7 +12333,7 @@ static zend_bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa
 
        if (ssa->vars[var].definition >= 0) {
                uint32_t def = ssa->vars[var].definition;
-               if (!zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + def, ssa->ops + def)) {
+               if (!zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + def, ssa->ops + def, NULL)) {
                        return 0;
                }
        }
@@ -12331,7 +12343,7 @@ static zend_bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa
 
                do {
                        if (!zend_ssa_is_no_val_use(op_array->opcodes + use, ssa->ops + use, var) &&
-                           !zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + use, ssa->ops + use)) {
+                           !zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + use, ssa->ops + use, NULL)) {
                                return 0;
                        }
                        use = zend_ssa_next_use(ssa->ops, var, use);