summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-04-06 16:17:02 +0300
committerDmitry Stogov <dmitry@zend.com>2020-04-06 16:17:02 +0300
commitc4bdf41862c07f5c7e0d4eb5dac4bbeac0b40296 (patch)
tree6d718b21dd8953169fb469583cb85c2469da61a7
parent98097138442181ba0435934d5cf4f6d257acaac6 (diff)
downloadphp-git-c4bdf41862c07f5c7e0d4eb5dac4bbeac0b40296.tar.gz
Minor register allocator refactoring
-rw-r--r--ext/opcache/jit/zend_jit.c7
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc32
-rw-r--r--ext/opcache/jit/zend_jit_x86.h18
3 files changed, 30 insertions, 27 deletions
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index 4839e93e6f..76acfc29de 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -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;
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 3029d911ba..2306c7a392 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -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);
}
}
diff --git a/ext/opcache/jit/zend_jit_x86.h b/ext/opcache/jit/zend_jit_x86.h
index 6a3b455105..71fcb93ae1 100644
--- a/ext/opcache/jit/zend_jit_x86.h
+++ b/ext/opcache/jit/zend_jit_x86.h
@@ -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)