JIT: Avoid too aggressive loop unrolling

This fixes tests/func/010.phpt failure with tracing JIT on ARM64.
This commit is contained in:
Dmitry Stogov 2021-06-16 16:44:27 +03:00
parent 591dcdbdb0
commit 3a78259525
6 changed files with 78 additions and 40 deletions

View File

@ -3483,7 +3483,7 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec
}
/* }}} */
ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
ZEND_API void ZEND_FASTCALL zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
{
i_free_compiled_variables(execute_data);
}

View File

@ -359,7 +359,7 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode);
ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data);
ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table);
ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data);
ZEND_API void ZEND_FASTCALL zend_free_compiled_variables(zend_execute_data *execute_data);
ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num);
zval * ZEND_FASTCALL zend_handle_named_arg(

View File

@ -3525,18 +3525,27 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
if (!zend_jit_label(&dasm_state, jit_return_label)) {
goto jit_failure;
}
for (j = 0 ; j < op_array->last_var; j++) {
uint32_t info = zend_ssa_cv_info(op_array, ssa, j);
if (op_array->last_var > 100) {
/* To many CVs to unroll */
if (!zend_jit_free_cvs(&dasm_state)) {
goto jit_failure;
}
left_frame = 1;
}
if (!left_frame) {
for (j = 0 ; j < op_array->last_var; j++) {
uint32_t info = zend_ssa_cv_info(op_array, ssa, j);
if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
if (!left_frame) {
left_frame = 1;
if (!zend_jit_leave_frame(&dasm_state)) {
if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
if (!left_frame) {
left_frame = 1;
if (!zend_jit_leave_frame(&dasm_state)) {
goto jit_failure;
}
}
if (!zend_jit_free_cv(&dasm_state, info, j)) {
goto jit_failure;
}
}
if (!zend_jit_free_cv(&dasm_state, info, j)) {
goto jit_failure;
}
}
}
}

View File

@ -10321,6 +10321,16 @@ static int zend_jit_leave_frame(dasm_State **Dst)
return 1;
}
static int zend_jit_free_cvs(dasm_State **Dst)
{
| // EG(current_execute_data) = EX(prev_execute_data);
| ldr FCARG1x, EX->prev_execute_data
| MEM_STORE_64_ZTS str, FCARG1x, executor_globals, current_execute_data, REG0
| // zend_free_compiled_variables(execute_data);
| EXT_CALL zend_free_compiled_variables, REG0
return 1;
}
static int zend_jit_free_cv(dasm_State **Dst, uint32_t info, uint32_t var)
{
if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {

View File

@ -4883,36 +4883,45 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
op1_info, OP1_REG_ADDR())) {
goto jit_failure;
}
for (j = 0 ; j < op_array->last_var; j++) {
uint32_t info;
zend_uchar type;
info = zend_ssa_cv_info(op_array, op_array_ssa, j);
type = STACK_TYPE(stack, j);
info = zend_jit_trace_type_to_info_ex(type, info);
if (opline->op1_type == IS_CV
&& EX_VAR_TO_NUM(opline->op1.var) == j
&& !(op1_info & (MAY_BE_REF|MAY_BE_OBJECT))) {
if (JIT_G(current_frame)
&& TRACE_FRAME_IS_RETURN_VALUE_USED(JIT_G(current_frame))) {
continue;
} else {
info |= MAY_BE_NULL;
}
if (op_array->last_var > 100) {
/* To many CVs to unroll */
if (!zend_jit_free_cvs(&dasm_state)) {
goto jit_failure;
}
if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
if (!left_frame) {
left_frame = 1;
if (!zend_jit_leave_frame(&dasm_state)) {
left_frame = 1;
}
if (!left_frame) {
for (j = 0 ; j < op_array->last_var; j++) {
uint32_t info;
zend_uchar type;
info = zend_ssa_cv_info(op_array, op_array_ssa, j);
type = STACK_TYPE(stack, j);
info = zend_jit_trace_type_to_info_ex(type, info);
if (opline->op1_type == IS_CV
&& EX_VAR_TO_NUM(opline->op1.var) == j
&& !(op1_info & (MAY_BE_REF|MAY_BE_OBJECT))) {
if (JIT_G(current_frame)
&& TRACE_FRAME_IS_RETURN_VALUE_USED(JIT_G(current_frame))) {
continue;
} else {
info |= MAY_BE_NULL;
}
}
if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
if (!left_frame) {
left_frame = 1;
if (!zend_jit_leave_frame(&dasm_state)) {
goto jit_failure;
}
}
if (!zend_jit_free_cv(&dasm_state, info, j)) {
goto jit_failure;
}
}
if (!zend_jit_free_cv(&dasm_state, info, j)) {
goto jit_failure;
}
if (info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_RESOURCE)) {
if (info & MAY_BE_RC1) {
may_throw = 1;
}
if (info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_RESOURCE)) {
if (info & MAY_BE_RC1) {
may_throw = 1;
}
}
}
}

View File

@ -10931,6 +10931,16 @@ static int zend_jit_leave_frame(dasm_State **Dst)
return 1;
}
static int zend_jit_free_cvs(dasm_State **Dst)
{
| // EG(current_execute_data) = EX(prev_execute_data);
| mov FCARG1a, EX->prev_execute_data
| MEM_STORE_ZTS aword, executor_globals, current_execute_data, FCARG1a, r0
| // zend_free_compiled_variables(execute_data);
| EXT_CALL zend_free_compiled_variables, r0
return 1;
}
static int zend_jit_free_cv(dasm_State **Dst, uint32_t info, uint32_t var)
{
if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {