Skip to content

Commit 36afe4e

Browse files
committed
Optimize $x === null into is_null($x)
1 parent bd45881 commit 36afe4e

File tree

6 files changed

+30
-9
lines changed

6 files changed

+30
-9
lines changed

Zend/zend_compile.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7385,8 +7385,28 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
73857385
break;
73867386
}
73877387
}
7388-
}
7389-
if (opcode == ZEND_CONCAT) {
7388+
} else if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) {
7389+
/* convert $x === null to is_null($x) (i.e. ZEND_TYPE_CHECK opcode). Do the same thing for false/true. (covers IS_NULL, IS_FALSE, and IS_TRUE) */
7390+
if (left_node.op_type == IS_CONST) {
7391+
if (Z_TYPE(left_node.u.constant) <= IS_TRUE && Z_TYPE(left_node.u.constant) >= IS_NULL) {
7392+
zend_op *opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &right_node, NULL);
7393+
opline->extended_value =
7394+
(opcode == ZEND_IS_IDENTICAL) ?
7395+
(1 << Z_TYPE(left_node.u.constant)) :
7396+
(MAY_BE_ANY - (1 << Z_TYPE(left_node.u.constant)));
7397+
return;
7398+
}
7399+
} else if (right_node.op_type == IS_CONST) {
7400+
if (Z_TYPE(right_node.u.constant) <= IS_TRUE && Z_TYPE(right_node.u.constant) >= IS_NULL) {
7401+
zend_op *opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &left_node, NULL);
7402+
opline->extended_value =
7403+
(opcode == ZEND_IS_IDENTICAL) ?
7404+
(1 << Z_TYPE(right_node.u.constant)) :
7405+
(MAY_BE_ANY - (1 << Z_TYPE(right_node.u.constant)));
7406+
return;
7407+
}
7408+
}
7409+
} else if (opcode == ZEND_CONCAT) {
73907410
/* convert constant operands to strings at compile-time */
73917411
if (left_node.op_type == IS_CONST) {
73927412
if (Z_TYPE(left_node.u.constant) == IS_ARRAY) {

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7848,7 +7848,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMPVAR|CV, ANY, TYPE_MAS
78487848
value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
78497849
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
78507850
ZEND_VM_C_LABEL(type_check_resource):
7851-
if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
7851+
if (opline->extended_value != MAY_BE_RESOURCE
78527852
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
78537853
result = 1;
78547854
}

Zend/zend_vm_execute.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4436,7 +4436,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_C
44364436
value = RT_CONSTANT(opline, opline->op1);
44374437
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
44384438
type_check_resource:
4439-
if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
4439+
if (opline->extended_value != MAY_BE_RESOURCE
44404440
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
44414441
result = 1;
44424442
}
@@ -13254,7 +13254,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TM
1325413254
value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
1325513255
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
1325613256
type_check_resource:
13257-
if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
13257+
if (opline->extended_value != MAY_BE_RESOURCE
1325813258
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
1325913259
result = 1;
1326013260
}
@@ -36407,7 +36407,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV
3640736407
value = EX_VAR(opline->op1.var);
3640836408
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
3640936409
type_check_resource:
36410-
if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
36410+
if (opline->extended_value != MAY_BE_RESOURCE
3641136411
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
3641236412
result = 1;
3641336413
}

ext/opcache/Optimizer/zend_dump.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
516516
fprintf(stderr, " (bool)");
517517
break;
518518
default:
519-
fprintf(stderr, " (\?\?\?)");
519+
fprintf(stderr, " TYPE");
520+
zend_dump_type_info(opline->extended_value, NULL, 0, dump_flags);
520521
break;
521522
}
522523
} else if (ZEND_VM_EXT_EVAL == (flags & ZEND_VM_EXT_MASK)) {

ext/opcache/Optimizer/zend_ssa.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static inline void pi_not_type_mask(zend_ssa_phi *phi, uint32_t type_mask) {
161161
}
162162
static inline uint32_t mask_for_type_check(uint32_t type) {
163163
if (type & MAY_BE_ARRAY) {
164-
return MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
164+
return type | (MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF);
165165
} else {
166166
return type;
167167
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8003,7 +8003,7 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, int b, i
80038003
zend_bool smart_branch = 0;
80048004
zend_jit_addr op1_addr = zend_jit_decode_op(op_array, opline->op1_type, opline->op1, opline, NULL, -1);
80058005

8006-
if (opline->extended_value & MAY_BE_RESOURCE) {
8006+
if (opline->extended_value == MAY_BE_RESOURCE) {
80078007
// TODO: support for is_resource() ???
80088008
goto fallback;
80098009
}

0 commit comments

Comments
 (0)