From: Tyson Andre Date: Wed, 13 Nov 2019 06:12:49 +0000 (-0500) Subject: Optimize int === int/double === double X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e8525c2f68d938162af055fd843239778a13565d;p=php Optimize int === int/double === double Do this by reusing the implementation used for `==` when both arguments are ints (IS_LONG) or both are floats (IS_DOUBLE) ```php // Before: nestedloop_ni took 0.442 seconds // After: nestedloop_ni takes 0.401 seconds (same as nestedloop_ne) function nestedloop_ni(int $k) { $x = 0; for ($i=0; $i < 50000000; $i++) { if ($i === $k) { $x++; } } print "$x\n"; } function nestedloop_ne(int $k) { $x = 0; for ($i=0; $i < 50000000; $i++) { if ($i == $k) { $x++; } } print "$x\n"; } ``` --- diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5da5452b69..fec62d8dc0 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -59194,6 +59194,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t } break; case ZEND_IS_EQUAL: + case ZEND_IS_IDENTICAL: if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -59210,6 +59211,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t } break; case ZEND_IS_NOT_EQUAL: + case ZEND_IS_NOT_IDENTICAL: if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -59330,8 +59332,6 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t case ZEND_BW_AND: case ZEND_BW_XOR: case ZEND_BOOL_XOR: - case ZEND_IS_IDENTICAL: - case ZEND_IS_NOT_IDENTICAL: if (op->op1_type < op->op2_type) { zend_swap_operands(op); } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index d263f542c5..47975b3940 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -2818,6 +2818,13 @@ function gen_vm($def, $skel) { if (isset($dsc['type_spec'])) { $orig_op = $dsc['op']; out($f, "\t\tcase $orig_op:\n"); + // XXX: Copy the specializations for LONG == LONG and DOUBLE != DOUBLE to work for ===/!== as well. + // (Those are currently the only specializations) + if ($orig_op === 'ZEND_IS_EQUAL') { + out($f, "\t\tcase ZEND_IS_IDENTICAL:\n"); + } elseif ($orig_op === 'ZEND_IS_NOT_EQUAL') { + out($f, "\t\tcase ZEND_IS_NOT_IDENTICAL:\n"); + } if (isset($dsc["spec"]["COMMUTATIVE"])) { out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n"); out($f, "\t\t\t\tzend_swap_operands(op);\n"); @@ -2857,8 +2864,10 @@ function gen_vm($def, $skel) { !isset($dsc['type_spec']) && isset($dsc["spec"]["COMMUTATIVE"])) { $orig_op = $dsc['op']; - out($f, "\t\tcase $orig_op:\n"); - $has_commutative = true; + if (!in_array($orig_op, ['ZEND_IS_IDENTICAL', 'ZEND_IS_NOT_IDENTICAL'])) { + out($f, "\t\tcase $orig_op:\n"); + $has_commutative = true; + } } } if ($has_commutative) {