From b3e51b76757b7c49a40d4237fb587831d0352402 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 23 Jul 2020 17:08:28 +0300 Subject: [PATCH] Allow keeping result of FETCH_DIM_R in CPU register --- ext/opcache/jit/zend_jit.c | 2 +- ext/opcache/jit/zend_jit_trace.c | 7 ++++--- ext/opcache/jit/zend_jit_x86.dasc | 24 ++++++++++++++++++------ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 48a04735da..0115ef7801 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -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; } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 310dacd840..c651606c5e 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -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 || diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ae0067dc82..0100e18725 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -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); -- 2.50.1