Skip to content

Commit 2172142

Browse files
committed
Tracing JIT: Use recorded information about elements of arrays to generate better code for ASSIGN_DIM_OP.
1 parent 3191f83 commit 2172142

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4978,6 +4978,8 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
49784978
| bls &exit_addr
49794979
} else if (type == BP_VAR_IS && not_found_exit_addr) {
49804980
| bls &not_found_exit_addr
4981+
} else if (type == BP_VAR_RW && not_found_exit_addr) {
4982+
| bls &not_found_exit_addr
49814983
} else if (type == BP_VAR_IS && found_exit_addr) {
49824984
| bls >7 // NOT_FOUND
49834985
} else {
@@ -5100,7 +5102,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
51005102
break;
51015103
case BP_VAR_RW:
51025104
if (packed_loaded) {
5103-
| IF_NOT_Z_TYPE REG0, IS_UNDEF, >8, TMP1w
5105+
if (not_found_exit_addr) {
5106+
|.cold_code
5107+
} else {
5108+
| IF_NOT_Z_TYPE REG0, IS_UNDEF, >8, TMP1w
5109+
}
51045110
}
51055111
|2:
51065112
|4:
@@ -5112,6 +5118,17 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
51125118
| EXT_CALL zend_jit_hash_index_lookup_rw, REG0
51135119
| mov REG0, RETVALx
51145120
| cbz REG0, >9
5121+
if (not_found_exit_addr) {
5122+
if (packed_loaded) {
5123+
| cbnz REG0, >8
5124+
| b &not_found_exit_addr
5125+
|.code
5126+
} else {
5127+
| cbz REG0, &not_found_exit_addr
5128+
}
5129+
} else {
5130+
| cbz REG0, >9
5131+
}
51155132
break;
51165133
case BP_VAR_W:
51175134
if (packed_loaded) {
@@ -5921,6 +5938,8 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
59215938
static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op1_def_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t op1_data_info, zend_ssa_range *op1_data_range, uint8_t dim_type, int may_throw)
59225939
{
59235940
zend_jit_addr op2_addr, op3_addr, var_addr;
5941+
const void *not_found_exit_addr = NULL;
5942+
uint32_t var_info = MAY_BE_NULL;
59245943

59255944
ZEND_ASSERT(opline->result_type == IS_UNUSED);
59265945

@@ -5993,7 +6012,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
59936012
}
59946013

59956014
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY)) {
5996-
uint32_t var_info;
59976015
uint32_t var_def_info = zend_array_element_type(op1_def_info, opline->op1_type, 1, 0);
59986016

59996017
|6:
@@ -6022,12 +6040,25 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
60226040
var_info |= MAY_BE_RC1;
60236041
}
60246042

6025-
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, NULL, NULL)) {
6043+
if (dim_type != IS_UNKNOWN
6044+
&& dim_type != IS_UNDEF
6045+
&& (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY
6046+
&& (op2_info & (MAY_BE_LONG|MAY_BE_STRING))
6047+
&& !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING)))) {
6048+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
6049+
not_found_exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6050+
}
6051+
6052+
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, not_found_exit_addr, NULL)) {
60266053
return 0;
60276054
}
60286055

60296056
|8:
6030-
if (op1_info & (MAY_BE_ARRAY_OF_REF)) {
6057+
if (not_found_exit_addr && dim_type != IS_REFERENCE) {
6058+
| IF_NOT_Z_TYPE, REG0, dim_type, &not_found_exit_addr, TMP1w
6059+
var_info = (1 << dim_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF));
6060+
}
6061+
if (var_info & MAY_BE_REF) {
60316062
binary_op_type binary_op = get_binary_op(opline->extended_value);
60326063
| IF_NOT_Z_TYPE, REG0, IS_REFERENCE, >1, TMP1w
60336064
| GET_Z_PTR FCARG1x, REG0
@@ -6120,7 +6151,8 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
61206151
|.code
61216152
|9:
61226153
}
6123-
} else if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY)) {
6154+
} else if ((op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY))
6155+
&& (!not_found_exit_addr || (var_info & MAY_BE_REF))) {
61246156
|.cold_code
61256157
|9:
61266158
| FREE_OP (opline+1)->op1_type, (opline+1)->op1, op1_data_info, 0, opline, ZREG_TMP1, ZREG_TMP2

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5440,6 +5440,8 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
54405440
| jbe &exit_addr
54415441
} else if (type == BP_VAR_IS && not_found_exit_addr) {
54425442
| jbe &not_found_exit_addr
5443+
} else if (type == BP_VAR_RW && not_found_exit_addr) {
5444+
| jbe &not_found_exit_addr
54435445
} else if (type == BP_VAR_IS && found_exit_addr) {
54445446
| jbe >7 // NOT_FOUND
54455447
} else {
@@ -5567,7 +5569,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
55675569
break;
55685570
case BP_VAR_RW:
55695571
if (packed_loaded) {
5570-
| IF_NOT_Z_TYPE r0, IS_UNDEF, >8
5572+
if (not_found_exit_addr) {
5573+
|.cold_code
5574+
} else {
5575+
| IF_NOT_Z_TYPE r0, IS_UNDEF, >8
5576+
}
55715577
}
55725578
|2:
55735579
|4:
@@ -5578,7 +5584,17 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
55785584
| SET_EX_OPLINE opline, r0
55795585
| EXT_CALL zend_jit_hash_index_lookup_rw, r0
55805586
| test r0, r0
5581-
| jz >9
5587+
if (not_found_exit_addr) {
5588+
if (packed_loaded) {
5589+
| jnz >8
5590+
| jmp &not_found_exit_addr
5591+
|.code
5592+
} else {
5593+
| jz &not_found_exit_addr
5594+
}
5595+
} else {
5596+
| jz >9
5597+
}
55825598
break;
55835599
case BP_VAR_W:
55845600
if (packed_loaded) {
@@ -6413,6 +6429,8 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
64136429
static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op1_def_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t op1_data_info, zend_ssa_range *op1_data_range, uint8_t dim_type, int may_throw)
64146430
{
64156431
zend_jit_addr op2_addr, op3_addr, var_addr;
6432+
const void *not_found_exit_addr = NULL;
6433+
uint32_t var_info = MAY_BE_NULL;
64166434

64176435
ZEND_ASSERT(opline->result_type == IS_UNUSED);
64186436

@@ -6483,7 +6501,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
64836501
}
64846502

64856503
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY)) {
6486-
uint32_t var_info;
64876504
uint32_t var_def_info = zend_array_element_type(op1_def_info, opline->op1_type, 1, 0);
64886505

64896506
|6:
@@ -6512,12 +6529,25 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
65126529
var_info |= MAY_BE_RC1;
65136530
}
65146531

6515-
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, NULL, NULL)) {
6532+
if (dim_type != IS_UNKNOWN
6533+
&& dim_type != IS_UNDEF
6534+
&& (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY
6535+
&& (op2_info & (MAY_BE_LONG|MAY_BE_STRING))
6536+
&& !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING)))) {
6537+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
6538+
not_found_exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6539+
}
6540+
6541+
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, not_found_exit_addr, NULL)) {
65166542
return 0;
65176543
}
65186544

65196545
|8:
6520-
if (op1_info & (MAY_BE_ARRAY_OF_REF)) {
6546+
if (not_found_exit_addr && dim_type != IS_REFERENCE) {
6547+
| IF_NOT_Z_TYPE, r0, dim_type, &not_found_exit_addr
6548+
var_info = (1 << dim_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF));
6549+
}
6550+
if (var_info & MAY_BE_REF) {
65216551
binary_op_type binary_op = get_binary_op(opline->extended_value);
65226552
| IF_NOT_Z_TYPE, r0, IS_REFERENCE, >1
65236553
| GET_Z_PTR FCARG1a, r0
@@ -6627,7 +6657,8 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
66276657
|.code
66286658
|9:
66296659
}
6630-
} else if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY)) {
6660+
} else if ((op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY))
6661+
&& (!not_found_exit_addr || (var_info & MAY_BE_REF))) {
66316662
|.cold_code
66326663
|9:
66336664
| FREE_OP (opline+1)->op1_type, (opline+1)->op1, op1_data_info, 0, opline

0 commit comments

Comments
 (0)