]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-100982: Break up COMPARE_AND_BRANCH (GH-102801)
authorBrandt Bucher <brandtbucher@microsoft.com>
Thu, 23 Mar 2023 22:25:09 +0000 (15:25 -0700)
committerGitHub <noreply@github.com>
Thu, 23 Mar 2023 22:25:09 +0000 (15:25 -0700)
18 files changed:
Doc/library/dis.rst
Include/internal/pycore_code.h
Include/internal/pycore_opcode.h
Include/opcode.h
Lib/importlib/_bootstrap_external.py
Lib/opcode.py
Lib/test/test_compile.py
Lib/test/test_dis.py
Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-100982.Pf_BI6.rst [new file with mode: 0644]
Objects/frameobject.c
Python/bytecodes.c
Python/compile.c
Python/generated_cases.c.h
Python/opcode_metadata.h
Python/opcode_targets.h
Python/specialize.c
Tools/c-analyzer/cpython/ignored.tsv
Tools/scripts/summarize_stats.py

index b06fe67a983aa169abfc78ec9f0d80dff63b38d3..8703cddb3448cc973ce0a442a649a706de9e759d 100644 (file)
@@ -1042,15 +1042,6 @@ iterations of the loop.
    ``cmp_op[opname]``.
 
 
-.. opcode:: COMPARE_AND_BRANCH (opname)
-
-   Compares the top two values on the stack, popping them, then branches.
-   The direction and offset of the jump is embedded as a ``POP_JUMP_IF_TRUE``
-   or ``POP_JUMP_IF_FALSE`` instruction immediately following the cache.
-
-   .. versionadded:: 3.12
-
-
 .. opcode:: IS_OP (invert)
 
    Performs ``is`` comparison, or ``is not`` if ``invert`` is 1.
index 6bd212dd42c6f27021b209aa2099e0da0f012a2c..3359dfd8a499e0580643b4d58b13c4c2351db37d 100644 (file)
@@ -234,7 +234,7 @@ extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
                                 int nargs, PyObject *kwnames);
 extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
                                     int oparg, PyObject **locals);
-extern void _Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs,
+extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
                                      _Py_CODEUNIT *instr, int oparg);
 extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr,
                                           int oparg);
index edcf4476ff3e745801b72ed39157dd036811b990..4a0b27a13ae96c78b81e6c2b39345208f49f091c 100644 (file)
@@ -51,7 +51,6 @@ const uint8_t _PyOpcode_Caches[256] = {
     [LOAD_GLOBAL] = 4,
     [BINARY_OP] = 1,
     [SEND] = 1,
-    [COMPARE_AND_BRANCH] = 1,
     [CALL] = 4,
 };
 
@@ -105,11 +104,10 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [CHECK_EG_MATCH] = CHECK_EG_MATCH,
     [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
     [CLEANUP_THROW] = CLEANUP_THROW,
-    [COMPARE_AND_BRANCH] = COMPARE_AND_BRANCH,
-    [COMPARE_AND_BRANCH_FLOAT] = COMPARE_AND_BRANCH,
-    [COMPARE_AND_BRANCH_INT] = COMPARE_AND_BRANCH,
-    [COMPARE_AND_BRANCH_STR] = COMPARE_AND_BRANCH,
     [COMPARE_OP] = COMPARE_OP,
+    [COMPARE_OP_FLOAT] = COMPARE_OP,
+    [COMPARE_OP_INT] = COMPARE_OP,
+    [COMPARE_OP_STR] = COMPARE_OP,
     [CONTAINS_OP] = CONTAINS_OP,
     [COPY] = COPY,
     [COPY_FREE_VARS] = COPY_FREE_VARS,
@@ -277,7 +275,7 @@ static const char *const _PyOpcode_OpName[263] = {
     [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
     [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
     [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
-    [COMPARE_AND_BRANCH_FLOAT] = "COMPARE_AND_BRANCH_FLOAT",
+    [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
     [WITH_EXCEPT_START] = "WITH_EXCEPT_START",
     [GET_AITER] = "GET_AITER",
     [GET_ANEXT] = "GET_ANEXT",
@@ -285,8 +283,8 @@ static const char *const _PyOpcode_OpName[263] = {
     [BEFORE_WITH] = "BEFORE_WITH",
     [END_ASYNC_FOR] = "END_ASYNC_FOR",
     [CLEANUP_THROW] = "CLEANUP_THROW",
-    [COMPARE_AND_BRANCH_INT] = "COMPARE_AND_BRANCH_INT",
-    [COMPARE_AND_BRANCH_STR] = "COMPARE_AND_BRANCH_STR",
+    [COMPARE_OP_INT] = "COMPARE_OP_INT",
+    [COMPARE_OP_STR] = "COMPARE_OP_STR",
     [FOR_ITER_LIST] = "FOR_ITER_LIST",
     [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE",
     [STORE_SUBSCR] = "STORE_SUBSCR",
@@ -370,9 +368,9 @@ static const char *const _PyOpcode_OpName[263] = {
     [STORE_DEREF] = "STORE_DEREF",
     [DELETE_DEREF] = "DELETE_DEREF",
     [JUMP_BACKWARD] = "JUMP_BACKWARD",
-    [COMPARE_AND_BRANCH] = "COMPARE_AND_BRANCH",
-    [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
     [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
+    [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
+    [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
     [EXTENDED_ARG] = "EXTENDED_ARG",
     [LIST_APPEND] = "LIST_APPEND",
     [SET_ADD] = "SET_ADD",
@@ -382,13 +380,13 @@ static const char *const _PyOpcode_OpName[263] = {
     [YIELD_VALUE] = "YIELD_VALUE",
     [RESUME] = "RESUME",
     [MATCH_CLASS] = "MATCH_CLASS",
-    [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
     [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
+    [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
     [FORMAT_VALUE] = "FORMAT_VALUE",
     [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
     [BUILD_STRING] = "BUILD_STRING",
-    [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
     [SEND_GEN] = "SEND_GEN",
+    [159] = "<159>",
     [160] = "<160>",
     [161] = "<161>",
     [LIST_EXTEND] = "LIST_EXTEND",
@@ -496,6 +494,7 @@ static const char *const _PyOpcode_OpName[263] = {
 #endif
 
 #define EXTRA_CASES \
+    case 159: \
     case 160: \
     case 161: \
     case 166: \
index 8ec10742fb7797b6a6c88c7ba2dcafa5ca671d14..0ff84dc5a551a0e5f6f5dffbb7ab16aea570c32f 100644 (file)
@@ -93,7 +93,6 @@ extern "C" {
 #define STORE_DEREF                            138
 #define DELETE_DEREF                           139
 #define JUMP_BACKWARD                          140
-#define COMPARE_AND_BRANCH                     141
 #define CALL_FUNCTION_EX                       142
 #define EXTENDED_ARG                           144
 #define LIST_APPEND                            145
@@ -153,9 +152,9 @@ extern "C" {
 #define CALL_NO_KW_STR_1                        45
 #define CALL_NO_KW_TUPLE_1                      46
 #define CALL_NO_KW_TYPE_1                       47
-#define COMPARE_AND_BRANCH_FLOAT                48
-#define COMPARE_AND_BRANCH_INT                  56
-#define COMPARE_AND_BRANCH_STR                  57
+#define COMPARE_OP_FLOAT                        48
+#define COMPARE_OP_INT                          56
+#define COMPARE_OP_STR                          57
 #define FOR_ITER_LIST                           58
 #define FOR_ITER_TUPLE                          59
 #define FOR_ITER_RANGE                          62
@@ -181,11 +180,11 @@ extern "C" {
 #define STORE_FAST__LOAD_FAST                  111
 #define STORE_FAST__STORE_FAST                 112
 #define STORE_SUBSCR_DICT                      113
-#define STORE_SUBSCR_LIST_INT                  143
-#define UNPACK_SEQUENCE_LIST                   153
-#define UNPACK_SEQUENCE_TUPLE                  154
-#define UNPACK_SEQUENCE_TWO_TUPLE              158
-#define SEND_GEN                               159
+#define STORE_SUBSCR_LIST_INT                  141
+#define UNPACK_SEQUENCE_LIST                   143
+#define UNPACK_SEQUENCE_TUPLE                  153
+#define UNPACK_SEQUENCE_TWO_TUPLE              154
+#define SEND_GEN                               158
 #define DO_TRACING                             255
 
 #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\
index 3f78300c226345b1b3c3f9297b1255ad9e7e59ac..28e55fdc8b7d10023a3115e10348b848e6a41d82 100644 (file)
@@ -435,7 +435,7 @@ _code_type = type(_write_atomic.__code__)
 #     Python 3.12a6 3519 (Modify SEND instruction)
 #     Python 3.12a6 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2)
 #     Python 3.12a7 3521 (Shrink the LOAD_GLOBAL caches)
-#     Python 3.12a7 3522 (Removed JUMP_IF_FALSE_OR_POP/JUMP_IF_TRUE_OR_POP)
+#     Python 3.12a7 3523 (Convert COMPARE_AND_BRANCH back to COMPARE_OP)
 
 #     Python 3.13 will start with 3550
 
@@ -452,7 +452,7 @@ _code_type = type(_write_atomic.__code__)
 # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
 # in PC/launcher.c must also be updated.
 
-MAGIC_NUMBER = (3522).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3523).to_bytes(2, 'little') + b'\r\n'
 
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
 
index f37d00e5014aecd2f22b42a798ce24035f246ecc..60670f571fdc4d9396bbaacbcbceb0f250b4cb91 100644 (file)
@@ -191,8 +191,6 @@ hasfree.append(138)
 def_op('DELETE_DEREF', 139)
 hasfree.append(139)
 jrel_op('JUMP_BACKWARD', 140)    # Number of words to skip (backwards)
-def_op('COMPARE_AND_BRANCH', 141)   # Comparison and jump
-hascompare.append(141)
 
 def_op('CALL_FUNCTION_EX', 142)  # Flags
 
@@ -314,10 +312,10 @@ _specializations = {
         "CALL_NO_KW_TUPLE_1",
         "CALL_NO_KW_TYPE_1",
     ],
-    "COMPARE_AND_BRANCH": [
-        "COMPARE_AND_BRANCH_FLOAT",
-        "COMPARE_AND_BRANCH_INT",
-        "COMPARE_AND_BRANCH_STR",
+    "COMPARE_OP": [
+        "COMPARE_OP_FLOAT",
+        "COMPARE_OP_INT",
+        "COMPARE_OP_STR",
     ],
     "FOR_ITER": [
         "FOR_ITER_LIST",
@@ -392,9 +390,6 @@ _cache_format = {
     "COMPARE_OP": {
         "counter": 1,
     },
-    "COMPARE_AND_BRANCH": {
-        "counter": 1,
-    },
     "BINARY_SUBSCR": {
         "counter": 1,
         "type_version": 2,
index fe775779c50f50319ed6de942980256967ea5eb1..dca38418935b7695cfdc899314b2befe06a32f38 100644 (file)
@@ -1283,7 +1283,7 @@ class TestSourcePositions(unittest.TestCase):
         self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_FALSE',
             line=2, end_line=2, column=15, end_column=16, occurrence=2)
         # compare d and 0
-        self.assertOpcodeSourcePositionIs(compiled_code, 'COMPARE_AND_BRANCH',
+        self.assertOpcodeSourcePositionIs(compiled_code, 'COMPARE_OP',
             line=4, end_line=4, column=8, end_column=13, occurrence=1)
         # jump if comparison it True
         self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE',
index fa1de1c7ded1b397f5357231a10678b38172f70c..ed66b362b0808096ffe51bc43f4f09bf1dd8034f 100644 (file)
@@ -46,7 +46,7 @@ dis_c_instance_method = """\
 
 %3d        LOAD_FAST                1 (x)
            LOAD_CONST               1 (1)
-           COMPARE_OP              32 (==)
+           COMPARE_OP              40 (==)
            LOAD_FAST                0 (self)
            STORE_ATTR               0 (x)
            RETURN_CONST             0 (None)
@@ -56,7 +56,7 @@ dis_c_instance_method_bytes = """\
        RESUME                   0
        LOAD_FAST                1
        LOAD_CONST               1
-       COMPARE_OP              32 (==)
+       COMPARE_OP              40 (==)
        LOAD_FAST                0
        STORE_ATTR               0
        RETURN_CONST             0
@@ -67,7 +67,7 @@ dis_c_class_method = """\
 
 %3d        LOAD_FAST                1 (x)
            LOAD_CONST               1 (1)
-           COMPARE_OP              32 (==)
+           COMPARE_OP              40 (==)
            LOAD_FAST                0 (cls)
            STORE_ATTR               0 (x)
            RETURN_CONST             0 (None)
@@ -78,7 +78,7 @@ dis_c_static_method = """\
 
 %3d        LOAD_FAST                0 (x)
            LOAD_CONST               1 (1)
-           COMPARE_OP              32 (==)
+           COMPARE_OP              40 (==)
            STORE_FAST               0 (x)
            RETURN_CONST             0 (None)
 """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,)
@@ -1554,12 +1554,12 @@ expected_opinfo_jumpy = [
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=54, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=56, starts_line=5, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=58, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=13, argval='<', argrepr='<', offset=60, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COMPARE_OP', opcode=107, arg=2, argval='<', argrepr='<', offset=60, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=68, argrepr='to 68', offset=64, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='JUMP_BACKWARD', opcode=140, arg=21, argval=26, argrepr='to 26', offset=66, starts_line=6, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=68, starts_line=7, is_jump_target=True, positions=None),
   Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=70, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=68, argval='>', argrepr='>', offset=72, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COMPARE_OP', opcode=107, arg=68, argval='>', argrepr='>', offset=72, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=80, argrepr='to 80', offset=76, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='JUMP_BACKWARD', opcode=140, arg=27, argval=26, argrepr='to 26', offset=78, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=80, starts_line=8, is_jump_target=True, positions=None),
@@ -1581,12 +1581,12 @@ expected_opinfo_jumpy = [
   Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=146, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=148, starts_line=14, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=150, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=75, argval='>', argrepr='>', offset=152, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COMPARE_OP', opcode=107, arg=68, argval='>', argrepr='>', offset=152, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=160, argrepr='to 160', offset=156, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='JUMP_BACKWARD', opcode=140, arg=25, argval=110, argrepr='to 110', offset=158, starts_line=15, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=160, starts_line=16, is_jump_target=True, positions=None),
   Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=162, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=13, argval='<', argrepr='<', offset=164, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COMPARE_OP', opcode=107, arg=2, argval='<', argrepr='<', offset=164, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=172, argrepr='to 172', offset=168, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='JUMP_FORWARD', opcode=110, arg=15, argval=202, argrepr='to 202', offset=170, starts_line=17, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=172, starts_line=11, is_jump_target=True, positions=None),
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-100982.Pf_BI6.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-17-12-09-45.gh-issue-100982.Pf_BI6.rst
new file mode 100644 (file)
index 0000000..31a8660
--- /dev/null
@@ -0,0 +1 @@
+Replace all occurrences of ``COMPARE_AND_BRANCH`` with :opcode:`COMPARE_OP`.
index 19bd4b10780b91c253bff20c9a8ee22e41672384..63590d58809e3e1133097be16ca2f9d6bbbad374 100644 (file)
@@ -347,14 +347,6 @@ mark_stacks(PyCodeObject *code_obj, int len)
                     assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
                     stacks[j] = next_stack;
                     break;
-                case COMPARE_AND_BRANCH:
-                    next_stack = pop_value(pop_value(next_stack));
-                    i++;
-                    j = get_arg(code, i) + i + 1;
-                    assert(j < len);
-                    assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
-                    stacks[j] = next_stack;
-                    break;
                 case GET_ITER:
                 case GET_AITER:
                     next_stack = push_value(pop_value(next_stack), Iterator);
index b5ead16d3f1bb22cebcbbe858b758752db1a7e7b..2fe85dfeedf47f395f8915c80538842820b0f592 100644 (file)
@@ -1687,75 +1687,54 @@ dummy_func(
             Py_DECREF(owner);
         }
 
-        inst(COMPARE_OP, (unused/1, left, right -- res)) {
-            STAT_INC(COMPARE_OP, deferred);
-            assert((oparg >> 4) <= Py_GE);
-            res = PyObject_RichCompare(left, right, oparg>>4);
-            DECREF_INPUTS();
-            ERROR_IF(res == NULL, error);
-        }
-
-        // No cache size here, since this is a family of super-instructions.
-        family(compare_and_branch) = {
-            COMPARE_AND_BRANCH,
-            COMPARE_AND_BRANCH_FLOAT,
-            COMPARE_AND_BRANCH_INT,
-            COMPARE_AND_BRANCH_STR,
+        family(compare_op, INLINE_CACHE_ENTRIES_COMPARE_OP) = {
+            COMPARE_OP,
+            COMPARE_OP_FLOAT,
+            COMPARE_OP_INT,
+            COMPARE_OP_STR,
         };
 
-        inst(COMPARE_AND_BRANCH, (unused/2, left, right -- )) {
+        inst(COMPARE_OP, (unused/1, left, right -- res)) {
             #if ENABLE_SPECIALIZATION
             _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
                 assert(cframe.use_tracing == 0);
                 next_instr--;
-                _Py_Specialize_CompareAndBranch(left, right, next_instr, oparg);
+                _Py_Specialize_CompareOp(left, right, next_instr, oparg);
                 DISPATCH_SAME_OPARG();
             }
-            STAT_INC(COMPARE_AND_BRANCH, deferred);
+            STAT_INC(COMPARE_OP, deferred);
             DECREMENT_ADAPTIVE_COUNTER(cache->counter);
             #endif  /* ENABLE_SPECIALIZATION */
             assert((oparg >> 4) <= Py_GE);
-            PyObject *cond = PyObject_RichCompare(left, right, oparg>>4);
+            res = PyObject_RichCompare(left, right, oparg>>4);
             DECREF_INPUTS();
-            ERROR_IF(cond == NULL, error);
-            assert(next_instr[1].op.code == POP_JUMP_IF_FALSE ||
-                   next_instr[1].op.code == POP_JUMP_IF_TRUE);
-            bool jump_on_true = next_instr[1].op.code == POP_JUMP_IF_TRUE;
-            int offset = next_instr[1].op.arg;
-            int err = PyObject_IsTrue(cond);
-            Py_DECREF(cond);
-            ERROR_IF(err < 0, error);
-            if (jump_on_true == (err != 0)) {
-                JUMPBY(offset);
-            }
+            ERROR_IF(res == NULL, error);
         }
 
-        inst(COMPARE_AND_BRANCH_FLOAT, (unused/2, left, right -- )) {
+        inst(COMPARE_OP_FLOAT, (unused/1, left, right -- res)) {
             assert(cframe.use_tracing == 0);
-            DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_AND_BRANCH);
-            STAT_INC(COMPARE_AND_BRANCH, hit);
+            DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP);
+            DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP);
+            STAT_INC(COMPARE_OP, hit);
             double dleft = PyFloat_AS_DOUBLE(left);
             double dright = PyFloat_AS_DOUBLE(right);
             // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg
             int sign_ish = COMPARISON_BIT(dleft, dright);
             _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
             _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            if (sign_ish & oparg) {
-                int offset = next_instr[1].op.arg;
-                JUMPBY(offset);
-            }
+            res = (sign_ish & oparg) ? Py_True : Py_False;
+            Py_INCREF(res);
         }
 
-        // Similar to COMPARE_AND_BRANCH_FLOAT
-        inst(COMPARE_AND_BRANCH_INT, (unused/2, left, right -- )) {
+        // Similar to COMPARE_OP_FLOAT
+        inst(COMPARE_OP_INT, (unused/1, left, right -- res)) {
             assert(cframe.use_tracing == 0);
-            DEOPT_IF(!PyLong_CheckExact(left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!PyLong_CheckExact(right), COMPARE_AND_BRANCH);
-            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_AND_BRANCH);
-            STAT_INC(COMPARE_AND_BRANCH, hit);
+            DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP);
+            DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP);
+            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP);
+            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP);
+            STAT_INC(COMPARE_OP, hit);
             assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 &&
                    _PyLong_DigitCount((PyLongObject *)right) <= 1);
             Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left);
@@ -1764,29 +1743,25 @@ dummy_func(
             int sign_ish = COMPARISON_BIT(ileft, iright);
             _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
             _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
-            if (sign_ish & oparg) {
-                int offset = next_instr[1].op.arg;
-                JUMPBY(offset);
-            }
+            res = (sign_ish & oparg) ? Py_True : Py_False;
+            Py_INCREF(res);
         }
 
-        // Similar to COMPARE_AND_BRANCH_FLOAT, but for ==, != only
-        inst(COMPARE_AND_BRANCH_STR, (unused/2, left, right -- )) {
+        // Similar to COMPARE_OP_FLOAT, but for ==, != only
+        inst(COMPARE_OP_STR, (unused/1, left, right -- res)) {
             assert(cframe.use_tracing == 0);
-            DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_AND_BRANCH);
-            STAT_INC(COMPARE_AND_BRANCH, hit);
-            int res = _PyUnicode_Equal(left, right);
+            DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
+            DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP);
+            STAT_INC(COMPARE_OP, hit);
+            int eq = _PyUnicode_Equal(left, right);
             assert((oparg >>4) == Py_EQ || (oparg >>4) == Py_NE);
             _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc);
             _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc);
-            assert(res == 0 || res == 1);
+            assert(eq == 0 || eq == 1);
             assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS);
             assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS);
-            if ((res + COMPARISON_NOT_EQUALS) & oparg) {
-                int offset = next_instr[1].op.arg;
-                JUMPBY(offset);
-            }
+            res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False;
+            Py_INCREF(res);
         }
 
         inst(IS_OP, (left, right -- b)) {
index 33cd6ca07d3bb6bd65d4985ecba9bbdc8b3d36f2..192deaa4b35f4db1facfed7c51869c1823f16ace 100644 (file)
@@ -2800,6 +2800,15 @@ check_compare(struct compiler *c, expr_ty e)
     return SUCCESS;
 }
 
+static const int compare_masks[] = {
+    [Py_LT] = COMPARISON_LESS_THAN,
+    [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS,
+    [Py_EQ] = COMPARISON_EQUALS,
+    [Py_NE] = COMPARISON_NOT_EQUALS,
+    [Py_GT] = COMPARISON_GREATER_THAN,
+    [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
+};
+
 static int compiler_addcompare(struct compiler *c, location loc,
                                cmpop_ty op)
 {
@@ -2840,7 +2849,7 @@ static int compiler_addcompare(struct compiler *c, location loc,
     }
     /* cmp goes in top bits of the oparg, while the low bits are used by quickened
      * versions of this opcode to store the comparison mask. */
-    ADDOP_I(c, loc, COMPARE_OP, cmp << 4);
+    ADDOP_I(c, loc, COMPARE_OP, (cmp << 4) | compare_masks[cmp]);
     return SUCCESS;
 }
 
index c59042dad66c1a84ddf06762374185c4fa133f9b..d793c1e23bc48ea38a601afc1973c62c34ac2842 100644 (file)
         }
 
         TARGET(COMPARE_OP) {
+            PREDICTED(COMPARE_OP);
+            static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size");
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *res;
-            #line 1691 "Python/bytecodes.c"
-            STAT_INC(COMPARE_OP, deferred);
-            assert((oparg >> 4) <= Py_GE);
-            res = PyObject_RichCompare(left, right, oparg>>4);
-            #line 2431 "Python/generated_cases.c.h"
-            Py_DECREF(left);
-            Py_DECREF(right);
-            #line 1695 "Python/bytecodes.c"
-            if (res == NULL) goto pop_2_error;
-            #line 2436 "Python/generated_cases.c.h"
-            STACK_SHRINK(1);
-            stack_pointer[-1] = res;
-            next_instr += 1;
-            DISPATCH();
-        }
-
-        TARGET(COMPARE_AND_BRANCH) {
-            PREDICTED(COMPARE_AND_BRANCH);
-            PyObject *right = stack_pointer[-1];
-            PyObject *left = stack_pointer[-2];
-            #line 1707 "Python/bytecodes.c"
+            #line 1698 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
                 assert(cframe.use_tracing == 0);
                 next_instr--;
-                _Py_Specialize_CompareAndBranch(left, right, next_instr, oparg);
+                _Py_Specialize_CompareOp(left, right, next_instr, oparg);
                 DISPATCH_SAME_OPARG();
             }
-            STAT_INC(COMPARE_AND_BRANCH, deferred);
+            STAT_INC(COMPARE_OP, deferred);
             DECREMENT_ADAPTIVE_COUNTER(cache->counter);
             #endif  /* ENABLE_SPECIALIZATION */
             assert((oparg >> 4) <= Py_GE);
-            PyObject *cond = PyObject_RichCompare(left, right, oparg>>4);
-            #line 2461 "Python/generated_cases.c.h"
+            res = PyObject_RichCompare(left, right, oparg>>4);
+            #line 2443 "Python/generated_cases.c.h"
             Py_DECREF(left);
             Py_DECREF(right);
-            #line 1721 "Python/bytecodes.c"
-            if (cond == NULL) goto pop_2_error;
-            assert(next_instr[1].op.code == POP_JUMP_IF_FALSE ||
-                   next_instr[1].op.code == POP_JUMP_IF_TRUE);
-            bool jump_on_true = next_instr[1].op.code == POP_JUMP_IF_TRUE;
-            int offset = next_instr[1].op.arg;
-            int err = PyObject_IsTrue(cond);
-            Py_DECREF(cond);
-            if (err < 0) goto pop_2_error;
-            if (jump_on_true == (err != 0)) {
-                JUMPBY(offset);
-            }
-            #line 2476 "Python/generated_cases.c.h"
-            STACK_SHRINK(2);
-            next_instr += 2;
+            #line 1712 "Python/bytecodes.c"
+            if (res == NULL) goto pop_2_error;
+            #line 2448 "Python/generated_cases.c.h"
+            STACK_SHRINK(1);
+            stack_pointer[-1] = res;
+            next_instr += 1;
             DISPATCH();
         }
 
-        TARGET(COMPARE_AND_BRANCH_FLOAT) {
+        TARGET(COMPARE_OP_FLOAT) {
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
-            #line 1735 "Python/bytecodes.c"
+            PyObject *res;
+            #line 1716 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
-            DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_AND_BRANCH);
-            STAT_INC(COMPARE_AND_BRANCH, hit);
+            DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP);
+            DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP);
+            STAT_INC(COMPARE_OP, hit);
             double dleft = PyFloat_AS_DOUBLE(left);
             double dright = PyFloat_AS_DOUBLE(right);
             // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg
             int sign_ish = COMPARISON_BIT(dleft, dright);
             _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
             _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            if (sign_ish & oparg) {
-                int offset = next_instr[1].op.arg;
-                JUMPBY(offset);
-            }
-            #line 2500 "Python/generated_cases.c.h"
-            STACK_SHRINK(2);
-            next_instr += 2;
+            res = (sign_ish & oparg) ? Py_True : Py_False;
+            Py_INCREF(res);
+            #line 2472 "Python/generated_cases.c.h"
+            STACK_SHRINK(1);
+            stack_pointer[-1] = res;
+            next_instr += 1;
             DISPATCH();
         }
 
-        TARGET(COMPARE_AND_BRANCH_INT) {
+        TARGET(COMPARE_OP_INT) {
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
-            #line 1753 "Python/bytecodes.c"
+            PyObject *res;
+            #line 1732 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
-            DEOPT_IF(!PyLong_CheckExact(left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!PyLong_CheckExact(right), COMPARE_AND_BRANCH);
-            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_AND_BRANCH);
-            STAT_INC(COMPARE_AND_BRANCH, hit);
+            DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP);
+            DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP);
+            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP);
+            DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP);
+            STAT_INC(COMPARE_OP, hit);
             assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 &&
                    _PyLong_DigitCount((PyLongObject *)right) <= 1);
             Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left);
             int sign_ish = COMPARISON_BIT(ileft, iright);
             _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
             _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
-            if (sign_ish & oparg) {
-                int offset = next_instr[1].op.arg;
-                JUMPBY(offset);
-            }
-            #line 2528 "Python/generated_cases.c.h"
-            STACK_SHRINK(2);
-            next_instr += 2;
+            res = (sign_ish & oparg) ? Py_True : Py_False;
+            Py_INCREF(res);
+            #line 2500 "Python/generated_cases.c.h"
+            STACK_SHRINK(1);
+            stack_pointer[-1] = res;
+            next_instr += 1;
             DISPATCH();
         }
 
-        TARGET(COMPARE_AND_BRANCH_STR) {
+        TARGET(COMPARE_OP_STR) {
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
-            #line 1775 "Python/bytecodes.c"
+            PyObject *res;
+            #line 1752 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
-            DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_AND_BRANCH);
-            DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_AND_BRANCH);
-            STAT_INC(COMPARE_AND_BRANCH, hit);
-            int res = _PyUnicode_Equal(left, right);
+            DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
+            DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP);
+            STAT_INC(COMPARE_OP, hit);
+            int eq = _PyUnicode_Equal(left, right);
             assert((oparg >>4) == Py_EQ || (oparg >>4) == Py_NE);
             _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc);
             _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc);
-            assert(res == 0 || res == 1);
+            assert(eq == 0 || eq == 1);
             assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS);
             assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS);
-            if ((res + COMPARISON_NOT_EQUALS) & oparg) {
-                int offset = next_instr[1].op.arg;
-                JUMPBY(offset);
-            }
-            #line 2553 "Python/generated_cases.c.h"
-            STACK_SHRINK(2);
-            next_instr += 2;
+            res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False;
+            Py_INCREF(res);
+            #line 2525 "Python/generated_cases.c.h"
+            STACK_SHRINK(1);
+            stack_pointer[-1] = res;
+            next_instr += 1;
             DISPATCH();
         }
 
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *b;
-            #line 1793 "Python/bytecodes.c"
+            #line 1768 "Python/bytecodes.c"
             int res = Py_Is(left, right) ^ oparg;
-            #line 2565 "Python/generated_cases.c.h"
+            #line 2538 "Python/generated_cases.c.h"
             Py_DECREF(left);
             Py_DECREF(right);
-            #line 1795 "Python/bytecodes.c"
+            #line 1770 "Python/bytecodes.c"
             b = Py_NewRef(res ? Py_True : Py_False);
-            #line 2570 "Python/generated_cases.c.h"
+            #line 2543 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = b;
             DISPATCH();
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *b;
-            #line 1799 "Python/bytecodes.c"
+            #line 1774 "Python/bytecodes.c"
             int res = PySequence_Contains(right, left);
-            #line 2582 "Python/generated_cases.c.h"
+            #line 2555 "Python/generated_cases.c.h"
             Py_DECREF(left);
             Py_DECREF(right);
-            #line 1801 "Python/bytecodes.c"
+            #line 1776 "Python/bytecodes.c"
             if (res < 0) goto pop_2_error;
             b = Py_NewRef((res^oparg) ? Py_True : Py_False);
-            #line 2588 "Python/generated_cases.c.h"
+            #line 2561 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = b;
             DISPATCH();
             PyObject *exc_value = stack_pointer[-2];
             PyObject *rest;
             PyObject *match;
-            #line 1806 "Python/bytecodes.c"
+            #line 1781 "Python/bytecodes.c"
             if (check_except_star_type_valid(tstate, match_type) < 0) {
-            #line 2601 "Python/generated_cases.c.h"
+            #line 2574 "Python/generated_cases.c.h"
                 Py_DECREF(exc_value);
                 Py_DECREF(match_type);
-            #line 1808 "Python/bytecodes.c"
+            #line 1783 "Python/bytecodes.c"
                 if (true) goto pop_2_error;
             }
 
             rest = NULL;
             int res = exception_group_match(exc_value, match_type,
                                             &match, &rest);
-            #line 2612 "Python/generated_cases.c.h"
+            #line 2585 "Python/generated_cases.c.h"
             Py_DECREF(exc_value);
             Py_DECREF(match_type);
-            #line 1816 "Python/bytecodes.c"
+            #line 1791 "Python/bytecodes.c"
             if (res < 0) goto pop_2_error;
 
             assert((match == NULL) == (rest == NULL));
             if (!Py_IsNone(match)) {
                 PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL);
             }
-            #line 2624 "Python/generated_cases.c.h"
+            #line 2597 "Python/generated_cases.c.h"
             stack_pointer[-1] = match;
             stack_pointer[-2] = rest;
             DISPATCH();
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *b;
-            #line 1827 "Python/bytecodes.c"
+            #line 1802 "Python/bytecodes.c"
             assert(PyExceptionInstance_Check(left));
             if (check_except_type_valid(tstate, right) < 0) {
-            #line 2637 "Python/generated_cases.c.h"
+            #line 2610 "Python/generated_cases.c.h"
                  Py_DECREF(right);
-            #line 1830 "Python/bytecodes.c"
+            #line 1805 "Python/bytecodes.c"
                  if (true) goto pop_1_error;
             }
 
             int res = PyErr_GivenExceptionMatches(left, right);
-            #line 2644 "Python/generated_cases.c.h"
+            #line 2617 "Python/generated_cases.c.h"
             Py_DECREF(right);
-            #line 1835 "Python/bytecodes.c"
+            #line 1810 "Python/bytecodes.c"
             b = Py_NewRef(res ? Py_True : Py_False);
-            #line 2648 "Python/generated_cases.c.h"
+            #line 2621 "Python/generated_cases.c.h"
             stack_pointer[-1] = b;
             DISPATCH();
         }
             PyObject *fromlist = stack_pointer[-1];
             PyObject *level = stack_pointer[-2];
             PyObject *res;
-            #line 1839 "Python/bytecodes.c"
+            #line 1814 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             res = import_name(tstate, frame, name, fromlist, level);
-            #line 2660 "Python/generated_cases.c.h"
+            #line 2633 "Python/generated_cases.c.h"
             Py_DECREF(level);
             Py_DECREF(fromlist);
-            #line 1842 "Python/bytecodes.c"
+            #line 1817 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
-            #line 2665 "Python/generated_cases.c.h"
+            #line 2638 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             DISPATCH();
         TARGET(IMPORT_FROM) {
             PyObject *from = stack_pointer[-1];
             PyObject *res;
-            #line 1846 "Python/bytecodes.c"
+            #line 1821 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             res = import_from(tstate, from, name);
             if (res == NULL) goto error;
-            #line 2678 "Python/generated_cases.c.h"
+            #line 2651 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             DISPATCH();
         }
 
         TARGET(JUMP_FORWARD) {
-            #line 1852 "Python/bytecodes.c"
+            #line 1827 "Python/bytecodes.c"
             JUMPBY(oparg);
-            #line 2687 "Python/generated_cases.c.h"
+            #line 2660 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(JUMP_BACKWARD) {
             PREDICTED(JUMP_BACKWARD);
-            #line 1856 "Python/bytecodes.c"
+            #line 1831 "Python/bytecodes.c"
             assert(oparg < INSTR_OFFSET());
             JUMPBY(-oparg);
-            #line 2696 "Python/generated_cases.c.h"
+            #line 2669 "Python/generated_cases.c.h"
             CHECK_EVAL_BREAKER();
             DISPATCH();
         }
         TARGET(POP_JUMP_IF_FALSE) {
             PREDICTED(POP_JUMP_IF_FALSE);
             PyObject *cond = stack_pointer[-1];
-            #line 1862 "Python/bytecodes.c"
+            #line 1837 "Python/bytecodes.c"
             if (Py_IsTrue(cond)) {
                 _Py_DECREF_NO_DEALLOC(cond);
             }
             }
             else {
                 int err = PyObject_IsTrue(cond);
-            #line 2714 "Python/generated_cases.c.h"
+            #line 2687 "Python/generated_cases.c.h"
                 Py_DECREF(cond);
-            #line 1872 "Python/bytecodes.c"
+            #line 1847 "Python/bytecodes.c"
                 if (err == 0) {
                     JUMPBY(oparg);
                 }
                     if (err < 0) goto pop_1_error;
                 }
             }
-            #line 2724 "Python/generated_cases.c.h"
+            #line 2697 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(POP_JUMP_IF_TRUE) {
             PyObject *cond = stack_pointer[-1];
-            #line 1882 "Python/bytecodes.c"
+            #line 1857 "Python/bytecodes.c"
             if (Py_IsFalse(cond)) {
                 _Py_DECREF_NO_DEALLOC(cond);
             }
             }
             else {
                 int err = PyObject_IsTrue(cond);
-            #line 2741 "Python/generated_cases.c.h"
+            #line 2714 "Python/generated_cases.c.h"
                 Py_DECREF(cond);
-            #line 1892 "Python/bytecodes.c"
+            #line 1867 "Python/bytecodes.c"
                 if (err > 0) {
                     JUMPBY(oparg);
                 }
                     if (err < 0) goto pop_1_error;
                 }
             }
-            #line 2751 "Python/generated_cases.c.h"
+            #line 2724 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(POP_JUMP_IF_NOT_NONE) {
             PyObject *value = stack_pointer[-1];
-            #line 1902 "Python/bytecodes.c"
+            #line 1877 "Python/bytecodes.c"
             if (!Py_IsNone(value)) {
-            #line 2760 "Python/generated_cases.c.h"
+            #line 2733 "Python/generated_cases.c.h"
                 Py_DECREF(value);
-            #line 1904 "Python/bytecodes.c"
+            #line 1879 "Python/bytecodes.c"
                 JUMPBY(oparg);
             }
             else {
                 _Py_DECREF_NO_DEALLOC(value);
             }
-            #line 2768 "Python/generated_cases.c.h"
+            #line 2741 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(POP_JUMP_IF_NONE) {
             PyObject *value = stack_pointer[-1];
-            #line 1912 "Python/bytecodes.c"
+            #line 1887 "Python/bytecodes.c"
             if (Py_IsNone(value)) {
                 _Py_DECREF_NO_DEALLOC(value);
                 JUMPBY(oparg);
             }
             else {
-            #line 2781 "Python/generated_cases.c.h"
+            #line 2754 "Python/generated_cases.c.h"
                 Py_DECREF(value);
-            #line 1918 "Python/bytecodes.c"
+            #line 1893 "Python/bytecodes.c"
             }
-            #line 2785 "Python/generated_cases.c.h"
+            #line 2758 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(JUMP_BACKWARD_NO_INTERRUPT) {
-            #line 1922 "Python/bytecodes.c"
+            #line 1897 "Python/bytecodes.c"
             /* This bytecode is used in the `yield from` or `await` loop.
              * If there is an interrupt, we want it handled in the innermost
              * generator or coroutine, so we deliberately do not check it here.
              * (see bpo-30039).
              */
             JUMPBY(-oparg);
-            #line 2798 "Python/generated_cases.c.h"
+            #line 2771 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(GET_LEN) {
             PyObject *obj = stack_pointer[-1];
             PyObject *len_o;
-            #line 1931 "Python/bytecodes.c"
+            #line 1906 "Python/bytecodes.c"
             // PUSH(len(TOS))
             Py_ssize_t len_i = PyObject_Length(obj);
             if (len_i < 0) goto error;
             len_o = PyLong_FromSsize_t(len_i);
             if (len_o == NULL) goto error;
-            #line 2811 "Python/generated_cases.c.h"
+            #line 2784 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = len_o;
             DISPATCH();
             PyObject *type = stack_pointer[-2];
             PyObject *subject = stack_pointer[-3];
             PyObject *attrs;
-            #line 1939 "Python/bytecodes.c"
+            #line 1914 "Python/bytecodes.c"
             // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
             // None on failure.
             assert(PyTuple_CheckExact(names));
             attrs = match_class(tstate, subject, type, oparg, names);
-            #line 2827 "Python/generated_cases.c.h"
+            #line 2800 "Python/generated_cases.c.h"
             Py_DECREF(subject);
             Py_DECREF(type);
             Py_DECREF(names);
-            #line 1944 "Python/bytecodes.c"
+            #line 1919 "Python/bytecodes.c"
             if (attrs) {
                 assert(PyTuple_CheckExact(attrs));  // Success!
             }
                 if (_PyErr_Occurred(tstate)) goto pop_3_error;
                 attrs = Py_NewRef(Py_None);  // Failure!
             }
-            #line 2839 "Python/generated_cases.c.h"
+            #line 2812 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             stack_pointer[-1] = attrs;
             DISPATCH();
         TARGET(MATCH_MAPPING) {
             PyObject *subject = stack_pointer[-1];
             PyObject *res;
-            #line 1954 "Python/bytecodes.c"
+            #line 1929 "Python/bytecodes.c"
             int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
             res = Py_NewRef(match ? Py_True : Py_False);
-            #line 2851 "Python/generated_cases.c.h"
+            #line 2824 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             PREDICT(POP_JUMP_IF_FALSE);
         TARGET(MATCH_SEQUENCE) {
             PyObject *subject = stack_pointer[-1];
             PyObject *res;
-            #line 1960 "Python/bytecodes.c"
+            #line 1935 "Python/bytecodes.c"
             int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
             res = Py_NewRef(match ? Py_True : Py_False);
-            #line 2864 "Python/generated_cases.c.h"
+            #line 2837 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             PREDICT(POP_JUMP_IF_FALSE);
             PyObject *keys = stack_pointer[-1];
             PyObject *subject = stack_pointer[-2];
             PyObject *values_or_none;
-            #line 1966 "Python/bytecodes.c"
+            #line 1941 "Python/bytecodes.c"
             // On successful match, PUSH(values). Otherwise, PUSH(None).
             values_or_none = match_keys(tstate, subject, keys);
             if (values_or_none == NULL) goto error;
-            #line 2879 "Python/generated_cases.c.h"
+            #line 2852 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = values_or_none;
             DISPATCH();
         TARGET(GET_ITER) {
             PyObject *iterable = stack_pointer[-1];
             PyObject *iter;
-            #line 1972 "Python/bytecodes.c"
+            #line 1947 "Python/bytecodes.c"
             /* before: [obj]; after [getiter(obj)] */
             iter = PyObject_GetIter(iterable);
-            #line 2891 "Python/generated_cases.c.h"
+            #line 2864 "Python/generated_cases.c.h"
             Py_DECREF(iterable);
-            #line 1975 "Python/bytecodes.c"
+            #line 1950 "Python/bytecodes.c"
             if (iter == NULL) goto pop_1_error;
-            #line 2895 "Python/generated_cases.c.h"
+            #line 2868 "Python/generated_cases.c.h"
             stack_pointer[-1] = iter;
             DISPATCH();
         }
         TARGET(GET_YIELD_FROM_ITER) {
             PyObject *iterable = stack_pointer[-1];
             PyObject *iter;
-            #line 1979 "Python/bytecodes.c"
+            #line 1954 "Python/bytecodes.c"
             /* before: [obj]; after [getiter(obj)] */
             if (PyCoro_CheckExact(iterable)) {
                 /* `iterable` is a coroutine */
                 if (iter == NULL) {
                     goto error;
                 }
-            #line 2926 "Python/generated_cases.c.h"
+            #line 2899 "Python/generated_cases.c.h"
                 Py_DECREF(iterable);
-            #line 2002 "Python/bytecodes.c"
+            #line 1977 "Python/bytecodes.c"
             }
-            #line 2930 "Python/generated_cases.c.h"
+            #line 2903 "Python/generated_cases.c.h"
             stack_pointer[-1] = iter;
             PREDICT(LOAD_CONST);
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2021 "Python/bytecodes.c"
+            #line 1996 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyForIterCache *cache = (_PyForIterCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
                 DISPATCH();
             }
             // Common case: no jump, leave it to the code generator
-            #line 2974 "Python/generated_cases.c.h"
+            #line 2947 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
         TARGET(FOR_ITER_LIST) {
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2056 "Python/bytecodes.c"
+            #line 2031 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
             _PyListIterObject *it = (_PyListIterObject *)iter;
             DISPATCH();
         end_for_iter_list:
             // Common case: no jump, leave it to the code generator
-            #line 3005 "Python/generated_cases.c.h"
+            #line 2978 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
         TARGET(FOR_ITER_TUPLE) {
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2079 "Python/bytecodes.c"
+            #line 2054 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             _PyTupleIterObject *it = (_PyTupleIterObject *)iter;
             DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER);
             DISPATCH();
         end_for_iter_tuple:
             // Common case: no jump, leave it to the code generator
-            #line 3036 "Python/generated_cases.c.h"
+            #line 3009 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
         TARGET(FOR_ITER_RANGE) {
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2102 "Python/bytecodes.c"
+            #line 2077 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             _PyRangeIterObject *r = (_PyRangeIterObject *)iter;
             DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
             if (next == NULL) {
                 goto error;
             }
-            #line 3065 "Python/generated_cases.c.h"
+            #line 3038 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
 
         TARGET(FOR_ITER_GEN) {
             PyObject *iter = stack_pointer[-1];
-            #line 2123 "Python/bytecodes.c"
+            #line 2098 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             PyGenObject *gen = (PyGenObject *)iter;
             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER);
             JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
             assert(next_instr->op.code == END_FOR);
             DISPATCH_INLINED(gen_frame);
-            #line 3089 "Python/generated_cases.c.h"
+            #line 3062 "Python/generated_cases.c.h"
         }
 
         TARGET(BEFORE_ASYNC_WITH) {
             PyObject *mgr = stack_pointer[-1];
             PyObject *exit;
             PyObject *res;
-            #line 2140 "Python/bytecodes.c"
+            #line 2115 "Python/bytecodes.c"
             PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__));
             if (enter == NULL) {
                 if (!_PyErr_Occurred(tstate)) {
                 Py_DECREF(enter);
                 goto error;
             }
-            #line 3119 "Python/generated_cases.c.h"
+            #line 3092 "Python/generated_cases.c.h"
             Py_DECREF(mgr);
-            #line 2163 "Python/bytecodes.c"
+            #line 2138 "Python/bytecodes.c"
             res = _PyObject_CallNoArgs(enter);
             Py_DECREF(enter);
             if (res == NULL) {
                 Py_DECREF(exit);
                 if (true) goto pop_1_error;
             }
-            #line 3128 "Python/generated_cases.c.h"
+            #line 3101 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             stack_pointer[-2] = exit;
             PyObject *mgr = stack_pointer[-1];
             PyObject *exit;
             PyObject *res;
-            #line 2173 "Python/bytecodes.c"
+            #line 2148 "Python/bytecodes.c"
             /* pop the context manager, push its __exit__ and the
              * value returned from calling its __enter__
              */
                 Py_DECREF(enter);
                 goto error;
             }
-            #line 3166 "Python/generated_cases.c.h"
+            #line 3139 "Python/generated_cases.c.h"
             Py_DECREF(mgr);
-            #line 2199 "Python/bytecodes.c"
+            #line 2174 "Python/bytecodes.c"
             res = _PyObject_CallNoArgs(enter);
             Py_DECREF(enter);
             if (res == NULL) {
                 Py_DECREF(exit);
                 if (true) goto pop_1_error;
             }
-            #line 3175 "Python/generated_cases.c.h"
+            #line 3148 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             stack_pointer[-2] = exit;
             PyObject *lasti = stack_pointer[-3];
             PyObject *exit_func = stack_pointer[-4];
             PyObject *res;
-            #line 2208 "Python/bytecodes.c"
+            #line 2183 "Python/bytecodes.c"
             /* At the top of the stack are 4 values:
                - val: TOP = exc_info()
                - unused: SECOND = previous exception
             res = PyObject_Vectorcall(exit_func, stack + 1,
                     3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
             if (res == NULL) goto error;
-            #line 3208 "Python/generated_cases.c.h"
+            #line 3181 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             DISPATCH();
         TARGET(PUSH_EXC_INFO) {
             PyObject *new_exc = stack_pointer[-1];
             PyObject *prev_exc;
-            #line 2231 "Python/bytecodes.c"
+            #line 2206 "Python/bytecodes.c"
             _PyErr_StackItem *exc_info = tstate->exc_info;
             if (exc_info->exc_value != NULL) {
                 prev_exc = exc_info->exc_value;
             }
             assert(PyExceptionInstance_Check(new_exc));
             exc_info->exc_value = Py_NewRef(new_exc);
-            #line 3227 "Python/generated_cases.c.h"
+            #line 3200 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = new_exc;
             stack_pointer[-2] = prev_exc;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint32_t keys_version = read_u32(&next_instr[3].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 2243 "Python/bytecodes.c"
+            #line 2218 "Python/bytecodes.c"
             /* Cached method object */
             assert(cframe.use_tracing == 0);
             PyTypeObject *self_cls = Py_TYPE(self);
             assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR));
             res = self;
             assert(oparg & 1);
-            #line 3259 "Python/generated_cases.c.h"
+            #line 3232 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 2263 "Python/bytecodes.c"
+            #line 2238 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             PyTypeObject *self_cls = Py_TYPE(self);
             DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
             res2 = Py_NewRef(descr);
             res = self;
             assert(oparg & 1);
-            #line 3284 "Python/generated_cases.c.h"
+            #line 3257 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 2276 "Python/bytecodes.c"
+            #line 2251 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             PyTypeObject *self_cls = Py_TYPE(self);
             DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
             res2 = Py_NewRef(descr);
             res = self;
             assert(oparg & 1);
-            #line 3313 "Python/generated_cases.c.h"
+            #line 3286 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
         }
 
         TARGET(KW_NAMES) {
-            #line 2293 "Python/bytecodes.c"
+            #line 2268 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts));
             kwnames = GETITEM(frame->f_code->co_consts, oparg);
-            #line 3326 "Python/generated_cases.c.h"
+            #line 3299 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2329 "Python/bytecodes.c"
+            #line 2304 "Python/bytecodes.c"
             int is_meth = method != NULL;
             int total_args = oparg;
             if (is_meth) {
                 Py_DECREF(args[i]);
             }
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3409 "Python/generated_cases.c.h"
+            #line 3382 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
         TARGET(CALL_BOUND_METHOD_EXACT_ARGS) {
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
-            #line 2407 "Python/bytecodes.c"
+            #line 2382 "Python/bytecodes.c"
             DEOPT_IF(method != NULL, CALL);
             DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
             STAT_INC(CALL, hit);
             PEEK(oparg + 2) = Py_NewRef(meth);  // method
             Py_DECREF(callable);
             GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS);
-            #line 3431 "Python/generated_cases.c.h"
+            #line 3404 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_PY_EXACT_ARGS) {
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             uint32_t func_version = read_u32(&next_instr[1].cache);
-            #line 2419 "Python/bytecodes.c"
+            #line 2394 "Python/bytecodes.c"
             assert(kwnames == NULL);
             DEOPT_IF(tstate->interp->eval_frame, CALL);
             int is_meth = method != NULL;
             STACK_SHRINK(oparg + 2);
             JUMPBY(INLINE_CACHE_ENTRIES_CALL);
             DISPATCH_INLINED(new_frame);
-            #line 3465 "Python/generated_cases.c.h"
+            #line 3438 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_PY_WITH_DEFAULTS) {
             PyObject *method = stack_pointer[-(2 + oparg)];
             uint32_t func_version = read_u32(&next_instr[1].cache);
             uint16_t min_args = read_u16(&next_instr[3].cache);
-            #line 2446 "Python/bytecodes.c"
+            #line 2421 "Python/bytecodes.c"
             assert(kwnames == NULL);
             DEOPT_IF(tstate->interp->eval_frame, CALL);
             int is_meth = method != NULL;
             STACK_SHRINK(oparg + 2);
             JUMPBY(INLINE_CACHE_ENTRIES_CALL);
             DISPATCH_INLINED(new_frame);
-            #line 3504 "Python/generated_cases.c.h"
+            #line 3477 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_NO_KW_TYPE_1) {
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *null = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2478 "Python/bytecodes.c"
+            #line 2453 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(cframe.use_tracing == 0);
             assert(oparg == 1);
             res = Py_NewRef(Py_TYPE(obj));
             Py_DECREF(obj);
             Py_DECREF(&PyType_Type);  // I.e., callable
-            #line 3523 "Python/generated_cases.c.h"
+            #line 3496 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *null = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2491 "Python/bytecodes.c"
+            #line 2466 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(cframe.use_tracing == 0);
             assert(oparg == 1);
             Py_DECREF(arg);
             Py_DECREF(&PyUnicode_Type);  // I.e., callable
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3548 "Python/generated_cases.c.h"
+            #line 3521 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *null = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2506 "Python/bytecodes.c"
+            #line 2481 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 1);
             DEOPT_IF(null != NULL, CALL);
             Py_DECREF(arg);
             Py_DECREF(&PyTuple_Type);  // I.e., tuple
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3573 "Python/generated_cases.c.h"
+            #line 3546 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2520 "Python/bytecodes.c"
+            #line 2495 "Python/bytecodes.c"
             int is_meth = method != NULL;
             int total_args = oparg;
             if (is_meth) {
             }
             Py_DECREF(tp);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3609 "Python/generated_cases.c.h"
+            #line 3582 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2545 "Python/bytecodes.c"
+            #line 2520 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             /* Builtin METH_O functions */
             assert(kwnames == NULL);
             Py_DECREF(arg);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3652 "Python/generated_cases.c.h"
+            #line 3625 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2577 "Python/bytecodes.c"
+            #line 2552 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             /* Builtin METH_FASTCALL functions, without keywords */
             assert(kwnames == NULL);
                    'invalid'). In those cases an exception is set, so we must
                    handle it.
                 */
-            #line 3699 "Python/generated_cases.c.h"
+            #line 3672 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2613 "Python/bytecodes.c"
+            #line 2588 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             /* Builtin METH_FASTCALL | METH_KEYWORDS functions */
             int is_meth = method != NULL;
             }
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3746 "Python/generated_cases.c.h"
+            #line 3719 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2649 "Python/bytecodes.c"
+            #line 2624 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             assert(kwnames == NULL);
             /* len(o) */
             Py_DECREF(callable);
             Py_DECREF(arg);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3786 "Python/generated_cases.c.h"
+            #line 3759 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2677 "Python/bytecodes.c"
+            #line 2652 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             assert(kwnames == NULL);
             /* isinstance(o, o2) */
             Py_DECREF(cls);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3827 "Python/generated_cases.c.h"
+            #line 3800 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject **args = (stack_pointer - oparg);
             PyObject *self = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
-            #line 2708 "Python/bytecodes.c"
+            #line 2683 "Python/bytecodes.c"
             assert(cframe.use_tracing == 0);
             assert(kwnames == NULL);
             assert(oparg == 1);
             JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1);
             assert(next_instr[-1].op.code == POP_TOP);
             DISPATCH();
-            #line 3858 "Python/generated_cases.c.h"
+            #line 3831 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) {
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2729 "Python/bytecodes.c"
+            #line 2704 "Python/bytecodes.c"
             assert(kwnames == NULL);
             int is_meth = method != NULL;
             int total_args = oparg;
             Py_DECREF(arg);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3896 "Python/generated_cases.c.h"
+            #line 3869 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2763 "Python/bytecodes.c"
+            #line 2738 "Python/bytecodes.c"
             int is_meth = method != NULL;
             int total_args = oparg;
             if (is_meth) {
             }
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3938 "Python/generated_cases.c.h"
+            #line 3911 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2795 "Python/bytecodes.c"
+            #line 2770 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 0 || oparg == 1);
             int is_meth = method != NULL;
             Py_DECREF(self);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3980 "Python/generated_cases.c.h"
+            #line 3953 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2827 "Python/bytecodes.c"
+            #line 2802 "Python/bytecodes.c"
             assert(kwnames == NULL);
             int is_meth = method != NULL;
             int total_args = oparg;
             }
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4021 "Python/generated_cases.c.h"
+            #line 3994 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))];
             PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))];
             PyObject *result;
-            #line 2858 "Python/bytecodes.c"
+            #line 2833 "Python/bytecodes.c"
             if (oparg & 1) {
                 // DICT_MERGE is called before this opcode if there are kwargs.
                 // It converts all dict subtypes in kwargs into regular dicts.
             assert(PyTuple_CheckExact(callargs));
 
             result = do_call_core(tstate, func, callargs, kwargs, cframe.use_tracing);
-            #line 4055 "Python/generated_cases.c.h"
+            #line 4028 "Python/generated_cases.c.h"
             Py_DECREF(func);
             Py_DECREF(callargs);
             Py_XDECREF(kwargs);
-            #line 2877 "Python/bytecodes.c"
+            #line 2852 "Python/bytecodes.c"
 
             assert(PEEK(3 + (oparg & 1)) == NULL);
             if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; }
-            #line 4063 "Python/generated_cases.c.h"
+            #line 4036 "Python/generated_cases.c.h"
             STACK_SHRINK(((oparg & 1) ? 1 : 0));
             STACK_SHRINK(2);
             stack_pointer[-1] = result;
             PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL;
             PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL;
             PyObject *func;
-            #line 2888 "Python/bytecodes.c"
+            #line 2863 "Python/bytecodes.c"
 
             PyFunctionObject *func_obj = (PyFunctionObject *)
                 PyFunction_New(codeobj, GLOBALS());
 
             func_obj->func_version = ((PyCodeObject *)codeobj)->co_version;
             func = (PyObject *)func_obj;
-            #line 4107 "Python/generated_cases.c.h"
+            #line 4080 "Python/generated_cases.c.h"
             STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0));
             stack_pointer[-1] = func;
             DISPATCH();
         }
 
         TARGET(RETURN_GENERATOR) {
-            #line 2919 "Python/bytecodes.c"
+            #line 2894 "Python/bytecodes.c"
             assert(PyFunction_Check(frame->f_funcobj));
             PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
             PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
             frame = cframe.current_frame = prev;
             _PyFrame_StackPush(frame, (PyObject *)gen);
             goto resume_frame;
-            #line 4135 "Python/generated_cases.c.h"
+            #line 4108 "Python/generated_cases.c.h"
         }
 
         TARGET(BUILD_SLICE) {
             PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))];
             PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))];
             PyObject *slice;
-            #line 2942 "Python/bytecodes.c"
+            #line 2917 "Python/bytecodes.c"
             slice = PySlice_New(start, stop, step);
-            #line 4145 "Python/generated_cases.c.h"
+            #line 4118 "Python/generated_cases.c.h"
             Py_DECREF(start);
             Py_DECREF(stop);
             Py_XDECREF(step);
-            #line 2944 "Python/bytecodes.c"
+            #line 2919 "Python/bytecodes.c"
             if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; }
-            #line 4151 "Python/generated_cases.c.h"
+            #line 4124 "Python/generated_cases.c.h"
             STACK_SHRINK(((oparg == 3) ? 1 : 0));
             STACK_SHRINK(1);
             stack_pointer[-1] = slice;
             PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL;
             PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))];
             PyObject *result;
-            #line 2948 "Python/bytecodes.c"
+            #line 2923 "Python/bytecodes.c"
             /* Handles f-string value formatting. */
             PyObject *(*conv_fn)(PyObject *);
             int which_conversion = oparg & FVC_MASK;
             Py_DECREF(value);
             Py_XDECREF(fmt_spec);
             if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; }
-            #line 4197 "Python/generated_cases.c.h"
+            #line 4170 "Python/generated_cases.c.h"
             STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0));
             stack_pointer[-1] = result;
             DISPATCH();
         TARGET(COPY) {
             PyObject *bottom = stack_pointer[-(1 + (oparg-1))];
             PyObject *top;
-            #line 2985 "Python/bytecodes.c"
+            #line 2960 "Python/bytecodes.c"
             assert(oparg > 0);
             top = Py_NewRef(bottom);
-            #line 4209 "Python/generated_cases.c.h"
+            #line 4182 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = top;
             DISPATCH();
             PyObject *rhs = stack_pointer[-1];
             PyObject *lhs = stack_pointer[-2];
             PyObject *res;
-            #line 2990 "Python/bytecodes.c"
+            #line 2965 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
             assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops));
             assert(binary_ops[oparg]);
             res = binary_ops[oparg](lhs, rhs);
-            #line 4237 "Python/generated_cases.c.h"
+            #line 4210 "Python/generated_cases.c.h"
             Py_DECREF(lhs);
             Py_DECREF(rhs);
-            #line 3006 "Python/bytecodes.c"
+            #line 2981 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
-            #line 4242 "Python/generated_cases.c.h"
+            #line 4215 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             next_instr += 1;
         TARGET(SWAP) {
             PyObject *top = stack_pointer[-1];
             PyObject *bottom = stack_pointer[-(2 + (oparg-2))];
-            #line 3011 "Python/bytecodes.c"
+            #line 2986 "Python/bytecodes.c"
             assert(oparg >= 2);
-            #line 4254 "Python/generated_cases.c.h"
+            #line 4227 "Python/generated_cases.c.h"
             stack_pointer[-1] = bottom;
             stack_pointer[-(2 + (oparg-2))] = top;
             DISPATCH();
         }
 
         TARGET(EXTENDED_ARG) {
-            #line 3015 "Python/bytecodes.c"
+            #line 2990 "Python/bytecodes.c"
             assert(oparg);
             assert(cframe.use_tracing == 0);
             opcode = next_instr->op.code;
             oparg = oparg << 8 | next_instr->op.arg;
             PRE_DISPATCH_GOTO();
             DISPATCH_GOTO();
-            #line 4268 "Python/generated_cases.c.h"
+            #line 4241 "Python/generated_cases.c.h"
         }
 
         TARGET(CACHE) {
-            #line 3024 "Python/bytecodes.c"
+            #line 2999 "Python/bytecodes.c"
             Py_UNREACHABLE();
-            #line 4274 "Python/generated_cases.c.h"
+            #line 4247 "Python/generated_cases.c.h"
         }
index 920b7595484d53bca2be6f04bd1bd5c4f8213155..347a84dad46351c899b4c9d0ecfed1b0492e01e5 100644 (file)
@@ -215,13 +215,11 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
             return 2;
         case COMPARE_OP:
             return 2;
-        case COMPARE_AND_BRANCH:
+        case COMPARE_OP_FLOAT:
             return 2;
-        case COMPARE_AND_BRANCH_FLOAT:
+        case COMPARE_OP_INT:
             return 2;
-        case COMPARE_AND_BRANCH_INT:
-            return 2;
-        case COMPARE_AND_BRANCH_STR:
+        case COMPARE_OP_STR:
             return 2;
         case IS_OP:
             return 2;
@@ -563,14 +561,12 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
             return 0;
         case COMPARE_OP:
             return 1;
-        case COMPARE_AND_BRANCH:
-            return 0;
-        case COMPARE_AND_BRANCH_FLOAT:
-            return 0;
-        case COMPARE_AND_BRANCH_INT:
-            return 0;
-        case COMPARE_AND_BRANCH_STR:
-            return 0;
+        case COMPARE_OP_FLOAT:
+            return 1;
+        case COMPARE_OP_INT:
+            return 1;
+        case COMPARE_OP_STR:
+            return 1;
         case IS_OP:
             return 1;
         case CONTAINS_OP:
@@ -699,7 +695,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
 }
 #endif
 
-enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC0, INSTR_FMT_IBC000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 };
+enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 };
 struct opcode_metadata {
     bool valid_entry;
     enum InstructionFormat instr_format;
@@ -812,10 +808,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = {
     [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000 },
     [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000 },
     [COMPARE_OP] = { true, INSTR_FMT_IBC },
-    [COMPARE_AND_BRANCH] = { true, INSTR_FMT_IBC0 },
-    [COMPARE_AND_BRANCH_FLOAT] = { true, INSTR_FMT_IBC0 },
-    [COMPARE_AND_BRANCH_INT] = { true, INSTR_FMT_IBC0 },
-    [COMPARE_AND_BRANCH_STR] = { true, INSTR_FMT_IBC0 },
+    [COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC },
+    [COMPARE_OP_INT] = { true, INSTR_FMT_IBC },
+    [COMPARE_OP_STR] = { true, INSTR_FMT_IBC },
     [IS_OP] = { true, INSTR_FMT_IB },
     [CONTAINS_OP] = { true, INSTR_FMT_IB },
     [CHECK_EG_MATCH] = { true, INSTR_FMT_IX },
index 52f23ce7752e5d53bc8c6c4104cdff292ddf2dbc..c502471bcd17b68d29c493802752361aaca185bd 100644 (file)
@@ -47,7 +47,7 @@ static void *opcode_targets[256] = {
     &&TARGET_CALL_NO_KW_STR_1,
     &&TARGET_CALL_NO_KW_TUPLE_1,
     &&TARGET_CALL_NO_KW_TYPE_1,
-    &&TARGET_COMPARE_AND_BRANCH_FLOAT,
+    &&TARGET_COMPARE_OP_FLOAT,
     &&TARGET_WITH_EXCEPT_START,
     &&TARGET_GET_AITER,
     &&TARGET_GET_ANEXT,
@@ -55,8 +55,8 @@ static void *opcode_targets[256] = {
     &&TARGET_BEFORE_WITH,
     &&TARGET_END_ASYNC_FOR,
     &&TARGET_CLEANUP_THROW,
-    &&TARGET_COMPARE_AND_BRANCH_INT,
-    &&TARGET_COMPARE_AND_BRANCH_STR,
+    &&TARGET_COMPARE_OP_INT,
+    &&TARGET_COMPARE_OP_STR,
     &&TARGET_FOR_ITER_LIST,
     &&TARGET_FOR_ITER_TUPLE,
     &&TARGET_STORE_SUBSCR,
@@ -140,9 +140,9 @@ static void *opcode_targets[256] = {
     &&TARGET_STORE_DEREF,
     &&TARGET_DELETE_DEREF,
     &&TARGET_JUMP_BACKWARD,
-    &&TARGET_COMPARE_AND_BRANCH,
-    &&TARGET_CALL_FUNCTION_EX,
     &&TARGET_STORE_SUBSCR_LIST_INT,
+    &&TARGET_CALL_FUNCTION_EX,
+    &&TARGET_UNPACK_SEQUENCE_LIST,
     &&TARGET_EXTENDED_ARG,
     &&TARGET_LIST_APPEND,
     &&TARGET_SET_ADD,
@@ -152,15 +152,15 @@ static void *opcode_targets[256] = {
     &&TARGET_YIELD_VALUE,
     &&TARGET_RESUME,
     &&TARGET_MATCH_CLASS,
-    &&TARGET_UNPACK_SEQUENCE_LIST,
     &&TARGET_UNPACK_SEQUENCE_TUPLE,
+    &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
     &&TARGET_FORMAT_VALUE,
     &&TARGET_BUILD_CONST_KEY_MAP,
     &&TARGET_BUILD_STRING,
-    &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
     &&TARGET_SEND_GEN,
     &&_unknown_opcode,
     &&_unknown_opcode,
+    &&_unknown_opcode,
     &&TARGET_LIST_EXTEND,
     &&TARGET_SET_UPDATE,
     &&TARGET_DICT_MERGE,
index 2e93ab193990a13831d6b17a3795f12e0c4f8a6a..dd5b22dd2346c5a57777cae606b7bc90c167cdcd 100644 (file)
@@ -264,15 +264,6 @@ do { \
 #define SPECIALIZATION_FAIL(opcode, kind) ((void)0)
 #endif
 
-static int compare_masks[] = {
-    [Py_LT] = COMPARISON_LESS_THAN,
-    [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS,
-    [Py_EQ] = COMPARISON_EQUALS,
-    [Py_NE] = COMPARISON_NOT_EQUALS,
-    [Py_GT] = COMPARISON_GREATER_THAN,
-    [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
-};
-
 // Initialize warmup counters and insert superinstructions. This cannot fail.
 void
 _PyCode_Quicken(PyCodeObject *code)
@@ -305,19 +296,6 @@ _PyCode_Quicken(PyCodeObject *code)
             case STORE_FAST << 8 | STORE_FAST:
                 instructions[i - 1].op.code = STORE_FAST__STORE_FAST;
                 break;
-            case COMPARE_OP << 8 | POP_JUMP_IF_TRUE:
-            case COMPARE_OP << 8 | POP_JUMP_IF_FALSE:
-            {
-                int oparg = instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].op.arg;
-                assert((oparg >> 4) <= Py_GE);
-                int mask = compare_masks[oparg >> 4];
-                if (opcode == POP_JUMP_IF_FALSE) {
-                    mask = mask ^ 0xf;
-                }
-                instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].op.code = COMPARE_AND_BRANCH;
-                instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].op.arg = (oparg & 0xf0) | mask;
-                break;
-            }
         }
     }
     #endif /* ENABLE_SPECIALIZATION */
@@ -436,19 +414,17 @@ _PyCode_Quicken(PyCodeObject *code)
 #define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29
 
 /* COMPARE_OP */
-#define SPEC_FAIL_COMPARE_DIFFERENT_TYPES 12
-#define SPEC_FAIL_COMPARE_STRING 13
-#define SPEC_FAIL_COMPARE_NOT_FOLLOWED_BY_COND_JUMP 14
-#define SPEC_FAIL_COMPARE_BIG_INT 15
-#define SPEC_FAIL_COMPARE_BYTES 16
-#define SPEC_FAIL_COMPARE_TUPLE 17
-#define SPEC_FAIL_COMPARE_LIST 18
-#define SPEC_FAIL_COMPARE_SET 19
-#define SPEC_FAIL_COMPARE_BOOL 20
-#define SPEC_FAIL_COMPARE_BASEOBJECT 21
-#define SPEC_FAIL_COMPARE_FLOAT_LONG 22
-#define SPEC_FAIL_COMPARE_LONG_FLOAT 23
-#define SPEC_FAIL_COMPARE_EXTENDED_ARG 24
+#define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12
+#define SPEC_FAIL_COMPARE_OP_STRING 13
+#define SPEC_FAIL_COMPARE_OP_BIG_INT 14
+#define SPEC_FAIL_COMPARE_OP_BYTES 15
+#define SPEC_FAIL_COMPARE_OP_TUPLE 16
+#define SPEC_FAIL_COMPARE_OP_LIST 17
+#define SPEC_FAIL_COMPARE_OP_SET 18
+#define SPEC_FAIL_COMPARE_OP_BOOL 19
+#define SPEC_FAIL_COMPARE_OP_BASEOBJECT 20
+#define SPEC_FAIL_COMPARE_OP_FLOAT_LONG 21
+#define SPEC_FAIL_COMPARE_OP_LONG_FLOAT 22
 
 /* FOR_ITER */
 #define SPEC_FAIL_FOR_ITER_GENERATOR 10
@@ -1958,83 +1934,79 @@ compare_op_fail_kind(PyObject *lhs, PyObject *rhs)
 {
     if (Py_TYPE(lhs) != Py_TYPE(rhs)) {
         if (PyFloat_CheckExact(lhs) && PyLong_CheckExact(rhs)) {
-            return SPEC_FAIL_COMPARE_FLOAT_LONG;
+            return SPEC_FAIL_COMPARE_OP_FLOAT_LONG;
         }
         if (PyLong_CheckExact(lhs) && PyFloat_CheckExact(rhs)) {
-            return SPEC_FAIL_COMPARE_LONG_FLOAT;
+            return SPEC_FAIL_COMPARE_OP_LONG_FLOAT;
         }
-        return SPEC_FAIL_COMPARE_DIFFERENT_TYPES;
+        return SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES;
     }
     if (PyBytes_CheckExact(lhs)) {
-        return SPEC_FAIL_COMPARE_BYTES;
+        return SPEC_FAIL_COMPARE_OP_BYTES;
     }
     if (PyTuple_CheckExact(lhs)) {
-        return SPEC_FAIL_COMPARE_TUPLE;
+        return SPEC_FAIL_COMPARE_OP_TUPLE;
     }
     if (PyList_CheckExact(lhs)) {
-        return SPEC_FAIL_COMPARE_LIST;
+        return SPEC_FAIL_COMPARE_OP_LIST;
     }
     if (PySet_CheckExact(lhs) || PyFrozenSet_CheckExact(lhs)) {
-        return SPEC_FAIL_COMPARE_SET;
+        return SPEC_FAIL_COMPARE_OP_SET;
     }
     if (PyBool_Check(lhs)) {
-        return SPEC_FAIL_COMPARE_BOOL;
+        return SPEC_FAIL_COMPARE_OP_BOOL;
     }
     if (Py_TYPE(lhs)->tp_richcompare == PyBaseObject_Type.tp_richcompare) {
-        return SPEC_FAIL_COMPARE_BASEOBJECT;
+        return SPEC_FAIL_COMPARE_OP_BASEOBJECT;
     }
     return SPEC_FAIL_OTHER;
 }
 #endif
 
 void
-_Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
+_Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
                          int oparg)
 {
     assert(ENABLE_SPECIALIZATION);
-    assert(_PyOpcode_Caches[COMPARE_AND_BRANCH] == INLINE_CACHE_ENTRIES_COMPARE_OP);
+    assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP);
     _PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1);
-#ifndef NDEBUG
-    int next_opcode = instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1].op.code;
-    assert(next_opcode == POP_JUMP_IF_FALSE || next_opcode == POP_JUMP_IF_TRUE);
-#endif
     if (Py_TYPE(lhs) != Py_TYPE(rhs)) {
-        SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, compare_op_fail_kind(lhs, rhs));
+        SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
         goto failure;
     }
     if (PyFloat_CheckExact(lhs)) {
-        instr->op.code = COMPARE_AND_BRANCH_FLOAT;
+        instr->op.code = COMPARE_OP_FLOAT;
         goto success;
     }
     if (PyLong_CheckExact(lhs)) {
         if (_PyLong_IsCompact((PyLongObject *)lhs) && _PyLong_IsCompact((PyLongObject *)rhs)) {
-            instr->op.code = COMPARE_AND_BRANCH_INT;
+            instr->op.code = COMPARE_OP_INT;
             goto success;
         }
         else {
-            SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, SPEC_FAIL_COMPARE_BIG_INT);
+            SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_BIG_INT);
             goto failure;
         }
     }
     if (PyUnicode_CheckExact(lhs)) {
         int cmp = oparg >> 4;
         if (cmp != Py_EQ && cmp != Py_NE) {
-            SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, SPEC_FAIL_COMPARE_STRING);
+            SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_STRING);
             goto failure;
         }
         else {
-            instr->op.code = COMPARE_AND_BRANCH_STR;
+            instr->op.code = COMPARE_OP_STR;
             goto success;
         }
     }
-    SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, compare_op_fail_kind(lhs, rhs));
+    SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
 failure:
-    STAT_INC(COMPARE_AND_BRANCH, failure);
-    instr->op.code = COMPARE_AND_BRANCH;
+    STAT_INC(COMPARE_OP, failure);
+    instr->op.code = COMPARE_OP;
     cache->counter = adaptive_counter_backoff(cache->counter);
     return;
 success:
-    STAT_INC(COMPARE_AND_BRANCH, success);
+    STAT_INC(COMPARE_OP, success);
     cache->counter = adaptive_counter_cooldown();
 }
 
index 14fc32a07b4309b7b5c92f0ee1d9eab074eb8a7a..9203c1888149fb5a8674ad770f38df36e6e44530 100644 (file)
@@ -350,7 +350,6 @@ Python/pylifecycle.c        -       INTERPRETER_TRAMPOLINE_CODEDEF  -
 Python/pystate.c       -       initial -
 Python/specialize.c    -       adaptive_opcodes        -
 Python/specialize.c    -       cache_requirements      -
-Python/specialize.c    -       compare_masks   -
 Python/stdlib_module_names.h   -       _Py_stdlib_module_names -
 Python/sysmodule.c     -       _PySys_ImplCacheTag     -
 Python/sysmodule.c     -       _PySys_ImplName -
index 7789c4d3a17d38ff8e15c0972c3c6db43058b1d9..ce25374f3a9a52a93cd2c5635786b3241b34ceb9 100644 (file)
@@ -228,8 +228,6 @@ def kind_to_text(kind, defines, opname):
         return pretty(defines[kind][0])
     if opname.endswith("ATTR"):
         opname = "ATTR"
-    if opname in ("COMPARE_OP", "COMPARE_AND_BRANCH"):
-        opname = "COMPARE"
     if opname.endswith("SUBSCR"):
         opname = "SUBSCR"
     for name in defines[kind]: