Skip to content

Commit d2efb7e

Browse files
committed
Eliminate unnecessary IS_INDIRECT guards
1 parent 1c59bd5 commit d2efb7e

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

ext/opcache/Optimizer/zend_ssa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ typedef struct _zend_ssa_var_info {
130130
unsigned int delayed_fetch_this : 1;
131131
unsigned int avoid_refcounting : 1;
132132
unsigned int guarded_reference : 1;
133+
unsigned int indirect_reference : 1; /* IS_INDIRECT returned by FETCH_DIM_W/FETCH_OBJ_W */
133134
} zend_ssa_var_info;
134135

135136
typedef struct _zend_ssa {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3675,7 +3675,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
36753675
if (opline->op1_type == IS_VAR) {
36763676
if (orig_op1_type != IS_UNKNOWN
36773677
&& (orig_op1_type & IS_TRACE_INDIRECT)) {
3678-
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
3678+
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type,
3679+
&op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) {
36793680
goto jit_failure;
36803681
}
36813682
} else {
@@ -3714,7 +3715,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
37143715
if (orig_op1_type != IS_UNKNOWN
37153716
&& (orig_op1_type & IS_TRACE_INDIRECT)
37163717
&& opline->result_type == IS_UNUSED) {
3717-
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
3718+
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type,
3719+
&op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) {
37183720
goto jit_failure;
37193721
}
37203722
} else {
@@ -4361,7 +4363,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43614363
if (opline->op1_type == IS_VAR) {
43624364
if (orig_op1_type != IS_UNKNOWN
43634365
&& (orig_op1_type & IS_TRACE_INDIRECT)) {
4364-
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
4366+
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type,
4367+
&op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) {
43654368
goto jit_failure;
43664369
}
43674370
} else {
@@ -4386,9 +4389,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43864389
op1_def_info = OP1_DEF_INFO();
43874390
if (!zend_jit_fetch_dim(&dasm_state, opline,
43884391
op1_info, op1_addr, op2_info, RES_REG_ADDR(),
4389-
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info))) {
4392+
(opline->opcode == ZEND_FETCH_DIM_RW
4393+
|| opline->op2_type == IS_UNUSED
4394+
|| (op1_info & (MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))
4395+
|| (op2_info & (MAY_BE_UNDEF|MAY_BE_RESOURCE|MAY_BE_ARRAY|MAY_BE_OBJECT))
4396+
|| (opline->op1_type == IS_VAR
4397+
&& (op1_info & MAY_BE_UNDEF)
4398+
&& !ssa->var_info[ssa_op->op1_use].indirect_reference)))) {
43904399
goto jit_failure;
43914400
}
4401+
if (ssa_op->result_def > 0
4402+
&& (opline->opcode == ZEND_FETCH_DIM_W || opline->opcode == ZEND_FETCH_LIST_W)
4403+
&& !(op1_info & (MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))
4404+
&& !(op2_info & (MAY_BE_UNDEF|MAY_BE_RESOURCE|MAY_BE_ARRAY|MAY_BE_OBJECT))) {
4405+
ssa->var_info[ssa_op->result_def].indirect_reference = 1;
4406+
}
43924407
goto done;
43934408
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
43944409
if ((opline->extended_value & ZEND_ISEMPTY)) {
@@ -4504,7 +4519,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
45044519
if (orig_op1_type != IS_UNKNOWN
45054520
&& (orig_op1_type & IS_TRACE_INDIRECT)) {
45064521
op1_indirect = 1;
4507-
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
4522+
if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type,
4523+
&op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) {
45084524
goto jit_failure;
45094525
}
45104526
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12104,6 +12104,9 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
1210412104
}
1210512105
| SET_ZVAL_PTR res_addr, FCARG1a
1210612106
| SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT
12107+
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && prop_info) {
12108+
ssa->var_info[ssa_op->result_def].indirect_reference = 1;
12109+
}
1210712110
} else {
1210812111
zend_bool result_avoid_refcounting = 0;
1210912112

@@ -13245,19 +13248,35 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin
1324513248
return 1;
1324613249
}
1324713250

13248-
static zend_bool zend_jit_fetch_indirect_var(dasm_State **Dst, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr)
13251+
static zend_bool zend_jit_fetch_indirect_var(dasm_State **Dst, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr, zend_bool add_indirect_guard)
1324913252
{
1325013253
zend_jit_addr var_addr = *var_addr_ptr;
1325113254
uint32_t var_info = *var_info_ptr;
13252-
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
13253-
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
13255+
int32_t exit_point;
13256+
const void *exit_addr;
1325413257

13255-
if (!exit_addr) {
13256-
return 0;
13257-
}
13258+
if (add_indirect_guard) {
13259+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
13260+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
1325813261

13259-
| IF_NOT_ZVAL_TYPE var_addr, IS_INDIRECT, &exit_addr
13260-
| GET_ZVAL_PTR FCARG1a, var_addr
13262+
if (!exit_addr) {
13263+
return 0;
13264+
}
13265+
| IF_NOT_ZVAL_TYPE var_addr, IS_INDIRECT, &exit_addr
13266+
| GET_ZVAL_PTR FCARG1a, var_addr
13267+
} else {
13268+
/* May be already loaded into FCARG1a or RAX by previus FETCH_OBJ_W/DIM_W */
13269+
if (opline->op1_type != IS_VAR ||
13270+
(opline-1)->result_type != IS_VAR ||
13271+
(opline-1)->result.var != opline->op1.var ||
13272+
(opline-1)->op2_type == IS_VAR ||
13273+
(opline-1)->op2_type == IS_TMP_VAR) {
13274+
| GET_ZVAL_PTR FCARG1a, var_addr
13275+
} else if ((opline-1)->opcode == ZEND_FETCH_DIM_W || (opline-1)->opcode == ZEND_FETCH_DIM_RW) {
13276+
| mov FCARG1a, r0
13277+
}
13278+
}
13279+
*var_info_ptr &= ~MAY_BE_INDIRECT;
1326113280
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
1326213281
*var_addr_ptr = var_addr;
1326313282

0 commit comments

Comments
 (0)