Skip to content

JIT: Improve CPU register usage in DETCH_DIM_R, FETCH_DIM_IS and FETCH_LIST_R #14222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -2219,7 +2219,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
}
if (!zend_jit_fetch_dim_read(&ctx, opline, ssa, ssa_op,
OP1_INFO(), OP1_REG_ADDR(), 0,
OP2_INFO(), RES_INFO(), RES_REG_ADDR(), IS_UNKNOWN)) {
OP2_INFO(), OP2_REG_ADDR(),
RES_INFO(), RES_REG_ADDR(), IS_UNKNOWN)) {
goto jit_failure;
}
goto done;
Expand Down
26 changes: 15 additions & 11 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -11366,6 +11366,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit,
uint32_t type,
uint32_t op1_info,
uint32_t op2_info,
zend_jit_addr op2_addr,
uint8_t dim_type,
const void *found_exit_addr,
const void *not_found_exit_addr,
Expand All @@ -11377,7 +11378,6 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit,
ir_ref *end_inputs,
ir_ref *not_found_inputs)
{
zend_jit_addr op2_addr = OP2_ADDR();
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
ir_ref ref = IR_UNUSED, cond, if_found;
ir_ref if_type = IS_UNUSED;
Expand Down Expand Up @@ -11965,11 +11965,12 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,
zend_jit_addr op1_addr,
bool op1_avoid_refcounting,
uint32_t op2_info,
zend_jit_addr op2_addr,
uint32_t res_info,
zend_jit_addr res_addr,
uint8_t dim_type)
{
zend_jit_addr orig_op1_addr, op2_addr;
zend_jit_addr orig_op1_addr;
const void *exit_addr = NULL;
const void *not_found_exit_addr = NULL;
bool result_type_guard = 0;
Expand All @@ -11981,7 +11982,6 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,
ir_ref not_found_inputs = IR_UNUSED;

orig_op1_addr = OP1_ADDR();
op2_addr = OP2_ADDR();

if (opline->opcode != ZEND_FETCH_DIM_IS
&& JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE
Expand Down Expand Up @@ -12086,7 +12086,7 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,

if (!zend_jit_fetch_dimension_address_inner(jit, opline,
(opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS,
op1_info, op2_info, dim_type, NULL, not_found_exit_addr, exit_addr,
op1_info, op2_info, op2_addr, dim_type, NULL, not_found_exit_addr, exit_addr,
result_type_guard, ht_ref, found_inputs, found_vals,
&end_inputs, &not_found_inputs)) {
return 0;
Expand Down Expand Up @@ -12489,7 +12489,8 @@ static int zend_jit_fetch_dim(zend_jit_ctx *jit,
if (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING))) {
may_throw = 1;
}
if (!zend_jit_fetch_dimension_address_inner(jit, opline, type, op1_info, op2_info, dim_type, NULL, NULL, NULL,
if (!zend_jit_fetch_dimension_address_inner(jit, opline, type, op1_info,
op2_info, OP2_ADDR(), dim_type, NULL, NULL, NULL,
0, ht_ref, found_inputs, found_vals, &end_inputs, NULL)) {
return 0;
}
Expand Down Expand Up @@ -12648,7 +12649,8 @@ static int zend_jit_isset_isempty_dim(zend_jit_ctx *jit,
not_found_exit_addr = exit_addr;
}
}
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_JIT_IS, op1_info, op2_info, dim_type, found_exit_addr, not_found_exit_addr, NULL,
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_JIT_IS, op1_info,
op2_info, OP2_ADDR(), dim_type, found_exit_addr, not_found_exit_addr, NULL,
0, ht_ref, true_inputs, NULL, &false_inputs, NULL)) {
return 0;
}
Expand Down Expand Up @@ -12849,7 +12851,8 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, const zend_op *opline, uint32_
ir_refs_init(found_inputs, 8);
ir_refs_init(found_values, 8);

if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_W, op1_info, op2_info, dim_type, NULL, NULL, NULL,
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_W, op1_info,
op2_info, OP2_ADDR(), dim_type, NULL, NULL, NULL,
0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) {
return 0;
}
Expand Down Expand Up @@ -13009,7 +13012,8 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit, const zend_op *opline, uint
}
}

if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, not_found_exit_addr, NULL,
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_RW, op1_info,
op2_info, OP2_ADDR(), dim_type, NULL, not_found_exit_addr, NULL,
0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) {
return 0;
}
Expand Down Expand Up @@ -16536,6 +16540,8 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
case ZEND_FETCH_CONSTANT:
return 1;
case ZEND_FETCH_DIM_R:
case ZEND_FETCH_DIM_IS:
case ZEND_FETCH_LIST_R:
op1_info = OP1_INFO();
op2_info = OP2_INFO();
if (trace
Expand All @@ -16544,10 +16550,8 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
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))));
((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING));
}
return 0;
}
Expand Down
7 changes: 3 additions & 4 deletions ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2909,9 +2909,7 @@ static zend_jit_reg_var* zend_jit_trace_allocate_registers(zend_jit_trace_rec *t
if (ssa_op->op2_use >= 0
&& ssa_op->op2_use != ssa_op->op1_use
&& RA_HAS_IVAL(ssa_op->op2_use)) {
/* Quick workaround to disable register allocation for unsupported operand */
// TODO: Find a general solution ???
if (!support_opline || opline->opcode == ZEND_FETCH_DIM_R) {
if (!support_opline) {
RA_IVAL_DEL(ssa_op->op2_use);
count--;
} else if (!zend_ssa_is_no_val_use(opline, ssa_op, ssa_op->op2_use)) {
Expand Down Expand Up @@ -5717,7 +5715,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
}
if (!zend_jit_fetch_dim_read(&ctx, opline, ssa, ssa_op,
op1_info, op1_addr, avoid_refcounting,
op2_info, res_info, RES_REG_ADDR(), val_type)) {
op2_info, OP2_REG_ADDR(),
res_info, RES_REG_ADDR(), val_type)) {
goto jit_failure;
}
if (ssa_op->op1_def >= 0 && op1_type != IS_UNKNOWN) {
Expand Down
Loading