From 29dd1240f3b9a199e19f1c2e4b47cc6f44461e87 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 1 Oct 2020 22:39:58 +0300 Subject: [PATCH] Clenup BINARY_OP + SEND_VAL optimization --- ext/opcache/jit/zend_jit.c | 26 +++++------ ext/opcache/jit/zend_jit_trace.c | 19 ++++++--- ext/opcache/jit/zend_jit_x86.dasc | 71 ++++++++++--------------------- 3 files changed, 51 insertions(+), 65 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 111b5f47e9..91f1a5d458 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2034,7 +2034,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op zend_uchar smart_branch_opcode; uint32_t target_label, target_label2; uint32_t op1_info, op1_def_info, op2_info, res_info, res_use_info; - zend_bool send_result; zend_jit_addr op1_addr, op1_def_addr, op2_addr, op2_def_addr, res_addr; zend_class_entry *ce; zend_bool ce_is_instanceof; @@ -2306,11 +2305,12 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; - send_result = 1; res_use_info = -1; - res_addr = 0; /* set inside backend */ + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); + if (!zend_jit_reuse_ip(&dasm_state)) { + goto jit_failure; + } } else { - send_result = 0; res_use_info = RES_USE_INFO(); res_addr = RES_REG_ADDR(); } @@ -2318,7 +2318,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op op1_info, OP1_RANGE(), OP1_REG_ADDR(), op2_info, OP2_RANGE(), OP2_REG_ADDR(), res_use_info, RES_INFO(), res_addr, - send_result, zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; } @@ -2353,11 +2352,12 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; - send_result = 1; res_use_info = -1; - res_addr = 0; /* set inside backend */ + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); + if (!zend_jit_reuse_ip(&dasm_state)) { + goto jit_failure; + } } else { - send_result = 0; res_use_info = RES_USE_INFO(); res_addr = RES_REG_ADDR(); } @@ -2366,7 +2366,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op op1_info, OP1_REG_ADDR(), op2_info, OP2_REG_ADDR(), res_use_info, res_info, res_addr, - send_result, (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG) && (res_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, ssa_op, op_array, ssa), zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; @@ -2392,12 +2391,15 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op && (opline+1)->op1_type == IS_TMP_VAR && (opline+1)->op1.var == opline->result.var) { i++; - send_result = 1; + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); + if (!zend_jit_reuse_ip(&dasm_state)) { + goto jit_failure; + } } else { - send_result = 0; + res_addr = RES_REG_ADDR(); } if (!zend_jit_concat(&dasm_state, opline, - op1_info, op2_info, send_result, + op1_info, op2_info, res_addr, zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index caf162e44d..27ff183ba4 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3524,7 +3524,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } send_result = 1; res_use_info = -1; - res_addr = 0; /* set inside backend */ + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); + if (!zend_jit_reuse_ip(&dasm_state)) { + goto jit_failure; + } } else { send_result = 0; if (opline->result_type == IS_CV) { @@ -3543,7 +3546,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_info, OP1_RANGE(), OP1_REG_ADDR(), op2_info, OP2_RANGE(), OP2_REG_ADDR(), res_use_info, res_info, res_addr, - send_result, zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; } @@ -3595,7 +3597,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } send_result = 1; res_use_info = -1; - res_addr = 0; /* set inside backend */ + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); + if (!zend_jit_reuse_ip(&dasm_state)) { + goto jit_failure; + } } else { send_result = 0; if (opline->result_type == IS_CV) { @@ -3614,7 +3619,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_info, OP1_REG_ADDR(), op2_info, OP2_REG_ADDR(), res_use_info, res_info, res_addr, - send_result, (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG) && (res_info & (MAY_BE_DOUBLE|MAY_BE_GUARD)) && zend_may_overflow(opline, ssa_op, op_array, ssa), zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; @@ -3659,11 +3663,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par p++; } send_result = 1; + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); + if (!zend_jit_reuse_ip(&dasm_state)) { + goto jit_failure; + } } else { send_result = 0; + res_addr = RES_REG_ADDR(); } if (!zend_jit_concat(&dasm_state, opline, - op1_info, op2_info, send_result, + op1_info, op2_info, res_addr, zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index fd04435818..09143b2119 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -1656,6 +1656,16 @@ static void zend_jit_start_reuse_ip(void) reuse_ip = 1; } +static int zend_jit_reuse_ip(dasm_State **Dst) +{ + if (!reuse_ip) { + zend_jit_start_reuse_ip(); + | // call = EX(call); + | mov RX, EX->call + } + return 1; +} + static void zend_jit_stop_reuse_ip(void) { reuse_ip = 0; @@ -4709,21 +4719,12 @@ static int zend_jit_math_helper(dasm_State **Dst, return 1; } -static int zend_jit_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, zend_bool send_result, int may_overflow, int may_throw) +static int zend_jit_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, int may_overflow, int may_throw) { ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF)); ZEND_ASSERT((op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) && (op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))); - if (send_result) { - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call - } - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); - } - if (!zend_jit_math_helper(Dst, opline, opline->opcode, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, res_info, res_use_info, may_overflow, may_throw)) { return 0; } @@ -5049,20 +5050,11 @@ static int zend_jit_long_math_helper(dasm_State **Dst, return 1; } -static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_ssa_range *op1_range, zend_jit_addr op1_addr, uint32_t op2_info, zend_ssa_range *op2_range, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, zend_bool send_result, int may_throw) +static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_ssa_range *op1_range, zend_jit_addr op1_addr, uint32_t op2_info, zend_ssa_range *op2_range, zend_jit_addr op2_addr, uint32_t res_use_info, uint32_t res_info, zend_jit_addr res_addr, int may_throw) { ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF)); ZEND_ASSERT((op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG)); - if (send_result) { - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call - } - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); - } - if (!zend_jit_long_math_helper(Dst, opline, opline->opcode, opline->op1_type, opline->op1, op1_addr, op1_info, op1_range, opline->op2_type, opline->op2, op2_addr, op2_info, op2_range, @@ -5160,9 +5152,9 @@ static int zend_jit_concat_helper(dasm_State **Dst, return 1; } -static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op2_info, zend_bool send_result, int may_throw) +static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op2_info, zend_jit_addr res_addr, int may_throw) { - zend_jit_addr op1_addr, op2_addr, res_addr; + zend_jit_addr op1_addr, op2_addr; ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF)); ZEND_ASSERT((op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING)); @@ -5170,16 +5162,6 @@ static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, uint32_t op1 op1_addr = OP1_ADDR(); op2_addr = OP2_ADDR(); - if (send_result) { - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call - } - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, (opline+1)->result.var); - } else { - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); - } return zend_jit_concat_helper(Dst, opline, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr, may_throw); } @@ -10011,10 +9993,8 @@ static int zend_jit_send_val(dasm_State **Dst, const zend_op *opline, uint32_t o ZEND_ASSERT(opline->opcode == ZEND_SEND_VAL || arg_num <= MAX_ARG_FLAG_NUM); - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call + if (!zend_jit_reuse_ip(Dst)) { + return 0; } if (opline->opcode == ZEND_SEND_VAL_EX) { @@ -10093,10 +10073,8 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend op1_addr = OP1_ADDR(); arg_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, opline->result.var); - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call + if (!zend_jit_reuse_ip(Dst)) { + return 0; } if (opline->op1_type == IS_VAR) { @@ -10180,10 +10158,8 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend arg_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, opline->result.var); - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call + if (!zend_jit_reuse_ip(Dst)) { + return 0; } if (opline->opcode == ZEND_SEND_VAR_EX) { @@ -10427,11 +10403,10 @@ static int zend_jit_check_func_arg(dasm_State **Dst, const zend_op *opline) // if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { uint32_t mask = (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF) << ((arg_num + 3) * 2); - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call + if (!zend_jit_reuse_ip(Dst)) { + return 0; } + | mov r0, EX:RX->func | test dword [r0 + offsetof(zend_function, quick_arg_flags)], mask | jnz >1 -- 2.40.0