Skip to content

Commit

Permalink
JIT for ZEND_ISSET_ISEMPTY_CV
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Aug 17, 2020
1 parent 28e24e7 commit afc93e4
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
27 changes: 27 additions & 0 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -2790,6 +2790,33 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
goto jit_failure;
}
goto done;
case ZEND_ISSET_ISEMPTY_CV:
if ((opline->extended_value & ZEND_ISEMPTY)) {
// TODO: support for empty() ???
break;
}
if ((opline->result_type & IS_TMP_VAR)
&& (i + 1) <= end
&& ((opline+1)->opcode == ZEND_JMPZ
|| (opline+1)->opcode == ZEND_JMPNZ
|| (opline+1)->opcode == ZEND_JMPZNZ)
&& (opline+1)->op1_type == IS_TMP_VAR
&& (opline+1)->op1.var == opline->result.var) {
i++;
smart_branch_opcode = (opline+1)->opcode;
target_label = ssa->cfg.blocks[b].successors[0];
target_label2 = ssa->cfg.blocks[b].successors[1];
} else {
smart_branch_opcode = 0;
target_label = target_label2 = (uint32_t)-1;
}
if (!zend_jit_isset_isempty_cv(&dasm_state, opline, op_array,
OP1_INFO(), OP1_REG_ADDR(),
smart_branch_opcode, target_label, target_label2,
NULL)) {
goto jit_failure;
}
goto done;
case ZEND_FETCH_DIM_R:
case ZEND_FETCH_DIM_IS:
if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) {
Expand Down
36 changes: 36 additions & 0 deletions ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
case ZEND_JMPNZ_EX:
case ZEND_BOOL:
case ZEND_BOOL_NOT:
case ZEND_ISSET_ISEMPTY_CV:
ADD_OP1_TRACE_GUARD();
break;
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
Expand Down Expand Up @@ -3912,6 +3913,41 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
goto jit_failure;
}
goto done;
case ZEND_ISSET_ISEMPTY_CV:
if ((opline->extended_value & ZEND_ISEMPTY)) {
// TODO: support for empty() ???
break;
}
op1_info = OP1_INFO();
op1_addr = OP1_REG_ADDR();
if (orig_op1_type != IS_UNKNOWN
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
goto jit_failure;
}
} else {
CHECK_OP1_TRACE_TYPE();
}
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {
zend_bool exit_if_true = 0;
const zend_op *exit_opline = zend_jit_trace_get_exit_opline(p + 1, opline + 1, &exit_if_true);
uint32_t exit_point = zend_jit_trace_get_exit_point(opline, exit_opline, p + 1, 0);

exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
goto jit_failure;
}
smart_branch_opcode = exit_if_true ? ZEND_JMPNZ : ZEND_JMPZ;
} else {
smart_branch_opcode = 0;
exit_addr = NULL;
}
if (!zend_jit_isset_isempty_cv(&dasm_state, opline, op_array,
op1_info, op1_addr,
smart_branch_opcode, -1, -1, exit_addr)) {
goto jit_failure;
}
goto done;
case ZEND_FETCH_DIM_FUNC_ARG:
if (!JIT_G(current_frame)
|| !JIT_G(current_frame)->call
Expand Down
69 changes: 69 additions & 0 deletions ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -12159,6 +12159,75 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op
return 1;
}

static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_jit_addr op1_addr, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
{
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);

// TODO: support for empty() ???
ZEND_ASSERT(!(opline->extended_value & ZEND_ISEMPTY));

if (op1_info & MAY_BE_REF) {
if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) {
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
}
| ZVAL_DEREF FCARG1a, op1_info
|1:
}

if (!(op1_info & (MAY_BE_UNDEF|MAY_BE_NULL))) {
if (exit_addr) {
ZEND_ASSERT(smart_branch_opcode == ZEND_JMPZ);
} else if (smart_branch_opcode) {
if (smart_branch_opcode == ZEND_JMPNZ) {
| jmp =>target_label
} else if (smart_branch_opcode == ZEND_JMPZNZ) {
| jmp =>target_label2
}
} else {
| SET_ZVAL_TYPE_INFO res_addr, IS_TRUE
}
} else if (!(op1_info & (MAY_BE_ANY - MAY_BE_NULL))) {
if (exit_addr) {
ZEND_ASSERT(smart_branch_opcode == ZEND_JMPNZ);
} else if (smart_branch_opcode) {
if (smart_branch_opcode != ZEND_JMPNZ) {
| jmp =>target_label
}
} else {
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
}
} else {
ZEND_ASSERT(Z_MODE(op1_addr) == IS_MEM_ZVAL);
| cmp byte [Ra(Z_REG(op1_addr))+Z_OFFSET(op1_addr)+offsetof(zval, u1.v.type)], IS_NULL
if (exit_addr) {
if (smart_branch_opcode == ZEND_JMPNZ) {
| jg &exit_addr
} else {
| jle &exit_addr
}
} else if (smart_branch_opcode) {
if (smart_branch_opcode == ZEND_JMPZ) {
| jle =>target_label
} else if (smart_branch_opcode == ZEND_JMPNZ) {
| jg =>target_label
} else if (smart_branch_opcode == ZEND_JMPZNZ) {
| jle =>target_label
| jmp =>target_label2
} else {
ZEND_UNREACHABLE();
}
} else {
| setg al
| movzx eax, al
| lea eax, [eax + IS_FALSE]
| SET_ZVAL_TYPE_INFO res_addr, eax
}
}

return 1;
}

static zend_bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr)
{
int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, 0);
Expand Down

0 comments on commit afc93e4

Please sign in to comment.