]> granicus.if.org Git - php/commitdiff
Fixed register allocation
authorDmitry Stogov <dmitry@zend.com>
Thu, 22 Oct 2020 20:16:41 +0000 (23:16 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 22 Oct 2020 20:16:41 +0000 (23:16 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_x86.dasc

index 6b16f83d51a6f1340b482b2a234d3811606faedd..0782f74dc04524a42c837643e6db2da07ce2a41b 100644 (file)
@@ -1560,6 +1560,15 @@ static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, const z
                if (ssa->ops[line].op1_def == current->ssa_var ||
                    ssa->ops[line].op2_def == current->ssa_var ||
                    ssa->ops[line].result_def == current->ssa_var) {
+                       regset = zend_jit_get_def_scratch_regset(
+                               ssa_opcodes ? ssa_opcodes[line] : op_array->opcodes + line,
+                               ssa->ops + line,
+                               op_array, ssa, current->ssa_var, line == last_use_line);
+                       ZEND_REGSET_FOREACH(regset, reg) {
+                               if (line < freeUntilPos[reg]) {
+                                       freeUntilPos[reg] = line;
+                               }
+                       } ZEND_REGSET_FOREACH_END();
                        line++;
                }
                while (line <= range->end) {
index beda12759862781462040a34224ea425ac9bed7e..3acf4b740ed3fafea11936c5e5b0c30ece54bbc2 100644 (file)
@@ -15162,6 +15162,28 @@ static zend_bool zend_needs_extra_reg_for_const(const zend_op *opline, zend_ucha
        return 0;
 }
 
+static zend_regset zend_jit_get_def_scratch_regset(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, zend_ssa *ssa, int current_var, zend_bool last_use)
+{
+       uint32_t op1_info, op2_info;
+
+       switch (opline->opcode) {
+               case ZEND_FETCH_DIM_R:
+                       op1_info = OP1_INFO();
+                       op2_info = OP2_INFO();
+                       if (((opline->op1_type & (IS_TMP_VAR|IS_VAR)) &&
+                            (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) ||
+                           ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) &&
+                            (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)))) {
+                               return ZEND_REGSET(ZREG_FCARG1a);
+                       }
+                       break;
+               default:
+                       break;
+       }
+
+       return ZEND_REGSET_EMPTY;
+}
+
 static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, zend_ssa *ssa, int current_var, zend_bool last_use)
 {
        uint32_t op1_info, op2_info, res_info;