@@ -3778,6 +3778,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
3778
3778
}
3779
3779
3780
3780
TARGET (COMPARE_OP ) {
3781
+ PREDICTED (COMPARE_OP );
3782
+ STAT_INC (COMPARE_OP , unquickened );
3781
3783
assert (oparg <= Py_GE );
3782
3784
PyObject * right = POP ();
3783
3785
PyObject * left = TOP ();
@@ -3792,6 +3794,125 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
3792
3794
DISPATCH ();
3793
3795
}
3794
3796
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
+
3795
3916
TARGET (IS_OP ) {
3796
3917
PyObject * right = POP ();
3797
3918
PyObject * left = TOP ();
@@ -5083,6 +5204,7 @@ MISS_WITH_CACHE(LOAD_GLOBAL)
5083
5204
MISS_WITH_CACHE (LOAD_METHOD )
5084
5205
MISS_WITH_CACHE (CALL_FUNCTION )
5085
5206
MISS_WITH_CACHE (BINARY_OP )
5207
+ MISS_WITH_CACHE (COMPARE_OP )
5086
5208
MISS_WITH_CACHE (BINARY_SUBSCR )
5087
5209
MISS_WITH_OPARG_COUNTER (STORE_SUBSCR )
5088
5210
0 commit comments