@@ -3778,6 +3778,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
37783778 }
37793779
37803780 TARGET (COMPARE_OP ) {
3781+ PREDICTED (COMPARE_OP );
3782+ STAT_INC (COMPARE_OP , unquickened );
37813783 assert (oparg <= Py_GE );
37823784 PyObject * right = POP ();
37833785 PyObject * left = TOP ();
@@ -3792,6 +3794,125 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
37923794 DISPATCH ();
37933795 }
37943796
3797+ TARGET (COMPARE_OP_ADAPTIVE ) {
3798+ assert (cframe .use_tracing == 0 );
3799+ SpecializedCacheEntry * cache = GET_CACHE ();
3800+ if (cache -> adaptive .counter == 0 ) {
3801+ PyObject * right = TOP ();
3802+ PyObject * left = SECOND ();
3803+ next_instr -- ;
3804+ _Py_Specialize_CompareOp (left , right , next_instr , cache );
3805+ DISPATCH ();
3806+ }
3807+ else {
3808+ STAT_INC (COMPARE_OP , deferred );
3809+ cache -> adaptive .counter -- ;
3810+ oparg = cache -> adaptive .original_oparg ;
3811+ STAT_DEC (COMPARE_OP , unquickened );
3812+ JUMP_TO_INSTRUCTION (COMPARE_OP );
3813+ }
3814+ }
3815+
3816+ TARGET (COMPARE_OP_FLOAT_JUMP ) {
3817+ assert (cframe .use_tracing == 0 );
3818+ // Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false)
3819+ SpecializedCacheEntry * caches = GET_CACHE ();
3820+ int when_to_jump_mask = caches [0 ].adaptive .index ;
3821+ PyObject * right = TOP ();
3822+ PyObject * left = SECOND ();
3823+ DEOPT_IF (!PyFloat_CheckExact (left ), COMPARE_OP );
3824+ DEOPT_IF (!PyFloat_CheckExact (right ), COMPARE_OP );
3825+ double dleft = PyFloat_AS_DOUBLE (left );
3826+ double dright = PyFloat_AS_DOUBLE (right );
3827+ int sign = (dleft > dright ) - (dleft < dright );
3828+ DEOPT_IF (isnan (dleft ), COMPARE_OP );
3829+ DEOPT_IF (isnan (dright ), COMPARE_OP );
3830+ STAT_INC (COMPARE_OP , hit );
3831+ NEXTOPARG ();
3832+ STACK_SHRINK (2 );
3833+ Py_DECREF (left );
3834+ Py_DECREF (right );
3835+ assert (opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE );
3836+ int jump = (1 << (sign + 1 )) & when_to_jump_mask ;
3837+ if (!jump ) {
3838+ next_instr ++ ;
3839+ NOTRACE_DISPATCH ();
3840+ }
3841+ else {
3842+ JUMPTO (oparg );
3843+ CHECK_EVAL_BREAKER ();
3844+ NOTRACE_DISPATCH ();
3845+ }
3846+ }
3847+
3848+ TARGET (COMPARE_OP_INT_JUMP ) {
3849+ assert (cframe .use_tracing == 0 );
3850+ // Combined: COMPARE_OP (int ? int) + POP_JUMP_IF_(true/false)
3851+ SpecializedCacheEntry * caches = GET_CACHE ();
3852+ int when_to_jump_mask = caches [0 ].adaptive .index ;
3853+ PyObject * right = TOP ();
3854+ PyObject * left = SECOND ();
3855+ DEOPT_IF (!PyLong_CheckExact (left ), COMPARE_OP );
3856+ DEOPT_IF (!PyLong_CheckExact (right ), COMPARE_OP );
3857+ DEOPT_IF ((size_t )(Py_SIZE (left ) + 1 ) > 2 , COMPARE_OP );
3858+ DEOPT_IF ((size_t )(Py_SIZE (right ) + 1 ) > 2 , COMPARE_OP );
3859+ STAT_INC (COMPARE_OP , hit );
3860+ assert (Py_ABS (Py_SIZE (left )) <= 1 && Py_ABS (Py_SIZE (right )) <= 1 );
3861+ Py_ssize_t ileft = Py_SIZE (left ) * ((PyLongObject * )left )-> ob_digit [0 ];
3862+ Py_ssize_t iright = Py_SIZE (right ) * ((PyLongObject * )right )-> ob_digit [0 ];
3863+ int sign = (ileft > iright ) - (ileft < iright );
3864+ NEXTOPARG ();
3865+ STACK_SHRINK (2 );
3866+ Py_DECREF (left );
3867+ Py_DECREF (right );
3868+ assert (opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE );
3869+ int jump = (1 << (sign + 1 )) & when_to_jump_mask ;
3870+ if (!jump ) {
3871+ next_instr ++ ;
3872+ NOTRACE_DISPATCH ();
3873+ }
3874+ else {
3875+ JUMPTO (oparg );
3876+ CHECK_EVAL_BREAKER ();
3877+ NOTRACE_DISPATCH ();
3878+ }
3879+ }
3880+
3881+ TARGET (COMPARE_OP_STR_JUMP ) {
3882+ assert (cframe .use_tracing == 0 );
3883+ // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_IF_(true/false)
3884+ SpecializedCacheEntry * caches = GET_CACHE ();
3885+ int invert = caches [0 ].adaptive .index ;
3886+ PyObject * right = TOP ();
3887+ PyObject * left = SECOND ();
3888+ DEOPT_IF (!PyUnicode_CheckExact (left ), COMPARE_OP );
3889+ DEOPT_IF (!PyUnicode_CheckExact (right ), COMPARE_OP );
3890+ STAT_INC (COMPARE_OP , hit );
3891+ int res = _PyUnicode_Equal (left , right );
3892+ if (res < 0 ) {
3893+ goto error ;
3894+ }
3895+ assert (caches [0 ].adaptive .original_oparg == Py_EQ ||
3896+ caches [0 ].adaptive .original_oparg == Py_NE );
3897+ NEXTOPARG ();
3898+ assert (opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE );
3899+ STACK_SHRINK (2 );
3900+ Py_DECREF (left );
3901+ Py_DECREF (right );
3902+ assert (res == 0 || res == 1 );
3903+ assert (invert == 0 || invert == 1 );
3904+ int jump = res ^ invert ;
3905+ if (!jump ) {
3906+ next_instr ++ ;
3907+ NOTRACE_DISPATCH ();
3908+ }
3909+ else {
3910+ JUMPTO (oparg );
3911+ CHECK_EVAL_BREAKER ();
3912+ NOTRACE_DISPATCH ();
3913+ }
3914+ }
3915+
37953916 TARGET (IS_OP ) {
37963917 PyObject * right = POP ();
37973918 PyObject * left = TOP ();
@@ -5083,6 +5204,7 @@ MISS_WITH_CACHE(LOAD_GLOBAL)
50835204MISS_WITH_CACHE (LOAD_METHOD )
50845205MISS_WITH_CACHE (CALL_FUNCTION )
50855206MISS_WITH_CACHE (BINARY_OP )
5207+ MISS_WITH_CACHE (COMPARE_OP )
50865208MISS_WITH_CACHE (BINARY_SUBSCR )
50875209MISS_WITH_OPARG_COUNTER (STORE_SUBSCR )
50885210
0 commit comments