]> granicus.if.org Git - php/commitdiff
Minor register allocator refactoring
authorDmitry Stogov <dmitry@zend.com>
Mon, 6 Apr 2020 13:17:02 +0000 (16:17 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 6 Apr 2020 13:17:02 +0000 (16:17 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_x86.dasc
ext/opcache/jit/zend_jit_x86.h

index 4839e93e6f919f4a10d6a77a1b4cd7317c7fa5a7..76acfc29defed1797da4c6b989216d4df2a63a10 100644 (file)
@@ -1404,7 +1404,7 @@ static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, zend_ss
                while (it) {
                        if (current->range.start != zend_interval_end(it)) {
                                freeUntilPos[it->reg] = 0;
-                       } else if (zend_jit_may_reuse_reg(op_array, ssa, current->range.start, current->ssa_var, it->ssa_var)) {
+                       } else if (zend_jit_may_reuse_reg(op_array->opcodes + current->range.start, ssa->ops + current->range.start, ssa, current->ssa_var, it->ssa_var)) {
                                if (!ZEND_REGSET_IN(*hints, it->reg) &&
                                    /* TODO: Avoid most often scratch registers. Find a better way ??? */
                                    (!current->used_as_hint ||
@@ -1460,7 +1460,10 @@ static int zend_jit_try_allocate_free_reg(const zend_op_array *op_array, zend_ss
                        line++;
                }
                while (line <= range->end) {
-                       regset = zend_jit_get_scratch_regset(op_array, ssa, line, current->ssa_var);
+                       regset = zend_jit_get_scratch_regset(
+                               op_array->opcodes + line,
+                               ssa->ops + line,
+                               op_array, ssa, current->ssa_var);
                        ZEND_REGSET_FOREACH(regset, reg) {
                                if (line < freeUntilPos[reg]) {
                                        freeUntilPos[reg] = line;
index 3029d911ba9f9194c5ca3d3e322320c0e981ffc6..2306c7a39205f5212b3385b5159d246d2d369039 100644 (file)
@@ -10895,13 +10895,13 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op
        return 1;
 }
 
-static zend_bool zend_jit_may_reuse_reg(const zend_op_array *op_array, zend_ssa *ssa, uint32_t position, int def_var, int use_var)
+static zend_bool zend_jit_may_reuse_reg(const zend_op *opline, const zend_ssa_op *ssa_op, zend_ssa *ssa, int def_var, int use_var)
 {
        if (ssa->var_info[def_var].type != ssa->var_info[use_var].type) {
                return 0;
        }
 
-       switch (op_array->opcodes[position].opcode) {
+       switch (opline->opcode) {
                case ZEND_QM_ASSIGN:
                case ZEND_SEND_VAR:
                case ZEND_ASSIGN:
@@ -10916,8 +10916,8 @@ static zend_bool zend_jit_may_reuse_reg(const zend_op_array *op_array, zend_ssa
                case ZEND_BW_OR:
                case ZEND_BW_AND:
                case ZEND_BW_XOR:
-                       if (def_var == ssa->ops[position].result_def &&
-                           use_var == ssa->ops[position].op1_use) {
+                       if (def_var == ssa_op->result_def &&
+                           use_var == ssa_op->op1_use) {
                                return 1;
                        }
                        break;
@@ -11068,10 +11068,8 @@ static zend_bool zend_needs_extra_reg_for_const(const zend_op_array *op_array, c
        return 0;
 }
 
-static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, zend_ssa *ssa, uint32_t line, int current_var)
+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)
 {
-       const zend_op *opline = op_array->opcodes + line;
-       const zend_ssa_op *ssa_op = ssa->ops + line;
        uint32_t op1_info, op2_info, res_info;
        zend_regset regset = ZEND_REGSET_SCRATCH;
 
@@ -11178,7 +11176,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, ze
                                regset = ZEND_REGSET_EMPTY;
                                if ((op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG)) {
                                        if (ssa_op->result_def != current_var &&
-                                           (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, line))) {
+                                           (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, ssa_op - ssa->ops))) {
                                                ZEND_REGSET_INCL(regset, ZREG_R0);
                                        }
                                        res_info = OP1_INFO();
@@ -11200,14 +11198,14 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, ze
                                        } else {
                                                ZEND_REGSET_INCL(regset, ZREG_XMM0);
                                                if (ssa_op->result_def != current_var &&
-                                                   (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, line))) {
+                                                   (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, ssa_op - ssa->ops))) {
                                                        ZEND_REGSET_INCL(regset, ZREG_XMM1);
                                                }
                                        }
                                }
                                if ((op1_info & MAY_BE_DOUBLE) && (op2_info & MAY_BE_DOUBLE)) {
                                        if (ssa_op->result_def != current_var &&
-                                           (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, line))) {
+                                           (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, ssa_op - ssa->ops))) {
                                                ZEND_REGSET_INCL(regset, ZREG_XMM0);
                                        }
                                }
@@ -11226,7 +11224,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, ze
                            !(op2_info & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)-MAY_BE_LONG))) {
                                regset = ZEND_REGSET_EMPTY;
                                if (ssa_op->result_def != current_var &&
-                                   (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, line))) {
+                                   (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, ssa_op - ssa->ops))) {
                                        ZEND_REGSET_INCL(regset, ZREG_R0);
                                }
                        }
@@ -11239,7 +11237,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, ze
                            !(op2_info & ((MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)-MAY_BE_LONG))) {
                                regset = ZEND_REGSET_EMPTY;
                                if (ssa_op->result_def != current_var &&
-                                   (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, line))) {
+                                   (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, ssa_op - ssa->ops))) {
                                        ZEND_REGSET_INCL(regset, ZREG_R0);
                                }
                                if (opline->op2_type != IS_CONST && ssa_op->op2_use != current_var) {
@@ -11257,7 +11255,7 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, ze
                                    Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) == IS_LONG &&
                                    zend_long_is_power_of_two(Z_LVAL_P(RT_CONSTANT(opline, opline->op2)))) {
                                        if (ssa_op->result_def != current_var &&
-                                           (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, line))) {
+                                           (ssa_op->op1_use != current_var || !zend_ssa_is_last_use(op_array, ssa, current_var, ssa_op - ssa->ops))) {
                                                ZEND_REGSET_INCL(regset, ZREG_R0);
                                        }
                                } else {
@@ -11339,11 +11337,13 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op_array *op_array, ze
 
 #if ZTS
        /* %r0 is used to check EG(vm_interrupt) */
-       {
-               uint32_t b = ssa->cfg.map[line];
+       if (zend_jit_trigger == ZEND_JIT_ON_HOT_TRACE) {
+               // TODO: loop detection ???
+       } else  {
+               uint32_t b = ssa->cfg.map[ssa_op - ssa->ops];
 
                if ((ssa->cfg.blocks[b].flags & ZEND_BB_LOOP_HEADER) != 0
-                && ssa->cfg.blocks[b].start == line) {
+                && ssa->cfg.blocks[b].start == ssa_op - ssa->ops) {
                        ZEND_REGSET_INCL(regset, ZREG_R0);
                }
        }
index 6a3b4551051a6b4c97d424784b7f8820a8d0161d..71fcb93ae13b46b6ccd4e548ed53ea1fe54479a3 100644 (file)
@@ -236,12 +236,12 @@ typedef uintptr_t zend_jit_addr;
         ((last_use) ? (1 << (_ZEND_ADDR_REG_LAST_USE_BIT-_ZEND_ADDR_REG_SHIFT)) : 0) \
        )
 
-#define OP_REG(line, op) \
-       (ra && ssa->ops[line].op >= 0 && ra[ssa->ops[line].op] ? \
-               OP_REG_EX(ra[ssa->ops[line].op]->reg, \
-                       ra[ssa->ops[line].op]->store, \
-                       ra[ssa->ops[line].op]->load, \
-                       zend_ssa_is_last_use(op_array, ssa, ssa->ops[line].op, line) \
+#define OP_REG(ssa_op, op) \
+       (ra && ssa_op->op >= 0 && ra[ssa_op->op] ? \
+               OP_REG_EX(ra[ssa_op->op]->reg, \
+                       ra[ssa_op->op]->store, \
+                       ra[ssa_op->op]->load, \
+                       zend_ssa_is_last_use(op_array, ssa, ssa_op->op, ssa_op - ssa->ops) \
                ) : ZREG_NONE)
 
 static zend_always_inline zend_jit_addr _zend_jit_decode_op(zend_uchar op_type, znode_op op, const zend_op *opline, zend_reg reg)
@@ -274,9 +274,9 @@ static zend_always_inline zend_jit_addr _zend_jit_decode_op(zend_uchar op_type,
 #define OP1_DATA_ADDR() \
        OP_ADDR(opline + 1, op1_type, op1)
 
-#define OP_REG_ADDR(opline, type, op, ssa_op) \
-       _zend_jit_decode_op((opline)->type, (opline)->op, opline, \
-               OP_REG((opline) - op_array->opcodes, ssa_op))
+#define OP_REG_ADDR(opline, type, _op, _ssa_op) \
+       _zend_jit_decode_op((opline)->type, (opline)->_op, opline, \
+               OP_REG(ssa_op, _ssa_op))
 
 #define OP1_REG_ADDR() \
        OP_REG_ADDR(opline, op1_type, op1, op1_use)