JIT support for ASSIGN_DIM[_OP] with IS_VAR op1 (#16339)

This commit is contained in:
Dmitry Stogov 2024-10-10 15:47:20 +03:00 committed by GitHub
parent 3da6818c9e
commit 57bfca9045
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 11 deletions

View file

@ -1741,7 +1741,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
break; break;
} }
if (!zend_jit_assign_dim_op(&ctx, opline, if (!zend_jit_assign_dim_op(&ctx, opline,
OP1_INFO(), OP1_DEF_INFO(), OP1_REG_ADDR(), OP1_INFO(), OP1_DEF_INFO(), OP1_REG_ADDR(), 0,
OP2_INFO(), (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0, OP2_INFO(), (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL, (opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
OP1_DATA_INFO(), OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), IS_UNKNOWN, OP1_DATA_INFO(), OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), IS_UNKNOWN,
@ -1757,7 +1757,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
break; break;
} }
if (!zend_jit_assign_dim(&ctx, opline, if (!zend_jit_assign_dim(&ctx, opline,
OP1_INFO(), OP1_REG_ADDR(), OP1_INFO(), OP1_REG_ADDR(), 0,
OP2_INFO(), (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0, OP2_INFO(), (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL, (opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
OP1_DATA_INFO(), OP1_DATA_REG_ADDR(), OP1_DATA_INFO(), OP1_DATA_REG_ADDR(),

View file

@ -13179,6 +13179,7 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit,
const zend_op *opline, const zend_op *opline,
uint32_t op1_info, uint32_t op1_info,
zend_jit_addr op1_addr, zend_jit_addr op1_addr,
bool op1_indirect,
uint32_t op2_info, uint32_t op2_info,
zend_jit_addr op2_addr, zend_jit_addr op2_addr,
zend_ssa_range *op2_range, zend_ssa_range *op2_range,
@ -13271,8 +13272,8 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit,
// JIT: value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE); // JIT: value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
if (opline->op1_type == IS_VAR if (opline->op1_type == IS_VAR
&& Z_MODE(op3_addr) != IS_REG && Z_MODE(op3_addr) != IS_REG
&& opline->result_type == IS_UNUSED
&& (res_addr == 0 || Z_MODE(res_addr) != IS_REG)) { && (res_addr == 0 || Z_MODE(res_addr) != IS_REG)) {
ZEND_ASSERT(opline->result_type == IS_UNUSED);
if (!zend_jit_assign_to_variable_call(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0)) { if (!zend_jit_assign_to_variable_call(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0)) {
return 0; return 0;
} }
@ -13339,6 +13340,10 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit,
ir_MERGE_list(end_inputs); ir_MERGE_list(end_inputs);
jit_FREE_OP(jit, opline->op2_type, opline->op2, op2_info, opline); jit_FREE_OP(jit, opline->op2_type, opline->op2, op2_info, opline);
if (!op1_indirect) {
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
}
if (may_throw) { if (may_throw) {
zend_jit_check_exception(jit); zend_jit_check_exception(jit);
} }
@ -13351,6 +13356,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit,
uint32_t op1_info, uint32_t op1_info,
uint32_t op1_def_info, uint32_t op1_def_info,
zend_jit_addr op1_addr, zend_jit_addr op1_addr,
bool op1_indirect,
uint32_t op2_info, uint32_t op2_info,
zend_jit_addr op2_addr, zend_jit_addr op2_addr,
zend_ssa_range *op2_range, zend_ssa_range *op2_range,
@ -13549,6 +13555,9 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit,
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, op1_data_info, NULL); jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, op1_data_info, NULL);
jit_FREE_OP(jit, opline->op2_type, opline->op2, op2_info, NULL); jit_FREE_OP(jit, opline->op2_type, opline->op2, op2_info, NULL);
if (!op1_indirect) {
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, NULL);
}
if (may_throw) { if (may_throw) {
zend_jit_check_exception(jit); zend_jit_check_exception(jit);
} }

View file

@ -4697,15 +4697,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
} }
op1_info = OP1_INFO(); op1_info = OP1_INFO();
op1_addr = OP1_REG_ADDR(); op1_addr = OP1_REG_ADDR();
op1_indirect = 0;
if (opline->op1_type == IS_VAR) { if (opline->op1_type == IS_VAR) {
if (orig_op1_type != IS_UNKNOWN if (orig_op1_type != IS_UNKNOWN
&& (orig_op1_type & IS_TRACE_INDIRECT)) { && (orig_op1_type & IS_TRACE_INDIRECT)) {
op1_indirect = 1;
if (!zend_jit_fetch_indirect_var(&ctx, opline, orig_op1_type, if (!zend_jit_fetch_indirect_var(&ctx, opline, orig_op1_type,
&op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) { &op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) {
goto jit_failure; goto jit_failure;
} }
} else {
break;
} }
} }
if (orig_op1_type != IS_UNKNOWN if (orig_op1_type != IS_UNKNOWN
@ -4727,7 +4727,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
CHECK_OP1_DATA_TRACE_TYPE(); CHECK_OP1_DATA_TRACE_TYPE();
op1_def_info = OP1_DEF_INFO(); op1_def_info = OP1_DEF_INFO();
if (!zend_jit_assign_dim_op(&ctx, opline, if (!zend_jit_assign_dim_op(&ctx, opline,
op1_info, op1_def_info, op1_addr, op1_info, op1_def_info, op1_addr, op1_indirect,
op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0, op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL, (opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
op1_data_info, OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), val_type, op1_data_info, OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), val_type,
@ -5009,6 +5009,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_DIM:
op1_info = OP1_INFO(); op1_info = OP1_INFO();
op1_addr = OP1_REG_ADDR(); op1_addr = OP1_REG_ADDR();
op1_indirect = 0;
if (opline->op1_type == IS_CV if (opline->op1_type == IS_CV
&& (opline+1)->op1_type == IS_CV && (opline+1)->op1_type == IS_CV
&& (opline+1)->op1.var == opline->op1.var) { && (opline+1)->op1.var == opline->op1.var) {
@ -5017,14 +5018,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
} }
if (opline->op1_type == IS_VAR) { if (opline->op1_type == IS_VAR) {
if (orig_op1_type != IS_UNKNOWN if (orig_op1_type != IS_UNKNOWN
&& (orig_op1_type & IS_TRACE_INDIRECT) && (orig_op1_type & IS_TRACE_INDIRECT)) {
&& opline->result_type == IS_UNUSED) { op1_indirect = 1;
if (!zend_jit_fetch_indirect_var(&ctx, opline, orig_op1_type, if (!zend_jit_fetch_indirect_var(&ctx, opline, orig_op1_type,
&op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) { &op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) {
goto jit_failure; goto jit_failure;
} }
} else {
break;
} }
} }
if (orig_op1_type != IS_UNKNOWN if (orig_op1_type != IS_UNKNOWN
@ -5045,7 +5044,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
op1_data_info = OP1_DATA_INFO(); op1_data_info = OP1_DATA_INFO();
CHECK_OP1_DATA_TRACE_TYPE(); CHECK_OP1_DATA_TRACE_TYPE();
if (!zend_jit_assign_dim(&ctx, opline, if (!zend_jit_assign_dim(&ctx, opline,
op1_info, op1_addr, op1_info, op1_addr, op1_indirect,
op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0, op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL, (opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
op1_data_info, OP1_DATA_REG_ADDR(), op1_data_info, OP1_DATA_REG_ADDR(),