]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-111485: Generate instruction and uop metadata (GH-113287)
authorMark Shannon <mark@hotpy.org>
Wed, 20 Dec 2023 14:27:25 +0000 (14:27 +0000)
committerGitHub <noreply@github.com>
Wed, 20 Dec 2023 14:27:25 +0000 (14:27 +0000)
27 files changed:
Include/internal/pycore_opcode_metadata.h
Include/internal/pycore_uop_ids.h
Include/internal/pycore_uop_metadata.h [new file with mode: 0644]
Include/opcode_ids.h
Lib/_opcode_metadata.py
Lib/test/test_capi/test_opt.py
Makefile.pre.in
Python/assemble.c
Python/bytecodes.c
Python/ceval.c
Python/compile.c
Python/flowgraph.c
Python/generated_cases.c.h
Python/optimizer.c
Python/specialize.c
Tools/cases_generator/analyzer.py
Tools/cases_generator/cwriter.py
Tools/cases_generator/generate_cases.py
Tools/cases_generator/generators_common.py
Tools/cases_generator/opcode_id_generator.py
Tools/cases_generator/opcode_metadata_generator.py [new file with mode: 0644]
Tools/cases_generator/py_metadata_generator.py [new file with mode: 0644]
Tools/cases_generator/stack.py
Tools/cases_generator/tier1_generator.py
Tools/cases_generator/tier2_generator.py
Tools/cases_generator/uop_id_generator.py
Tools/cases_generator/uop_metadata_generator.py [new file with mode: 0644]

index 36b6cd52d2b272d9879a0d3771e5e7aeb88f4266..a9e0cd1238929fc3f27fe7f1492b506e00a8bf33 100644 (file)
@@ -1,13 +1,20 @@
-// This file is generated by Tools/cases_generator/generate_cases.py
+// This file is generated by Tools/cases_generator/opcode_metadata_generator.py
 // from:
 //   Python/bytecodes.c
 // Do not edit!
 
+#ifndef Py_CORE_OPCODE_METADATA_H
+#define Py_CORE_OPCODE_METADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef Py_BUILD_CORE
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
 #include <stdbool.h>              // bool
+#include "opcode_ids.h"
 
 
 #define IS_PSEUDO_INSTR(OP)  ( \
     0)
 
 #include "pycore_uop_ids.h"
-
-extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump);
+extern int _PyOpcode_num_popped(int opcode, int oparg);
 #ifdef NEED_OPCODE_METADATA
-int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
+int _PyOpcode_num_popped(int opcode, int oparg)  {
     switch(opcode) {
         case BEFORE_ASYNC_WITH:
             return 1;
@@ -68,7 +74,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case BINARY_SUBSCR_TUPLE_INT:
             return 2;
         case BUILD_CONST_KEY_MAP:
-            return oparg + 1;
+            return 1 + oparg;
         case BUILD_LIST:
             return oparg;
         case BUILD_MAP:
@@ -76,7 +82,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case BUILD_SET:
             return oparg;
         case BUILD_SLICE:
-            return ((oparg == 3) ? 1 : 0) + 2;
+            return 2 + (((oparg == 3) ? 1 : 0));
         case BUILD_STRING:
             return oparg;
         case BUILD_TUPLE:
@@ -84,51 +90,51 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case CACHE:
             return 0;
         case CALL:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_ALLOC_AND_ENTER_INIT:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_BOUND_METHOD_EXACT_ARGS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_BUILTIN_CLASS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_BUILTIN_FAST:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_BUILTIN_FAST_WITH_KEYWORDS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_BUILTIN_O:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_FUNCTION_EX:
-            return ((oparg & 1) ? 1 : 0) + 3;
+            return 3 + ((oparg & 1));
         case CALL_INTRINSIC_1:
             return 1;
         case CALL_INTRINSIC_2:
             return 2;
         case CALL_ISINSTANCE:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_KW:
-            return oparg + 3;
+            return 3 + oparg;
         case CALL_LEN:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_LIST_APPEND:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_METHOD_DESCRIPTOR_FAST:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_METHOD_DESCRIPTOR_NOARGS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_METHOD_DESCRIPTOR_O:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_PY_EXACT_ARGS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_PY_WITH_DEFAULTS:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_STR_1:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_TUPLE_1:
-            return oparg + 2;
+            return 2 + oparg;
         case CALL_TYPE_1:
-            return oparg + 2;
+            return 2 + oparg;
         case CHECK_EG_MATCH:
             return 2;
         case CHECK_EXC_MATCH:
@@ -148,7 +154,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case CONVERT_VALUE:
             return 1;
         case COPY:
-            return (oparg-1) + 1;
+            return 1 + (oparg-1);
         case COPY_FREE_VARS:
             return 0;
         case DELETE_ATTR:
@@ -164,9 +170,9 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case DELETE_SUBSCR:
             return 2;
         case DICT_MERGE:
-            return (oparg - 1) + 5;
+            return 5 + (oparg - 1);
         case DICT_UPDATE:
-            return (oparg - 1) + 2;
+            return 2 + (oparg - 1);
         case END_ASYNC_FOR:
             return 2;
         case END_FOR:
@@ -249,20 +255,16 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 1;
         case IS_OP:
             return 2;
-        case JUMP:
-            return 0;
         case JUMP_BACKWARD:
             return 0;
         case JUMP_BACKWARD_NO_INTERRUPT:
             return 0;
         case JUMP_FORWARD:
             return 0;
-        case JUMP_NO_INTERRUPT:
-            return 0;
         case LIST_APPEND:
-            return (oparg-1) + 2;
+            return 2 + (oparg-1);
         case LIST_EXTEND:
-            return (oparg-1) + 2;
+            return 2 + (oparg-1);
         case LOAD_ASSERTION_ERROR:
             return 0;
         case LOAD_ATTR:
@@ -293,8 +295,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 1;
         case LOAD_BUILD_CLASS:
             return 0;
-        case LOAD_CLOSURE:
-            return 0;
         case LOAD_CONST:
             return 0;
         case LOAD_DEREF:
@@ -319,8 +319,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 0;
         case LOAD_LOCALS:
             return 0;
-        case LOAD_METHOD:
-            return 1;
         case LOAD_NAME:
             return 0;
         case LOAD_SUPER_ATTR:
@@ -329,18 +327,12 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 3;
         case LOAD_SUPER_ATTR_METHOD:
             return 3;
-        case LOAD_SUPER_METHOD:
-            return 3;
-        case LOAD_ZERO_SUPER_ATTR:
-            return 3;
-        case LOAD_ZERO_SUPER_METHOD:
-            return 3;
         case MAKE_CELL:
             return 0;
         case MAKE_FUNCTION:
             return 1;
         case MAP_ADD:
-            return (oparg - 1) + 3;
+            return 3 + (oparg - 1);
         case MATCH_CLASS:
             return 3;
         case MATCH_KEYS:
@@ -351,8 +343,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 1;
         case NOP:
             return 0;
-        case POP_BLOCK:
-            return 0;
         case POP_EXCEPT:
             return 1;
         case POP_JUMP_IF_FALSE:
@@ -372,7 +362,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case RAISE_VARARGS:
             return oparg;
         case RERAISE:
-            return oparg + 1;
+            return 1 + oparg;
         case RESERVED:
             return 0;
         case RESUME:
@@ -391,18 +381,12 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 2;
         case SETUP_ANNOTATIONS:
             return 0;
-        case SETUP_CLEANUP:
-            return 0;
-        case SETUP_FINALLY:
-            return 0;
-        case SETUP_WITH:
-            return 0;
         case SET_ADD:
-            return (oparg-1) + 2;
+            return 2 + (oparg-1);
         case SET_FUNCTION_ATTRIBUTE:
             return 2;
         case SET_UPDATE:
-            return (oparg-1) + 2;
+            return 2 + (oparg-1);
         case STORE_ATTR:
             return 2;
         case STORE_ATTR_INSTANCE_VALUE:
@@ -417,8 +401,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 1;
         case STORE_FAST_LOAD_FAST:
             return 1;
-        case STORE_FAST_MAYBE_NULL:
-            return 1;
         case STORE_FAST_STORE_FAST:
             return 2;
         case STORE_GLOBAL:
@@ -434,7 +416,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
         case STORE_SUBSCR_LIST_INT:
             return 3;
         case SWAP:
-            return (oparg-2) + 2;
+            return 2 + (oparg-2);
         case TO_BOOL:
             return 1;
         case TO_BOOL_ALWAYS_TRUE:
@@ -469,207 +451,16 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump)  {
             return 4;
         case YIELD_VALUE:
             return 1;
-        case _BINARY_OP:
-            return 2;
-        case _BINARY_OP_ADD_FLOAT:
-            return 2;
-        case _BINARY_OP_ADD_INT:
-            return 2;
-        case _BINARY_OP_ADD_UNICODE:
-            return 2;
-        case _BINARY_OP_INPLACE_ADD_UNICODE:
-            return 2;
-        case _BINARY_OP_MULTIPLY_FLOAT:
-            return 2;
-        case _BINARY_OP_MULTIPLY_INT:
-            return 2;
-        case _BINARY_OP_SUBTRACT_FLOAT:
-            return 2;
-        case _BINARY_OP_SUBTRACT_INT:
-            return 2;
-        case _BINARY_SUBSCR:
-            return 2;
-        case _CALL:
-            return oparg + 2;
-        case _CHECK_ATTR_CLASS:
-            return 1;
-        case _CHECK_ATTR_METHOD_LAZY_DICT:
-            return 1;
-        case _CHECK_ATTR_MODULE:
-            return 1;
-        case _CHECK_ATTR_WITH_HINT:
-            return 1;
-        case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
-            return oparg + 2;
-        case _CHECK_FUNCTION_EXACT_ARGS:
-            return oparg + 2;
-        case _CHECK_MANAGED_OBJECT_HAS_VALUES:
-            return 1;
-        case _CHECK_PEP_523:
-            return 0;
-        case _CHECK_STACK_SPACE:
-            return oparg + 2;
-        case _CHECK_VALIDITY:
-            return 0;
-        case _COMPARE_OP:
-            return 2;
-        case _EXIT_TRACE:
-            return 0;
-        case _FOR_ITER:
-            return 1;
-        case _FOR_ITER_TIER_TWO:
-            return 1;
-        case _GUARD_BOTH_FLOAT:
-            return 2;
-        case _GUARD_BOTH_INT:
-            return 2;
-        case _GUARD_BOTH_UNICODE:
-            return 2;
-        case _GUARD_BUILTINS_VERSION:
-            return 0;
-        case _GUARD_DORV_VALUES:
-            return 1;
-        case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT:
-            return 1;
-        case _GUARD_GLOBALS_VERSION:
-            return 0;
-        case _GUARD_IS_FALSE_POP:
-            return 1;
-        case _GUARD_IS_NONE_POP:
-            return 1;
-        case _GUARD_IS_NOT_NONE_POP:
-            return 1;
-        case _GUARD_IS_TRUE_POP:
-            return 1;
-        case _GUARD_KEYS_VERSION:
-            return 1;
-        case _GUARD_NOT_EXHAUSTED_LIST:
-            return 1;
-        case _GUARD_NOT_EXHAUSTED_RANGE:
-            return 1;
-        case _GUARD_NOT_EXHAUSTED_TUPLE:
-            return 1;
-        case _GUARD_TYPE_VERSION:
-            return 1;
-        case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
-            return oparg + 2;
-        case _INIT_CALL_PY_EXACT_ARGS:
-            return oparg + 2;
-        case _INSERT:
-            return oparg + 1;
-        case _IS_NONE:
-            return 1;
-        case _ITER_CHECK_LIST:
-            return 1;
-        case _ITER_CHECK_RANGE:
-            return 1;
-        case _ITER_CHECK_TUPLE:
-            return 1;
-        case _ITER_JUMP_LIST:
-            return 1;
-        case _ITER_JUMP_RANGE:
-            return 1;
-        case _ITER_JUMP_TUPLE:
-            return 1;
-        case _ITER_NEXT_LIST:
-            return 1;
-        case _ITER_NEXT_RANGE:
-            return 1;
-        case _ITER_NEXT_TUPLE:
-            return 1;
-        case _JUMP_TO_TOP:
-            return 0;
-        case _LOAD_ATTR:
-            return 1;
-        case _LOAD_ATTR_CLASS:
-            return 1;
-        case _LOAD_ATTR_INSTANCE_VALUE:
-            return 1;
-        case _LOAD_ATTR_METHOD_LAZY_DICT:
-            return 1;
-        case _LOAD_ATTR_METHOD_NO_DICT:
-            return 1;
-        case _LOAD_ATTR_METHOD_WITH_VALUES:
-            return 1;
-        case _LOAD_ATTR_MODULE:
-            return 1;
-        case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
-            return 1;
-        case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
-            return 1;
-        case _LOAD_ATTR_SLOT:
-            return 1;
-        case _LOAD_ATTR_WITH_HINT:
-            return 1;
-        case _LOAD_GLOBAL:
-            return 0;
-        case _LOAD_GLOBAL_BUILTINS:
-            return 0;
-        case _LOAD_GLOBAL_MODULE:
-            return 0;
-        case _LOAD_SUPER_ATTR:
-            return 3;
-        case _POP_FRAME:
-            return 1;
-        case _POP_JUMP_IF_FALSE:
-            return 1;
-        case _POP_JUMP_IF_TRUE:
-            return 1;
-        case _PUSH_FRAME:
-            return 1;
-        case _SAVE_RETURN_OFFSET:
-            return 0;
-        case _SEND:
-            return 2;
-        case _SET_IP:
-            return 0;
-        case _SPECIALIZE_BINARY_OP:
-            return 2;
-        case _SPECIALIZE_BINARY_SUBSCR:
-            return 2;
-        case _SPECIALIZE_CALL:
-            return oparg + 2;
-        case _SPECIALIZE_COMPARE_OP:
-            return 2;
-        case _SPECIALIZE_FOR_ITER:
-            return 1;
-        case _SPECIALIZE_LOAD_ATTR:
-            return 1;
-        case _SPECIALIZE_LOAD_GLOBAL:
-            return 0;
-        case _SPECIALIZE_LOAD_SUPER_ATTR:
-            return 3;
-        case _SPECIALIZE_SEND:
-            return 2;
-        case _SPECIALIZE_STORE_ATTR:
-            return 1;
-        case _SPECIALIZE_STORE_SUBSCR:
-            return 2;
-        case _SPECIALIZE_TO_BOOL:
-            return 1;
-        case _SPECIALIZE_UNPACK_SEQUENCE:
-            return 1;
-        case _STORE_ATTR:
-            return 2;
-        case _STORE_ATTR_INSTANCE_VALUE:
-            return 2;
-        case _STORE_ATTR_SLOT:
-            return 2;
-        case _STORE_SUBSCR:
-            return 3;
-        case _TO_BOOL:
-            return 1;
-        case _UNPACK_SEQUENCE:
-            return 1;
         default:
             return -1;
     }
 }
-#endif // NEED_OPCODE_METADATA
 
-extern int _PyOpcode_num_pushed(int opcode, int oparg, bool jump);
+#endif
+
+extern int _PyOpcode_num_pushed(int opcode, int oparg);
 #ifdef NEED_OPCODE_METADATA
-int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
+int _PyOpcode_num_pushed(int opcode, int oparg)  {
     switch(opcode) {
         case BEFORE_ASYNC_WITH:
             return 2;
@@ -728,7 +519,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case CALL_ALLOC_AND_ENTER_INIT:
             return 1;
         case CALL_BOUND_METHOD_EXACT_ARGS:
-            return 0;
+            return (((0) ? 1 : 0));
         case CALL_BUILTIN_CLASS:
             return 1;
         case CALL_BUILTIN_FAST:
@@ -760,7 +551,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case CALL_METHOD_DESCRIPTOR_O:
             return 1;
         case CALL_PY_EXACT_ARGS:
-            return 0;
+            return (((0) ? 1 : 0));
         case CALL_PY_WITH_DEFAULTS:
             return 1;
         case CALL_STR_1:
@@ -788,7 +579,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case CONVERT_VALUE:
             return 1;
         case COPY:
-            return (oparg-1) + 2;
+            return 2 + (oparg-1);
         case COPY_FREE_VARS:
             return 0;
         case DELETE_ATTR:
@@ -804,9 +595,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case DELETE_SUBSCR:
             return 0;
         case DICT_MERGE:
-            return (oparg - 1) + 4;
+            return 4 + (oparg - 1);
         case DICT_UPDATE:
-            return (oparg - 1) + 1;
+            return 1 + (oparg - 1);
         case END_ASYNC_FOR:
             return 0;
         case END_FOR:
@@ -868,7 +659,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case INSTRUMENTED_JUMP_FORWARD:
             return 0;
         case INSTRUMENTED_LOAD_SUPER_ATTR:
-            return ((oparg & 1) ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case INSTRUMENTED_POP_JUMP_IF_FALSE:
             return 0;
         case INSTRUMENTED_POP_JUMP_IF_NONE:
@@ -889,52 +680,46 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
             return 0;
         case IS_OP:
             return 1;
-        case JUMP:
-            return 0;
         case JUMP_BACKWARD:
             return 0;
         case JUMP_BACKWARD_NO_INTERRUPT:
             return 0;
         case JUMP_FORWARD:
             return 0;
-        case JUMP_NO_INTERRUPT:
-            return 0;
         case LIST_APPEND:
-            return (oparg-1) + 1;
+            return 1 + (oparg-1);
         case LIST_EXTEND:
-            return (oparg-1) + 1;
+            return 1 + (oparg-1);
         case LOAD_ASSERTION_ERROR:
             return 1;
         case LOAD_ATTR:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_ATTR_CLASS:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
-            return 1;
+            return 1 + (((0) ? 1 : 0));
         case LOAD_ATTR_INSTANCE_VALUE:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_ATTR_METHOD_LAZY_DICT:
-            return 2;
+            return 1 + (((1) ? 1 : 0));
         case LOAD_ATTR_METHOD_NO_DICT:
-            return 2;
+            return 1 + (((1) ? 1 : 0));
         case LOAD_ATTR_METHOD_WITH_VALUES:
-            return 2;
+            return 1 + (((1) ? 1 : 0));
         case LOAD_ATTR_MODULE:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
-            return 1;
+            return 1 + (((0) ? 1 : 0));
         case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
-            return 1;
+            return 1 + (((0) ? 1 : 0));
         case LOAD_ATTR_PROPERTY:
-            return 1;
+            return 1 + (((0) ? 1 : 0));
         case LOAD_ATTR_SLOT:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_ATTR_WITH_HINT:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_BUILD_CLASS:
             return 1;
-        case LOAD_CLOSURE:
-            return 1;
         case LOAD_CONST:
             return 1;
         case LOAD_DEREF:
@@ -952,35 +737,27 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case LOAD_FROM_DICT_OR_GLOBALS:
             return 1;
         case LOAD_GLOBAL:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_GLOBAL_BUILTIN:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_GLOBAL_MODULE:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_LOCALS:
             return 1;
-        case LOAD_METHOD:
-            return (oparg & 1 ? 1 : 0) + 1;
         case LOAD_NAME:
             return 1;
         case LOAD_SUPER_ATTR:
-            return (oparg & 1 ? 1 : 0) + 1;
+            return 1 + ((oparg & 1));
         case LOAD_SUPER_ATTR_ATTR:
-            return 1;
+            return 1 + (((0) ? 1 : 0));
         case LOAD_SUPER_ATTR_METHOD:
             return 2;
-        case LOAD_SUPER_METHOD:
-            return (oparg & 1 ? 1 : 0) + 1;
-        case LOAD_ZERO_SUPER_ATTR:
-            return (oparg & 1 ? 1 : 0) + 1;
-        case LOAD_ZERO_SUPER_METHOD:
-            return (oparg & 1 ? 1 : 0) + 1;
         case MAKE_CELL:
             return 0;
         case MAKE_FUNCTION:
             return 1;
         case MAP_ADD:
-            return (oparg - 1) + 1;
+            return 1 + (oparg - 1);
         case MATCH_CLASS:
             return 1;
         case MATCH_KEYS:
@@ -991,8 +768,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
             return 2;
         case NOP:
             return 0;
-        case POP_BLOCK:
-            return 0;
         case POP_EXCEPT:
             return 0;
         case POP_JUMP_IF_FALSE:
@@ -1031,18 +806,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
             return 2;
         case SETUP_ANNOTATIONS:
             return 0;
-        case SETUP_CLEANUP:
-            return 0;
-        case SETUP_FINALLY:
-            return 0;
-        case SETUP_WITH:
-            return 0;
         case SET_ADD:
-            return (oparg-1) + 1;
+            return 1 + (oparg-1);
         case SET_FUNCTION_ATTRIBUTE:
             return 1;
         case SET_UPDATE:
-            return (oparg-1) + 1;
+            return 1 + (oparg-1);
         case STORE_ATTR:
             return 0;
         case STORE_ATTR_INSTANCE_VALUE:
@@ -1057,8 +826,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
             return 0;
         case STORE_FAST_LOAD_FAST:
             return 1;
-        case STORE_FAST_MAYBE_NULL:
-            return 0;
         case STORE_FAST_STORE_FAST:
             return 0;
         case STORE_GLOBAL:
@@ -1074,7 +841,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case STORE_SUBSCR_LIST_INT:
             return 0;
         case SWAP:
-            return (oparg-2) + 2;
+            return 2 + (oparg-2);
         case TO_BOOL:
             return 1;
         case TO_BOOL_ALWAYS_TRUE:
@@ -1096,7 +863,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
         case UNARY_NOT:
             return 1;
         case UNPACK_EX:
-            return (oparg & 0xFF) + (oparg >> 8) + 1;
+            return 1 + (oparg >> 8) + (oparg & 0xFF);
         case UNPACK_SEQUENCE:
             return oparg;
         case UNPACK_SEQUENCE_LIST:
@@ -1109,221 +876,27 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump)  {
             return 5;
         case YIELD_VALUE:
             return 1;
-        case _BINARY_OP:
-            return 1;
-        case _BINARY_OP_ADD_FLOAT:
-            return 1;
-        case _BINARY_OP_ADD_INT:
-            return 1;
-        case _BINARY_OP_ADD_UNICODE:
-            return 1;
-        case _BINARY_OP_INPLACE_ADD_UNICODE:
-            return 0;
-        case _BINARY_OP_MULTIPLY_FLOAT:
-            return 1;
-        case _BINARY_OP_MULTIPLY_INT:
-            return 1;
-        case _BINARY_OP_SUBTRACT_FLOAT:
-            return 1;
-        case _BINARY_OP_SUBTRACT_INT:
-            return 1;
-        case _BINARY_SUBSCR:
-            return 1;
-        case _CALL:
-            return 1;
-        case _CHECK_ATTR_CLASS:
-            return 1;
-        case _CHECK_ATTR_METHOD_LAZY_DICT:
-            return 1;
-        case _CHECK_ATTR_MODULE:
-            return 1;
-        case _CHECK_ATTR_WITH_HINT:
-            return 1;
-        case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
-            return oparg + 2;
-        case _CHECK_FUNCTION_EXACT_ARGS:
-            return oparg + 2;
-        case _CHECK_MANAGED_OBJECT_HAS_VALUES:
-            return 1;
-        case _CHECK_PEP_523:
-            return 0;
-        case _CHECK_STACK_SPACE:
-            return oparg + 2;
-        case _CHECK_VALIDITY:
-            return 0;
-        case _COMPARE_OP:
-            return 1;
-        case _EXIT_TRACE:
-            return 0;
-        case _FOR_ITER:
-            return 2;
-        case _FOR_ITER_TIER_TWO:
-            return 2;
-        case _GUARD_BOTH_FLOAT:
-            return 2;
-        case _GUARD_BOTH_INT:
-            return 2;
-        case _GUARD_BOTH_UNICODE:
-            return 2;
-        case _GUARD_BUILTINS_VERSION:
-            return 0;
-        case _GUARD_DORV_VALUES:
-            return 1;
-        case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT:
-            return 1;
-        case _GUARD_GLOBALS_VERSION:
-            return 0;
-        case _GUARD_IS_FALSE_POP:
-            return 0;
-        case _GUARD_IS_NONE_POP:
-            return 0;
-        case _GUARD_IS_NOT_NONE_POP:
-            return 0;
-        case _GUARD_IS_TRUE_POP:
-            return 0;
-        case _GUARD_KEYS_VERSION:
-            return 1;
-        case _GUARD_NOT_EXHAUSTED_LIST:
-            return 1;
-        case _GUARD_NOT_EXHAUSTED_RANGE:
-            return 1;
-        case _GUARD_NOT_EXHAUSTED_TUPLE:
-            return 1;
-        case _GUARD_TYPE_VERSION:
-            return 1;
-        case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
-            return oparg + 2;
-        case _INIT_CALL_PY_EXACT_ARGS:
-            return 1;
-        case _INSERT:
-            return oparg + 1;
-        case _IS_NONE:
-            return 1;
-        case _ITER_CHECK_LIST:
-            return 1;
-        case _ITER_CHECK_RANGE:
-            return 1;
-        case _ITER_CHECK_TUPLE:
-            return 1;
-        case _ITER_JUMP_LIST:
-            return 1;
-        case _ITER_JUMP_RANGE:
-            return 1;
-        case _ITER_JUMP_TUPLE:
-            return 1;
-        case _ITER_NEXT_LIST:
-            return 2;
-        case _ITER_NEXT_RANGE:
-            return 2;
-        case _ITER_NEXT_TUPLE:
-            return 2;
-        case _JUMP_TO_TOP:
-            return 0;
-        case _LOAD_ATTR:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_ATTR_CLASS:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_ATTR_INSTANCE_VALUE:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_ATTR_METHOD_LAZY_DICT:
-            return 2;
-        case _LOAD_ATTR_METHOD_NO_DICT:
-            return 2;
-        case _LOAD_ATTR_METHOD_WITH_VALUES:
-            return 2;
-        case _LOAD_ATTR_MODULE:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
-            return 1;
-        case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
-            return 1;
-        case _LOAD_ATTR_SLOT:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_ATTR_WITH_HINT:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_GLOBAL:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_GLOBAL_BUILTINS:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_GLOBAL_MODULE:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _LOAD_SUPER_ATTR:
-            return ((oparg & 1) ? 1 : 0) + 1;
-        case _POP_FRAME:
-            return 0;
-        case _POP_JUMP_IF_FALSE:
-            return 0;
-        case _POP_JUMP_IF_TRUE:
-            return 0;
-        case _PUSH_FRAME:
-            return 0;
-        case _SAVE_RETURN_OFFSET:
-            return 0;
-        case _SEND:
-            return 2;
-        case _SET_IP:
-            return 0;
-        case _SPECIALIZE_BINARY_OP:
-            return 2;
-        case _SPECIALIZE_BINARY_SUBSCR:
-            return 2;
-        case _SPECIALIZE_CALL:
-            return oparg + 2;
-        case _SPECIALIZE_COMPARE_OP:
-            return 2;
-        case _SPECIALIZE_FOR_ITER:
-            return 1;
-        case _SPECIALIZE_LOAD_ATTR:
-            return 1;
-        case _SPECIALIZE_LOAD_GLOBAL:
-            return 0;
-        case _SPECIALIZE_LOAD_SUPER_ATTR:
-            return 3;
-        case _SPECIALIZE_SEND:
-            return 2;
-        case _SPECIALIZE_STORE_ATTR:
-            return 1;
-        case _SPECIALIZE_STORE_SUBSCR:
-            return 2;
-        case _SPECIALIZE_TO_BOOL:
-            return 1;
-        case _SPECIALIZE_UNPACK_SEQUENCE:
-            return 1;
-        case _STORE_ATTR:
-            return 0;
-        case _STORE_ATTR_INSTANCE_VALUE:
-            return 0;
-        case _STORE_ATTR_SLOT:
-            return 0;
-        case _STORE_SUBSCR:
-            return 0;
-        case _TO_BOOL:
-            return 1;
-        case _UNPACK_SEQUENCE:
-            return oparg;
         default:
             return -1;
     }
 }
-#endif // NEED_OPCODE_METADATA
+
+#endif
 
 enum InstructionFormat {
-    INSTR_FMT_IB,
-    INSTR_FMT_IBC,
-    INSTR_FMT_IBC0,
-    INSTR_FMT_IBC00,
-    INSTR_FMT_IBC000,
-    INSTR_FMT_IBC0000000,
-    INSTR_FMT_IBC00000000,
-    INSTR_FMT_IX,
-    INSTR_FMT_IXC,
-    INSTR_FMT_IXC0,
-    INSTR_FMT_IXC00,
-    INSTR_FMT_IXC000,
+    INSTR_FMT_IB = 1,
+    INSTR_FMT_IBC = 2,
+    INSTR_FMT_IBC00 = 3,
+    INSTR_FMT_IBC000 = 4,
+    INSTR_FMT_IBC00000000 = 5,
+    INSTR_FMT_IX = 6,
+    INSTR_FMT_IXC = 7,
+    INSTR_FMT_IXC00 = 8,
+    INSTR_FMT_IXC000 = 9,
 };
 
 #define IS_VALID_OPCODE(OP) \
-    (((OP) >= 0) && ((OP) < OPCODE_METADATA_SIZE) && \
+    (((OP) >= 0) && ((OP) < 268) && \
      (_PyOpcode_opcode_metadata[(OP)].valid_entry))
 
 #define HAS_ARG_FLAG (1)
@@ -1347,17 +920,6 @@ enum InstructionFormat {
 #define OPCODE_HAS_ERROR(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_FLAG))
 #define OPCODE_HAS_ESCAPES(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ESCAPES_FLAG))
 
-struct opcode_metadata {
-    bool valid_entry;
-    enum InstructionFormat instr_format;
-    int flags;
-};
-
-struct opcode_macro_expansion {
-    int nuops;
-    struct { int16_t uop; int8_t size; int8_t offset; } uops[12];
-};
-
 #define OPARG_FULL 0
 #define OPARG_CACHE_1 1
 #define OPARG_CACHE_2 2
@@ -1365,18 +927,17 @@ struct opcode_macro_expansion {
 #define OPARG_TOP 5
 #define OPARG_BOTTOM 6
 #define OPARG_SAVE_RETURN_OFFSET 7
+#define OPARG_REPLACED 9
 
-#define OPCODE_METADATA_FLAGS(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG | HAS_JUMP_FLAG))
-#define SAME_OPCODE_METADATA(OP1, OP2) \
-        (OPCODE_METADATA_FLAGS(OP1) == OPCODE_METADATA_FLAGS(OP2))
-
-#define OPCODE_METADATA_SIZE 512
-#define OPCODE_UOP_NAME_SIZE 512
-#define OPCODE_MACRO_EXPANSION_SIZE 256
+struct opcode_metadata {
+    uint8_t valid_entry;
+    int8_t instr_format;
+    int16_t flags;
+};
 
-extern const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE];
+extern const struct opcode_metadata _PyOpcode_opcode_metadata[268];
 #ifdef NEED_OPCODE_METADATA
-const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
+const struct opcode_metadata _PyOpcode_opcode_metadata[268] = {
     [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [BEFORE_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1486,11 +1047,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [INTERPRETER_EXIT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
     [IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
-    [JUMP] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
     [JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
-    [JUMP_NO_INTERRUPT] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
     [LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
     [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, 0 },
@@ -1508,7 +1067,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
     [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [LOAD_CLOSURE] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
     [LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
     [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
@@ -1521,14 +1079,10 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
     [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
     [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [LOAD_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [LOAD_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [LOAD_ZERO_SUPER_ATTR] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [LOAD_ZERO_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1537,7 +1091,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 },
     [MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 },
     [NOP] = { true, INSTR_FMT_IX, 0 },
-    [POP_BLOCK] = { true, 0, 0 },
     [POP_EXCEPT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
     [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
     [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
@@ -1557,9 +1110,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
     [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [SETUP_CLEANUP] = { true, 0, HAS_ARG_FLAG },
-    [SETUP_FINALLY] = { true, 0, HAS_ARG_FLAG },
-    [SETUP_WITH] = { true, 0, HAS_ARG_FLAG },
     [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
     [SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1570,7 +1120,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG },
     [STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
     [STORE_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
-    [STORE_FAST_MAYBE_NULL] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
     [STORE_FAST_STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
     [STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
@@ -1596,110 +1145,33 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
     [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
     [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_BINARY_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
-    [_BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, 0 },
-    [_BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
-    [_BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, 0 },
-    [_BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
-    [_BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, 0 },
-    [_BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
-    [_BINARY_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_CALL] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_CHECK_ATTR_CLASS] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
-    [_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_CHECK_ATTR_MODULE] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
-    [_CHECK_ATTR_WITH_HINT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
-    [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_CHECK_FUNCTION_EXACT_ARGS] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_CHECK_MANAGED_OBJECT_HAS_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_CHECK_PEP_523] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_CHECK_STACK_SPACE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_CHECK_VALIDITY] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_COMPARE_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_EXIT_TRACE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_FOR_ITER_TIER_TWO] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_GUARD_BOTH_FLOAT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_BOTH_INT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_BOTH_UNICODE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_BUILTINS_VERSION] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
-    [_GUARD_DORV_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_GLOBALS_VERSION] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
-    [_GUARD_IS_FALSE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_IS_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_IS_NOT_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_IS_TRUE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_KEYS_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
-    [_GUARD_NOT_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_NOT_EXHAUSTED_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_NOT_EXHAUSTED_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_GUARD_TYPE_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
-    [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
-    [_INIT_CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_INSERT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
-    [_IS_NONE] = { true, INSTR_FMT_IX, 0 },
-    [_ITER_CHECK_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_ITER_CHECK_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_ITER_CHECK_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
-    [_ITER_JUMP_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
-    [_ITER_JUMP_RANGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
-    [_ITER_JUMP_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
-    [_ITER_NEXT_LIST] = { true, INSTR_FMT_IX, 0 },
-    [_ITER_NEXT_RANGE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_ITER_NEXT_TUPLE] = { true, INSTR_FMT_IX, 0 },
-    [_JUMP_TO_TOP] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG },
-    [_LOAD_ATTR] = { true, INSTR_FMT_IBC0000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
-    [_LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
-    [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
-    [_LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
-    [_LOAD_GLOBAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_LOAD_GLOBAL_BUILTINS] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
-    [_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_POP_FRAME] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
-    [_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
-    [_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
-    [_PUSH_FRAME] = { true, INSTR_FMT_IX, 0 },
-    [_SAVE_RETURN_OFFSET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
-    [_SEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_SET_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_CALL] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_LOAD_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_LOAD_GLOBAL] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_SEND] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_STORE_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_TO_BOOL] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
-    [_SPECIALIZE_UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
-    [_STORE_ATTR] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
-    [_STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
-    [_STORE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_TO_BOOL] = { true, INSTR_FMT_IXC0, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
-    [_UNPACK_SEQUENCE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+    [LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+    [LOAD_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [LOAD_SUPER_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [LOAD_ZERO_SUPER_ATTR] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [LOAD_ZERO_SUPER_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+    [POP_BLOCK] = { true, -1, 0 },
+    [SETUP_CLEANUP] = { true, -1, HAS_ARG_FLAG },
+    [SETUP_FINALLY] = { true, -1, HAS_ARG_FLAG },
+    [SETUP_WITH] = { true, -1, HAS_ARG_FLAG },
+    [STORE_FAST_MAYBE_NULL] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
 };
-#endif // NEED_OPCODE_METADATA
+#endif
+
+#define MAX_UOP_PER_EXPANSION 8
+struct opcode_macro_expansion {
+    int nuops;
+    struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];
+};
+extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256];
 
-extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE];
 #ifdef NEED_OPCODE_METADATA
-const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] = {
-    [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { BEFORE_ASYNC_WITH, 0, 0 } } },
-    [BEFORE_WITH] = { .nuops = 1, .uops = { { BEFORE_WITH, 0, 0 } } },
+const struct opcode_macro_expansion
+_PyOpcode_macro_expansion[256] = {
+    [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { _BEFORE_ASYNC_WITH, 0, 0 } } },
+    [BEFORE_WITH] = { .nuops = 1, .uops = { { _BEFORE_WITH, 0, 0 } } },
     [BINARY_OP] = { .nuops = 1, .uops = { { _BINARY_OP, 0, 0 } } },
     [BINARY_OP_ADD_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_ADD_FLOAT, 0, 0 } } },
     [BINARY_OP_ADD_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_ADD_INT, 0, 0 } } },
@@ -1708,73 +1180,73 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
     [BINARY_OP_MULTIPLY_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_MULTIPLY_INT, 0, 0 } } },
     [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, 0, 0 } } },
     [BINARY_OP_SUBTRACT_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_SUBTRACT_INT, 0, 0 } } },
-    [BINARY_SLICE] = { .nuops = 1, .uops = { { BINARY_SLICE, 0, 0 } } },
+    [BINARY_SLICE] = { .nuops = 1, .uops = { { _BINARY_SLICE, 0, 0 } } },
     [BINARY_SUBSCR] = { .nuops = 1, .uops = { { _BINARY_SUBSCR, 0, 0 } } },
-    [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_DICT, 0, 0 } } },
-    [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_LIST_INT, 0, 0 } } },
-    [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_STR_INT, 0, 0 } } },
-    [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_TUPLE_INT, 0, 0 } } },
-    [BUILD_CONST_KEY_MAP] = { .nuops = 1, .uops = { { BUILD_CONST_KEY_MAP, 0, 0 } } },
-    [BUILD_LIST] = { .nuops = 1, .uops = { { BUILD_LIST, 0, 0 } } },
-    [BUILD_MAP] = { .nuops = 1, .uops = { { BUILD_MAP, 0, 0 } } },
-    [BUILD_SET] = { .nuops = 1, .uops = { { BUILD_SET, 0, 0 } } },
-    [BUILD_SLICE] = { .nuops = 1, .uops = { { BUILD_SLICE, 0, 0 } } },
-    [BUILD_STRING] = { .nuops = 1, .uops = { { BUILD_STRING, 0, 0 } } },
-    [BUILD_TUPLE] = { .nuops = 1, .uops = { { BUILD_TUPLE, 0, 0 } } },
+    [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_DICT, 0, 0 } } },
+    [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_LIST_INT, 0, 0 } } },
+    [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_STR_INT, 0, 0 } } },
+    [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_TUPLE_INT, 0, 0 } } },
+    [BUILD_CONST_KEY_MAP] = { .nuops = 1, .uops = { { _BUILD_CONST_KEY_MAP, 0, 0 } } },
+    [BUILD_LIST] = { .nuops = 1, .uops = { { _BUILD_LIST, 0, 0 } } },
+    [BUILD_MAP] = { .nuops = 1, .uops = { { _BUILD_MAP, 0, 0 } } },
+    [BUILD_SET] = { .nuops = 1, .uops = { { _BUILD_SET, 0, 0 } } },
+    [BUILD_SLICE] = { .nuops = 1, .uops = { { _BUILD_SLICE, 0, 0 } } },
+    [BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } },
+    [BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, 0, 0 } } },
     [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
-    [CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { CALL_BUILTIN_CLASS, 0, 0 } } },
-    [CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST, 0, 0 } } },
-    [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } },
-    [CALL_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_BUILTIN_O, 0, 0 } } },
-    [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { CALL_INTRINSIC_1, 0, 0 } } },
-    [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { CALL_INTRINSIC_2, 0, 0 } } },
-    [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_ISINSTANCE, 0, 0 } } },
-    [CALL_LEN] = { .nuops = 1, .uops = { { CALL_LEN, 0, 0 } } },
-    [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST, 0, 0 } } },
-    [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 } } },
-    [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } },
-    [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_O, 0, 0 } } },
+    [CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { _CALL_BUILTIN_CLASS, 0, 0 } } },
+    [CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { _CALL_BUILTIN_FAST, 0, 0 } } },
+    [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } },
+    [CALL_BUILTIN_O] = { .nuops = 1, .uops = { { _CALL_BUILTIN_O, 0, 0 } } },
+    [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, 0, 0 } } },
+    [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, 0, 0 } } },
+    [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { _CALL_ISINSTANCE, 0, 0 } } },
+    [CALL_LEN] = { .nuops = 1, .uops = { { _CALL_LEN, 0, 0 } } },
+    [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, 0, 0 } } },
+    [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 } } },
+    [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } },
+    [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { _CALL_METHOD_DESCRIPTOR_O, 0, 0 } } },
     [CALL_PY_EXACT_ARGS] = { .nuops = 6, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
-    [CALL_STR_1] = { .nuops = 1, .uops = { { CALL_STR_1, 0, 0 } } },
-    [CALL_TUPLE_1] = { .nuops = 1, .uops = { { CALL_TUPLE_1, 0, 0 } } },
-    [CALL_TYPE_1] = { .nuops = 1, .uops = { { CALL_TYPE_1, 0, 0 } } },
-    [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { CHECK_EG_MATCH, 0, 0 } } },
-    [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { CHECK_EXC_MATCH, 0, 0 } } },
+    [CALL_STR_1] = { .nuops = 1, .uops = { { _CALL_STR_1, 0, 0 } } },
+    [CALL_TUPLE_1] = { .nuops = 1, .uops = { { _CALL_TUPLE_1, 0, 0 } } },
+    [CALL_TYPE_1] = { .nuops = 1, .uops = { { _CALL_TYPE_1, 0, 0 } } },
+    [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { _CHECK_EG_MATCH, 0, 0 } } },
+    [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, 0, 0 } } },
     [COMPARE_OP] = { .nuops = 1, .uops = { { _COMPARE_OP, 0, 0 } } },
-    [COMPARE_OP_FLOAT] = { .nuops = 1, .uops = { { COMPARE_OP_FLOAT, 0, 0 } } },
-    [COMPARE_OP_INT] = { .nuops = 1, .uops = { { COMPARE_OP_INT, 0, 0 } } },
-    [COMPARE_OP_STR] = { .nuops = 1, .uops = { { COMPARE_OP_STR, 0, 0 } } },
-    [CONTAINS_OP] = { .nuops = 1, .uops = { { CONTAINS_OP, 0, 0 } } },
-    [CONVERT_VALUE] = { .nuops = 1, .uops = { { CONVERT_VALUE, 0, 0 } } },
-    [COPY] = { .nuops = 1, .uops = { { COPY, 0, 0 } } },
-    [COPY_FREE_VARS] = { .nuops = 1, .uops = { { COPY_FREE_VARS, 0, 0 } } },
-    [DELETE_ATTR] = { .nuops = 1, .uops = { { DELETE_ATTR, 0, 0 } } },
-    [DELETE_DEREF] = { .nuops = 1, .uops = { { DELETE_DEREF, 0, 0 } } },
-    [DELETE_FAST] = { .nuops = 1, .uops = { { DELETE_FAST, 0, 0 } } },
-    [DELETE_GLOBAL] = { .nuops = 1, .uops = { { DELETE_GLOBAL, 0, 0 } } },
-    [DELETE_NAME] = { .nuops = 1, .uops = { { DELETE_NAME, 0, 0 } } },
-    [DELETE_SUBSCR] = { .nuops = 1, .uops = { { DELETE_SUBSCR, 0, 0 } } },
-    [DICT_MERGE] = { .nuops = 1, .uops = { { DICT_MERGE, 0, 0 } } },
-    [DICT_UPDATE] = { .nuops = 1, .uops = { { DICT_UPDATE, 0, 0 } } },
-    [END_FOR] = { .nuops = 2, .uops = { { POP_TOP, 0, 0 }, { POP_TOP, 0, 0 } } },
-    [END_SEND] = { .nuops = 1, .uops = { { END_SEND, 0, 0 } } },
-    [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { EXIT_INIT_CHECK, 0, 0 } } },
-    [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { FORMAT_SIMPLE, 0, 0 } } },
-    [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { FORMAT_WITH_SPEC, 0, 0 } } },
-    [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, 0, 0 } } },
-    [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, 0, 0 }, { _ITER_JUMP_LIST, 0, 0 }, { _ITER_NEXT_LIST, 0, 0 } } },
-    [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, 0, 0 }, { _ITER_JUMP_RANGE, 0, 0 }, { _ITER_NEXT_RANGE, 0, 0 } } },
-    [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, 0, 0 }, { _ITER_JUMP_TUPLE, 0, 0 }, { _ITER_NEXT_TUPLE, 0, 0 } } },
-    [GET_AITER] = { .nuops = 1, .uops = { { GET_AITER, 0, 0 } } },
-    [GET_ANEXT] = { .nuops = 1, .uops = { { GET_ANEXT, 0, 0 } } },
-    [GET_AWAITABLE] = { .nuops = 1, .uops = { { GET_AWAITABLE, 0, 0 } } },
-    [GET_ITER] = { .nuops = 1, .uops = { { GET_ITER, 0, 0 } } },
-    [GET_LEN] = { .nuops = 1, .uops = { { GET_LEN, 0, 0 } } },
-    [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { GET_YIELD_FROM_ITER, 0, 0 } } },
-    [IS_OP] = { .nuops = 1, .uops = { { IS_OP, 0, 0 } } },
-    [LIST_APPEND] = { .nuops = 1, .uops = { { LIST_APPEND, 0, 0 } } },
-    [LIST_EXTEND] = { .nuops = 1, .uops = { { LIST_EXTEND, 0, 0 } } },
-    [LOAD_ASSERTION_ERROR] = { .nuops = 1, .uops = { { LOAD_ASSERTION_ERROR, 0, 0 } } },
+    [COMPARE_OP_FLOAT] = { .nuops = 1, .uops = { { _COMPARE_OP_FLOAT, 0, 0 } } },
+    [COMPARE_OP_INT] = { .nuops = 1, .uops = { { _COMPARE_OP_INT, 0, 0 } } },
+    [COMPARE_OP_STR] = { .nuops = 1, .uops = { { _COMPARE_OP_STR, 0, 0 } } },
+    [CONTAINS_OP] = { .nuops = 1, .uops = { { _CONTAINS_OP, 0, 0 } } },
+    [CONVERT_VALUE] = { .nuops = 1, .uops = { { _CONVERT_VALUE, 0, 0 } } },
+    [COPY] = { .nuops = 1, .uops = { { _COPY, 0, 0 } } },
+    [COPY_FREE_VARS] = { .nuops = 1, .uops = { { _COPY_FREE_VARS, 0, 0 } } },
+    [DELETE_ATTR] = { .nuops = 1, .uops = { { _DELETE_ATTR, 0, 0 } } },
+    [DELETE_DEREF] = { .nuops = 1, .uops = { { _DELETE_DEREF, 0, 0 } } },
+    [DELETE_FAST] = { .nuops = 1, .uops = { { _DELETE_FAST, 0, 0 } } },
+    [DELETE_GLOBAL] = { .nuops = 1, .uops = { { _DELETE_GLOBAL, 0, 0 } } },
+    [DELETE_NAME] = { .nuops = 1, .uops = { { _DELETE_NAME, 0, 0 } } },
+    [DELETE_SUBSCR] = { .nuops = 1, .uops = { { _DELETE_SUBSCR, 0, 0 } } },
+    [DICT_MERGE] = { .nuops = 1, .uops = { { _DICT_MERGE, 0, 0 } } },
+    [DICT_UPDATE] = { .nuops = 1, .uops = { { _DICT_UPDATE, 0, 0 } } },
+    [END_FOR] = { .nuops = 2, .uops = { { _POP_TOP, 0, 0 }, { _POP_TOP, 0, 0 } } },
+    [END_SEND] = { .nuops = 1, .uops = { { _END_SEND, 0, 0 } } },
+    [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { _EXIT_INIT_CHECK, 0, 0 } } },
+    [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { _FORMAT_SIMPLE, 0, 0 } } },
+    [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { _FORMAT_WITH_SPEC, 0, 0 } } },
+    [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, 9, 0 } } },
+    [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, 0, 0 }, { _ITER_JUMP_LIST, 9, 1 }, { _ITER_NEXT_LIST, 0, 0 } } },
+    [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, 0, 0 }, { _ITER_JUMP_RANGE, 9, 1 }, { _ITER_NEXT_RANGE, 0, 0 } } },
+    [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, 0, 0 }, { _ITER_JUMP_TUPLE, 9, 1 }, { _ITER_NEXT_TUPLE, 0, 0 } } },
+    [GET_AITER] = { .nuops = 1, .uops = { { _GET_AITER, 0, 0 } } },
+    [GET_ANEXT] = { .nuops = 1, .uops = { { _GET_ANEXT, 0, 0 } } },
+    [GET_AWAITABLE] = { .nuops = 1, .uops = { { _GET_AWAITABLE, 0, 0 } } },
+    [GET_ITER] = { .nuops = 1, .uops = { { _GET_ITER, 0, 0 } } },
+    [GET_LEN] = { .nuops = 1, .uops = { { _GET_LEN, 0, 0 } } },
+    [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { _GET_YIELD_FROM_ITER, 0, 0 } } },
+    [IS_OP] = { .nuops = 1, .uops = { { _IS_OP, 0, 0 } } },
+    [LIST_APPEND] = { .nuops = 1, .uops = { { _LIST_APPEND, 0, 0 } } },
+    [LIST_EXTEND] = { .nuops = 1, .uops = { { _LIST_EXTEND, 0, 0 } } },
+    [LOAD_ASSERTION_ERROR] = { .nuops = 1, .uops = { { _LOAD_ASSERTION_ERROR, 0, 0 } } },
     [LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, 0, 0 } } },
     [LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
     [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } },
@@ -1786,183 +1258,81 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
     [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
     [LOAD_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 } } },
     [LOAD_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_WITH_HINT, 0, 0 }, { _LOAD_ATTR_WITH_HINT, 1, 3 } } },
-    [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { LOAD_BUILD_CLASS, 0, 0 } } },
-    [LOAD_CONST] = { .nuops = 1, .uops = { { LOAD_CONST, 0, 0 } } },
-    [LOAD_DEREF] = { .nuops = 1, .uops = { { LOAD_DEREF, 0, 0 } } },
-    [LOAD_FAST] = { .nuops = 1, .uops = { { LOAD_FAST, 0, 0 } } },
-    [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { LOAD_FAST_AND_CLEAR, 0, 0 } } },
-    [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { LOAD_FAST_CHECK, 0, 0 } } },
-    [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { LOAD_FAST, 5, 0 }, { LOAD_FAST, 6, 0 } } },
-    [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_DEREF, 0, 0 } } },
-    [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } },
+    [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, 0, 0 } } },
+    [LOAD_CONST] = { .nuops = 1, .uops = { { _LOAD_CONST, 0, 0 } } },
+    [LOAD_DEREF] = { .nuops = 1, .uops = { { _LOAD_DEREF, 0, 0 } } },
+    [LOAD_FAST] = { .nuops = 1, .uops = { { _LOAD_FAST, 0, 0 } } },
+    [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { _LOAD_FAST_AND_CLEAR, 0, 0 } } },
+    [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { _LOAD_FAST_CHECK, 0, 0 } } },
+    [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _LOAD_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } },
+    [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_DEREF, 0, 0 } } },
+    [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } },
     [LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } },
     [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } },
     [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _LOAD_GLOBAL_MODULE, 1, 3 } } },
-    [LOAD_LOCALS] = { .nuops = 1, .uops = { { LOAD_LOCALS, 0, 0 } } },
-    [LOAD_NAME] = { .nuops = 1, .uops = { { LOAD_NAME, 0, 0 } } },
-    [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
-    [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
-    [MAKE_CELL] = { .nuops = 1, .uops = { { MAKE_CELL, 0, 0 } } },
-    [MAKE_FUNCTION] = { .nuops = 1, .uops = { { MAKE_FUNCTION, 0, 0 } } },
-    [MAP_ADD] = { .nuops = 1, .uops = { { MAP_ADD, 0, 0 } } },
-    [MATCH_CLASS] = { .nuops = 1, .uops = { { MATCH_CLASS, 0, 0 } } },
-    [MATCH_KEYS] = { .nuops = 1, .uops = { { MATCH_KEYS, 0, 0 } } },
-    [MATCH_MAPPING] = { .nuops = 1, .uops = { { MATCH_MAPPING, 0, 0 } } },
-    [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { MATCH_SEQUENCE, 0, 0 } } },
-    [NOP] = { .nuops = 1, .uops = { { NOP, 0, 0 } } },
-    [POP_EXCEPT] = { .nuops = 1, .uops = { { POP_EXCEPT, 0, 0 } } },
-    [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 0, 0 } } },
-    [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 0, 0 } } },
-    [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 0, 0 } } },
-    [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, 0, 0 } } },
-    [POP_TOP] = { .nuops = 1, .uops = { { POP_TOP, 0, 0 } } },
-    [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } },
-    [PUSH_NULL] = { .nuops = 1, .uops = { { PUSH_NULL, 0, 0 } } },
-    [RESUME_CHECK] = { .nuops = 1, .uops = { { RESUME_CHECK, 0, 0 } } },
-    [RETURN_CONST] = { .nuops = 2, .uops = { { LOAD_CONST, 0, 0 }, { _POP_FRAME, 0, 0 } } },
+    [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } },
+    [LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } },
+    [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
+    [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
+    [MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, 0, 0 } } },
+    [MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 0, 0 } } },
+    [MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, 0, 0 } } },
+    [MATCH_CLASS] = { .nuops = 1, .uops = { { _MATCH_CLASS, 0, 0 } } },
+    [MATCH_KEYS] = { .nuops = 1, .uops = { { _MATCH_KEYS, 0, 0 } } },
+    [MATCH_MAPPING] = { .nuops = 1, .uops = { { _MATCH_MAPPING, 0, 0 } } },
+    [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { _MATCH_SEQUENCE, 0, 0 } } },
+    [NOP] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
+    [POP_EXCEPT] = { .nuops = 1, .uops = { { _POP_EXCEPT, 0, 0 } } },
+    [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 9, 1 } } },
+    [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 9, 1 } } },
+    [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 9, 1 } } },
+    [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, 9, 1 } } },
+    [POP_TOP] = { .nuops = 1, .uops = { { _POP_TOP, 0, 0 } } },
+    [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, 0, 0 } } },
+    [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, 0, 0 } } },
+    [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, 0, 0 } } },
+    [RETURN_CONST] = { .nuops = 2, .uops = { { _LOAD_CONST, 0, 0 }, { _POP_FRAME, 0, 0 } } },
     [RETURN_VALUE] = { .nuops = 1, .uops = { { _POP_FRAME, 0, 0 } } },
-    [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { SETUP_ANNOTATIONS, 0, 0 } } },
-    [SET_ADD] = { .nuops = 1, .uops = { { SET_ADD, 0, 0 } } },
-    [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { SET_FUNCTION_ATTRIBUTE, 0, 0 } } },
-    [SET_UPDATE] = { .nuops = 1, .uops = { { SET_UPDATE, 0, 0 } } },
+    [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, 0, 0 } } },
+    [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, 0, 0 } } },
+    [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, 0, 0 } } },
+    [SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, 0, 0 } } },
     [STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, 0, 0 } } },
     [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } },
     [STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } },
-    [STORE_DEREF] = { .nuops = 1, .uops = { { STORE_DEREF, 0, 0 } } },
-    [STORE_FAST] = { .nuops = 1, .uops = { { STORE_FAST, 0, 0 } } },
-    [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { STORE_FAST, 5, 0 }, { LOAD_FAST, 6, 0 } } },
-    [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { STORE_FAST, 5, 0 }, { STORE_FAST, 6, 0 } } },
-    [STORE_GLOBAL] = { .nuops = 1, .uops = { { STORE_GLOBAL, 0, 0 } } },
-    [STORE_NAME] = { .nuops = 1, .uops = { { STORE_NAME, 0, 0 } } },
-    [STORE_SLICE] = { .nuops = 1, .uops = { { STORE_SLICE, 0, 0 } } },
+    [STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, 0, 0 } } },
+    [STORE_FAST] = { .nuops = 1, .uops = { { _STORE_FAST, 0, 0 } } },
+    [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } },
+    [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, 5, 0 }, { _STORE_FAST, 6, 0 } } },
+    [STORE_GLOBAL] = { .nuops = 1, .uops = { { _STORE_GLOBAL, 0, 0 } } },
+    [STORE_NAME] = { .nuops = 1, .uops = { { _STORE_NAME, 0, 0 } } },
+    [STORE_SLICE] = { .nuops = 1, .uops = { { _STORE_SLICE, 0, 0 } } },
     [STORE_SUBSCR] = { .nuops = 1, .uops = { { _STORE_SUBSCR, 0, 0 } } },
-    [STORE_SUBSCR_DICT] = { .nuops = 1, .uops = { { STORE_SUBSCR_DICT, 0, 0 } } },
-    [STORE_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { STORE_SUBSCR_LIST_INT, 0, 0 } } },
-    [SWAP] = { .nuops = 1, .uops = { { SWAP, 0, 0 } } },
+    [STORE_SUBSCR_DICT] = { .nuops = 1, .uops = { { _STORE_SUBSCR_DICT, 0, 0 } } },
+    [STORE_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { _STORE_SUBSCR_LIST_INT, 0, 0 } } },
+    [SWAP] = { .nuops = 1, .uops = { { _SWAP, 0, 0 } } },
     [TO_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL, 0, 0 } } },
-    [TO_BOOL_ALWAYS_TRUE] = { .nuops = 1, .uops = { { TO_BOOL_ALWAYS_TRUE, 2, 1 } } },
-    [TO_BOOL_BOOL] = { .nuops = 1, .uops = { { TO_BOOL_BOOL, 0, 0 } } },
-    [TO_BOOL_INT] = { .nuops = 1, .uops = { { TO_BOOL_INT, 0, 0 } } },
-    [TO_BOOL_LIST] = { .nuops = 1, .uops = { { TO_BOOL_LIST, 0, 0 } } },
-    [TO_BOOL_NONE] = { .nuops = 1, .uops = { { TO_BOOL_NONE, 0, 0 } } },
-    [TO_BOOL_STR] = { .nuops = 1, .uops = { { TO_BOOL_STR, 0, 0 } } },
-    [UNARY_INVERT] = { .nuops = 1, .uops = { { UNARY_INVERT, 0, 0 } } },
-    [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { UNARY_NEGATIVE, 0, 0 } } },
-    [UNARY_NOT] = { .nuops = 1, .uops = { { UNARY_NOT, 0, 0 } } },
-    [UNPACK_EX] = { .nuops = 1, .uops = { { UNPACK_EX, 0, 0 } } },
+    [TO_BOOL_ALWAYS_TRUE] = { .nuops = 1, .uops = { { _TO_BOOL_ALWAYS_TRUE, 2, 1 } } },
+    [TO_BOOL_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL_BOOL, 0, 0 } } },
+    [TO_BOOL_INT] = { .nuops = 1, .uops = { { _TO_BOOL_INT, 0, 0 } } },
+    [TO_BOOL_LIST] = { .nuops = 1, .uops = { { _TO_BOOL_LIST, 0, 0 } } },
+    [TO_BOOL_NONE] = { .nuops = 1, .uops = { { _TO_BOOL_NONE, 0, 0 } } },
+    [TO_BOOL_STR] = { .nuops = 1, .uops = { { _TO_BOOL_STR, 0, 0 } } },
+    [UNARY_INVERT] = { .nuops = 1, .uops = { { _UNARY_INVERT, 0, 0 } } },
+    [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { _UNARY_NEGATIVE, 0, 0 } } },
+    [UNARY_NOT] = { .nuops = 1, .uops = { { _UNARY_NOT, 0, 0 } } },
+    [UNPACK_EX] = { .nuops = 1, .uops = { { _UNPACK_EX, 0, 0 } } },
     [UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, 0, 0 } } },
-    [UNPACK_SEQUENCE_LIST] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_LIST, 0, 0 } } },
-    [UNPACK_SEQUENCE_TUPLE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_TUPLE, 0, 0 } } },
-    [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_TWO_TUPLE, 0, 0 } } },
-    [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { WITH_EXCEPT_START, 0, 0 } } },
+    [UNPACK_SEQUENCE_LIST] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_LIST, 0, 0 } } },
+    [UNPACK_SEQUENCE_TUPLE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_TUPLE, 0, 0 } } },
+    [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_TWO_TUPLE, 0, 0 } } },
+    [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, 0, 0 } } },
 };
 #endif // NEED_OPCODE_METADATA
 
-extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE];
+extern const char *_PyOpcode_OpName[268];
 #ifdef NEED_OPCODE_METADATA
-const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = {
-    [_EXIT_TRACE] = "_EXIT_TRACE",
-    [_SET_IP] = "_SET_IP",
-    [_BINARY_OP] = "_BINARY_OP",
-    [_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
-    [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
-    [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
-    [_BINARY_OP_INPLACE_ADD_UNICODE] = "_BINARY_OP_INPLACE_ADD_UNICODE",
-    [_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
-    [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
-    [_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
-    [_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
-    [_BINARY_SUBSCR] = "_BINARY_SUBSCR",
-    [_CALL] = "_CALL",
-    [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
-    [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
-    [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
-    [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
-    [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
-    [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
-    [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
-    [_CHECK_PEP_523] = "_CHECK_PEP_523",
-    [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
-    [_CHECK_VALIDITY] = "_CHECK_VALIDITY",
-    [_COMPARE_OP] = "_COMPARE_OP",
-    [_FOR_ITER] = "_FOR_ITER",
-    [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO",
-    [_GUARD_BOTH_FLOAT] = "_GUARD_BOTH_FLOAT",
-    [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT",
-    [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE",
-    [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION",
-    [_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES",
-    [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT",
-    [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
-    [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP",
-    [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP",
-    [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP",
-    [_GUARD_IS_TRUE_POP] = "_GUARD_IS_TRUE_POP",
-    [_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION",
-    [_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_EXHAUSTED_LIST",
-    [_GUARD_NOT_EXHAUSTED_RANGE] = "_GUARD_NOT_EXHAUSTED_RANGE",
-    [_GUARD_NOT_EXHAUSTED_TUPLE] = "_GUARD_NOT_EXHAUSTED_TUPLE",
-    [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION",
-    [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS",
-    [_INIT_CALL_PY_EXACT_ARGS] = "_INIT_CALL_PY_EXACT_ARGS",
-    [_INSERT] = "_INSERT",
-    [_IS_NONE] = "_IS_NONE",
-    [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
-    [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE",
-    [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE",
-    [_ITER_JUMP_LIST] = "_ITER_JUMP_LIST",
-    [_ITER_JUMP_RANGE] = "_ITER_JUMP_RANGE",
-    [_ITER_JUMP_TUPLE] = "_ITER_JUMP_TUPLE",
-    [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST",
-    [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE",
-    [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE",
-    [_JUMP_TO_TOP] = "_JUMP_TO_TOP",
-    [_LOAD_ATTR] = "_LOAD_ATTR",
-    [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
-    [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
-    [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
-    [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
-    [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
-    [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
-    [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
-    [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
-    [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
-    [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
-    [_LOAD_GLOBAL] = "_LOAD_GLOBAL",
-    [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS",
-    [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
-    [_LOAD_SUPER_ATTR] = "_LOAD_SUPER_ATTR",
-    [_POP_FRAME] = "_POP_FRAME",
-    [_POP_JUMP_IF_FALSE] = "_POP_JUMP_IF_FALSE",
-    [_POP_JUMP_IF_TRUE] = "_POP_JUMP_IF_TRUE",
-    [_PUSH_FRAME] = "_PUSH_FRAME",
-    [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET",
-    [_SEND] = "_SEND",
-    [_SPECIALIZE_BINARY_OP] = "_SPECIALIZE_BINARY_OP",
-    [_SPECIALIZE_BINARY_SUBSCR] = "_SPECIALIZE_BINARY_SUBSCR",
-    [_SPECIALIZE_CALL] = "_SPECIALIZE_CALL",
-    [_SPECIALIZE_COMPARE_OP] = "_SPECIALIZE_COMPARE_OP",
-    [_SPECIALIZE_FOR_ITER] = "_SPECIALIZE_FOR_ITER",
-    [_SPECIALIZE_LOAD_ATTR] = "_SPECIALIZE_LOAD_ATTR",
-    [_SPECIALIZE_LOAD_GLOBAL] = "_SPECIALIZE_LOAD_GLOBAL",
-    [_SPECIALIZE_LOAD_SUPER_ATTR] = "_SPECIALIZE_LOAD_SUPER_ATTR",
-    [_SPECIALIZE_SEND] = "_SPECIALIZE_SEND",
-    [_SPECIALIZE_STORE_ATTR] = "_SPECIALIZE_STORE_ATTR",
-    [_SPECIALIZE_STORE_SUBSCR] = "_SPECIALIZE_STORE_SUBSCR",
-    [_SPECIALIZE_TO_BOOL] = "_SPECIALIZE_TO_BOOL",
-    [_SPECIALIZE_UNPACK_SEQUENCE] = "_SPECIALIZE_UNPACK_SEQUENCE",
-    [_STORE_ATTR] = "_STORE_ATTR",
-    [_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
-    [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
-    [_STORE_SUBSCR] = "_STORE_SUBSCR",
-    [_TO_BOOL] = "_TO_BOOL",
-    [_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE",
-};
-#endif // NEED_OPCODE_METADATA
-
-extern const char *const _PyOpcode_OpName[268];
-#ifdef NEED_OPCODE_METADATA
-const char *const _PyOpcode_OpName[268] = {
+const char *_PyOpcode_OpName[268] = {
     [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH",
     [BEFORE_WITH] = "BEFORE_WITH",
     [BINARY_OP] = "BINARY_OP",
@@ -2184,13 +1554,13 @@ const char *const _PyOpcode_OpName[268] = {
     [WITH_EXCEPT_START] = "WITH_EXCEPT_START",
     [YIELD_VALUE] = "YIELD_VALUE",
 };
-#endif // NEED_OPCODE_METADATA
+#endif
 
 extern const uint8_t _PyOpcode_Caches[256];
 #ifdef NEED_OPCODE_METADATA
 const uint8_t _PyOpcode_Caches[256] = {
+    [JUMP_BACKWARD] = 1,
     [TO_BOOL] = 3,
-    [BINARY_OP_INPLACE_ADD_UNICODE] = 1,
     [BINARY_SUBSCR] = 1,
     [STORE_SUBSCR] = 1,
     [SEND] = 1,
@@ -2200,7 +1570,6 @@ const uint8_t _PyOpcode_Caches[256] = {
     [LOAD_SUPER_ATTR] = 1,
     [LOAD_ATTR] = 9,
     [COMPARE_OP] = 1,
-    [JUMP_BACKWARD] = 1,
     [POP_JUMP_IF_TRUE] = 1,
     [POP_JUMP_IF_FALSE] = 1,
     [POP_JUMP_IF_NONE] = 1,
@@ -2209,7 +1578,7 @@ const uint8_t _PyOpcode_Caches[256] = {
     [CALL] = 3,
     [BINARY_OP] = 1,
 };
-#endif // NEED_OPCODE_METADATA
+#endif
 
 extern const uint8_t _PyOpcode_Deopt[256];
 #ifdef NEED_OPCODE_METADATA
@@ -2423,6 +1792,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [WITH_EXCEPT_START] = WITH_EXCEPT_START,
     [YIELD_VALUE] = YIELD_VALUE,
 };
+
 #endif // NEED_OPCODE_METADATA
 
 #define EXTRA_CASES \
@@ -2475,4 +1845,40 @@ const uint8_t _PyOpcode_Deopt[256] = {
     case 235: \
     case 255: \
         ;
+struct pseudo_targets {
+    uint8_t targets[3];
+};
+extern const struct pseudo_targets _PyOpcode_PseudoTargets[12];
+#ifdef NEED_OPCODE_METADATA
+const struct pseudo_targets _PyOpcode_PseudoTargets[12] = {
+    [LOAD_CLOSURE-256] = { { LOAD_FAST, 0, 0 } },
+    [STORE_FAST_MAYBE_NULL-256] = { { STORE_FAST, 0, 0 } },
+    [LOAD_SUPER_METHOD-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+    [LOAD_ZERO_SUPER_METHOD-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+    [LOAD_ZERO_SUPER_ATTR-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+    [LOAD_METHOD-256] = { { LOAD_ATTR, 0, 0 } },
+    [JUMP-256] = { { JUMP_FORWARD, JUMP_BACKWARD, 0 } },
+    [JUMP_NO_INTERRUPT-256] = { { JUMP_FORWARD, JUMP_BACKWARD_NO_INTERRUPT, 0 } },
+    [SETUP_FINALLY-256] = { { NOP, 0, 0 } },
+    [SETUP_CLEANUP-256] = { { NOP, 0, 0 } },
+    [SETUP_WITH-256] = { { NOP, 0, 0 } },
+    [POP_BLOCK-256] = { { NOP, 0, 0 } },
+};
 
+#endif // NEED_OPCODE_METADATA
+static inline bool
+is_pseudo_target(int pseudo, int target) {
+    if (pseudo < 256 || pseudo >= 268) {
+        return false;
+    }
+    for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) {
+        if (_PyOpcode_PseudoTargets[pseudo-256].targets[i] == target) return true;
+    }
+    return false;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_OPCODE_METADATA_H */
index c96ea51ae1acb6e0eaad0c7fcf6cc5ac84ab4b38..4a9a00ba352d3388e11d93a305b7828784ae8f58 100644 (file)
@@ -2,6 +2,7 @@
 // from:
 //   Python/bytecodes.c
 // Do not edit!
+
 #ifndef Py_CORE_UOP_IDS_H
 #define Py_CORE_UOP_IDS_H
 #ifdef __cplusplus
@@ -11,7 +12,6 @@ extern "C" {
 #define _EXIT_TRACE 300
 #define _SET_IP 301
 #define _NOP NOP
-#define _RESUME RESUME
 #define _RESUME_CHECK RESUME_CHECK
 #define _INSTRUMENTED_RESUME INSTRUMENTED_RESUME
 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK
@@ -24,13 +24,10 @@ extern "C" {
 #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
 #define _POP_TOP POP_TOP
 #define _PUSH_NULL PUSH_NULL
-#define _INSTRUMENTED_END_FOR INSTRUMENTED_END_FOR
 #define _END_SEND END_SEND
-#define _INSTRUMENTED_END_SEND INSTRUMENTED_END_SEND
 #define _UNARY_NEGATIVE UNARY_NEGATIVE
 #define _UNARY_NOT UNARY_NOT
-#define _SPECIALIZE_TO_BOOL 302
-#define _TO_BOOL 303
+#define _TO_BOOL 302
 #define _TO_BOOL_BOOL TO_BOOL_BOOL
 #define _TO_BOOL_INT TO_BOOL_INT
 #define _TO_BOOL_LIST TO_BOOL_LIST
@@ -38,19 +35,17 @@ extern "C" {
 #define _TO_BOOL_STR TO_BOOL_STR
 #define _TO_BOOL_ALWAYS_TRUE TO_BOOL_ALWAYS_TRUE
 #define _UNARY_INVERT UNARY_INVERT
-#define _GUARD_BOTH_INT 304
-#define _BINARY_OP_MULTIPLY_INT 305
-#define _BINARY_OP_ADD_INT 306
-#define _BINARY_OP_SUBTRACT_INT 307
-#define _GUARD_BOTH_FLOAT 308
-#define _BINARY_OP_MULTIPLY_FLOAT 309
-#define _BINARY_OP_ADD_FLOAT 310
-#define _BINARY_OP_SUBTRACT_FLOAT 311
-#define _GUARD_BOTH_UNICODE 312
-#define _BINARY_OP_ADD_UNICODE 313
-#define _BINARY_OP_INPLACE_ADD_UNICODE 314
-#define _SPECIALIZE_BINARY_SUBSCR 315
-#define _BINARY_SUBSCR 316
+#define _GUARD_BOTH_INT 303
+#define _BINARY_OP_MULTIPLY_INT 304
+#define _BINARY_OP_ADD_INT 305
+#define _BINARY_OP_SUBTRACT_INT 306
+#define _GUARD_BOTH_FLOAT 307
+#define _BINARY_OP_MULTIPLY_FLOAT 308
+#define _BINARY_OP_ADD_FLOAT 309
+#define _BINARY_OP_SUBTRACT_FLOAT 310
+#define _GUARD_BOTH_UNICODE 311
+#define _BINARY_OP_ADD_UNICODE 312
+#define _BINARY_SUBSCR 313
 #define _BINARY_SLICE BINARY_SLICE
 #define _STORE_SLICE STORE_SLICE
 #define _BINARY_SUBSCR_LIST_INT BINARY_SUBSCR_LIST_INT
@@ -60,54 +55,43 @@ extern "C" {
 #define _BINARY_SUBSCR_GETITEM BINARY_SUBSCR_GETITEM
 #define _LIST_APPEND LIST_APPEND
 #define _SET_ADD SET_ADD
-#define _SPECIALIZE_STORE_SUBSCR 317
-#define _STORE_SUBSCR 318
+#define _STORE_SUBSCR 314
 #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
 #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
 #define _DELETE_SUBSCR DELETE_SUBSCR
 #define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
 #define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
-#define _RAISE_VARARGS RAISE_VARARGS
-#define _INTERPRETER_EXIT INTERPRETER_EXIT
-#define _POP_FRAME 319
+#define _POP_FRAME 315
 #define _INSTRUMENTED_RETURN_VALUE INSTRUMENTED_RETURN_VALUE
 #define _INSTRUMENTED_RETURN_CONST INSTRUMENTED_RETURN_CONST
 #define _GET_AITER GET_AITER
 #define _GET_ANEXT GET_ANEXT
 #define _GET_AWAITABLE GET_AWAITABLE
-#define _SPECIALIZE_SEND 320
-#define _SEND 321
+#define _SEND 316
 #define _SEND_GEN SEND_GEN
 #define _INSTRUMENTED_YIELD_VALUE INSTRUMENTED_YIELD_VALUE
-#define _YIELD_VALUE YIELD_VALUE
 #define _POP_EXCEPT POP_EXCEPT
-#define _RERAISE RERAISE
-#define _END_ASYNC_FOR END_ASYNC_FOR
-#define _CLEANUP_THROW CLEANUP_THROW
 #define _LOAD_ASSERTION_ERROR LOAD_ASSERTION_ERROR
 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
 #define _STORE_NAME STORE_NAME
 #define _DELETE_NAME DELETE_NAME
-#define _SPECIALIZE_UNPACK_SEQUENCE 322
-#define _UNPACK_SEQUENCE 323
+#define _UNPACK_SEQUENCE 317
 #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
 #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
 #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
 #define _UNPACK_EX UNPACK_EX
-#define _SPECIALIZE_STORE_ATTR 324
-#define _STORE_ATTR 325
+#define _STORE_ATTR 318
 #define _DELETE_ATTR DELETE_ATTR
 #define _STORE_GLOBAL STORE_GLOBAL
 #define _DELETE_GLOBAL DELETE_GLOBAL
 #define _LOAD_LOCALS LOAD_LOCALS
 #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
 #define _LOAD_NAME LOAD_NAME
-#define _SPECIALIZE_LOAD_GLOBAL 326
-#define _LOAD_GLOBAL 327
-#define _GUARD_GLOBALS_VERSION 328
-#define _GUARD_BUILTINS_VERSION 329
-#define _LOAD_GLOBAL_MODULE 330
-#define _LOAD_GLOBAL_BUILTINS 331
+#define _LOAD_GLOBAL 319
+#define _GUARD_GLOBALS_VERSION 320
+#define _GUARD_BUILTINS_VERSION 321
+#define _LOAD_GLOBAL_MODULE 322
+#define _LOAD_GLOBAL_BUILTINS 323
 #define _DELETE_FAST DELETE_FAST
 #define _MAKE_CELL MAKE_CELL
 #define _DELETE_DEREF DELETE_DEREF
@@ -128,30 +112,26 @@ extern "C" {
 #define _DICT_MERGE DICT_MERGE
 #define _MAP_ADD MAP_ADD
 #define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
-#define _SPECIALIZE_LOAD_SUPER_ATTR 332
-#define _LOAD_SUPER_ATTR 333
 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
 #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _SPECIALIZE_LOAD_ATTR 334
-#define _LOAD_ATTR 335
-#define _GUARD_TYPE_VERSION 336
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES 337
-#define _LOAD_ATTR_INSTANCE_VALUE 338
-#define _CHECK_ATTR_MODULE 339
-#define _LOAD_ATTR_MODULE 340
-#define _CHECK_ATTR_WITH_HINT 341
-#define _LOAD_ATTR_WITH_HINT 342
-#define _LOAD_ATTR_SLOT 343
-#define _CHECK_ATTR_CLASS 344
-#define _LOAD_ATTR_CLASS 345
+#define _LOAD_ATTR 324
+#define _GUARD_TYPE_VERSION 325
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES 326
+#define _LOAD_ATTR_INSTANCE_VALUE 327
+#define _CHECK_ATTR_MODULE 328
+#define _LOAD_ATTR_MODULE 329
+#define _CHECK_ATTR_WITH_HINT 330
+#define _LOAD_ATTR_WITH_HINT 331
+#define _LOAD_ATTR_SLOT 332
+#define _CHECK_ATTR_CLASS 333
+#define _LOAD_ATTR_CLASS 334
 #define _LOAD_ATTR_PROPERTY LOAD_ATTR_PROPERTY
 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _GUARD_DORV_VALUES 346
-#define _STORE_ATTR_INSTANCE_VALUE 347
+#define _GUARD_DORV_VALUES 335
+#define _STORE_ATTR_INSTANCE_VALUE 336
 #define _STORE_ATTR_WITH_HINT STORE_ATTR_WITH_HINT
-#define _STORE_ATTR_SLOT 348
-#define _SPECIALIZE_COMPARE_OP 349
-#define _COMPARE_OP 350
+#define _STORE_ATTR_SLOT 337
+#define _COMPARE_OP 338
 #define _COMPARE_OP_FLOAT COMPARE_OP_FLOAT
 #define _COMPARE_OP_INT COMPARE_OP_INT
 #define _COMPARE_OP_STR COMPARE_OP_STR
@@ -159,15 +139,10 @@ extern "C" {
 #define _CONTAINS_OP CONTAINS_OP
 #define _CHECK_EG_MATCH CHECK_EG_MATCH
 #define _CHECK_EXC_MATCH CHECK_EXC_MATCH
-#define _IMPORT_NAME IMPORT_NAME
-#define _IMPORT_FROM IMPORT_FROM
-#define _JUMP_FORWARD JUMP_FORWARD
 #define _JUMP_BACKWARD JUMP_BACKWARD
-#define _ENTER_EXECUTOR ENTER_EXECUTOR
-#define _POP_JUMP_IF_FALSE 351
-#define _POP_JUMP_IF_TRUE 352
-#define _IS_NONE 353
-#define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT
+#define _POP_JUMP_IF_FALSE 339
+#define _POP_JUMP_IF_TRUE 340
+#define _IS_NONE 341
 #define _GET_LEN GET_LEN
 #define _MATCH_CLASS MATCH_CLASS
 #define _MATCH_MAPPING MATCH_MAPPING
@@ -175,45 +150,43 @@ extern "C" {
 #define _MATCH_KEYS MATCH_KEYS
 #define _GET_ITER GET_ITER
 #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
-#define _SPECIALIZE_FOR_ITER 354
-#define _FOR_ITER 355
-#define _FOR_ITER_TIER_TWO 356
+#define _FOR_ITER 342
+#define _FOR_ITER_TIER_TWO 343
 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
-#define _ITER_CHECK_LIST 357
-#define _ITER_JUMP_LIST 358
-#define _GUARD_NOT_EXHAUSTED_LIST 359
-#define _ITER_NEXT_LIST 360
-#define _ITER_CHECK_TUPLE 361
-#define _ITER_JUMP_TUPLE 362
-#define _GUARD_NOT_EXHAUSTED_TUPLE 363
-#define _ITER_NEXT_TUPLE 364
-#define _ITER_CHECK_RANGE 365
-#define _ITER_JUMP_RANGE 366
-#define _GUARD_NOT_EXHAUSTED_RANGE 367
-#define _ITER_NEXT_RANGE 368
+#define _ITER_CHECK_LIST 344
+#define _ITER_JUMP_LIST 345
+#define _GUARD_NOT_EXHAUSTED_LIST 346
+#define _ITER_NEXT_LIST 347
+#define _ITER_CHECK_TUPLE 348
+#define _ITER_JUMP_TUPLE 349
+#define _GUARD_NOT_EXHAUSTED_TUPLE 350
+#define _ITER_NEXT_TUPLE 351
+#define _ITER_CHECK_RANGE 352
+#define _ITER_JUMP_RANGE 353
+#define _GUARD_NOT_EXHAUSTED_RANGE 354
+#define _ITER_NEXT_RANGE 355
 #define _FOR_ITER_GEN FOR_ITER_GEN
 #define _BEFORE_ASYNC_WITH BEFORE_ASYNC_WITH
 #define _BEFORE_WITH BEFORE_WITH
 #define _WITH_EXCEPT_START WITH_EXCEPT_START
 #define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 369
-#define _GUARD_KEYS_VERSION 370
-#define _LOAD_ATTR_METHOD_WITH_VALUES 371
-#define _LOAD_ATTR_METHOD_NO_DICT 372
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 373
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 374
-#define _CHECK_ATTR_METHOD_LAZY_DICT 375
-#define _LOAD_ATTR_METHOD_LAZY_DICT 376
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 356
+#define _GUARD_KEYS_VERSION 357
+#define _LOAD_ATTR_METHOD_WITH_VALUES 358
+#define _LOAD_ATTR_METHOD_NO_DICT 359
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 360
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 361
+#define _CHECK_ATTR_METHOD_LAZY_DICT 362
+#define _LOAD_ATTR_METHOD_LAZY_DICT 363
 #define _INSTRUMENTED_CALL INSTRUMENTED_CALL
-#define _SPECIALIZE_CALL 377
-#define _CALL 378
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 379
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 380
-#define _CHECK_PEP_523 381
-#define _CHECK_FUNCTION_EXACT_ARGS 382
-#define _CHECK_STACK_SPACE 383
-#define _INIT_CALL_PY_EXACT_ARGS 384
-#define _PUSH_FRAME 385
+#define _CALL 364
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 365
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 366
+#define _CHECK_PEP_523 367
+#define _CHECK_FUNCTION_EXACT_ARGS 368
+#define _CHECK_STACK_SPACE 369
+#define _INIT_CALL_PY_EXACT_ARGS 370
+#define _PUSH_FRAME 371
 #define _CALL_PY_WITH_DEFAULTS CALL_PY_WITH_DEFAULTS
 #define _CALL_TYPE_1 CALL_TYPE_1
 #define _CALL_STR_1 CALL_STR_1
@@ -226,7 +199,6 @@ extern "C" {
 #define _CALL_BUILTIN_FAST_WITH_KEYWORDS CALL_BUILTIN_FAST_WITH_KEYWORDS
 #define _CALL_LEN CALL_LEN
 #define _CALL_ISINSTANCE CALL_ISINSTANCE
-#define _CALL_LIST_APPEND CALL_LIST_APPEND
 #define _CALL_METHOD_DESCRIPTOR_O CALL_METHOD_DESCRIPTOR_O
 #define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
 #define _CALL_METHOD_DESCRIPTOR_NOARGS CALL_METHOD_DESCRIPTOR_NOARGS
@@ -237,14 +209,12 @@ extern "C" {
 #define _CALL_FUNCTION_EX CALL_FUNCTION_EX
 #define _MAKE_FUNCTION MAKE_FUNCTION
 #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
-#define _RETURN_GENERATOR RETURN_GENERATOR
 #define _BUILD_SLICE BUILD_SLICE
 #define _CONVERT_VALUE CONVERT_VALUE
 #define _FORMAT_SIMPLE FORMAT_SIMPLE
 #define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
 #define _COPY COPY
-#define _SPECIALIZE_BINARY_OP 386
-#define _BINARY_OP 387
+#define _BINARY_OP 372
 #define _SWAP SWAP
 #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
 #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -253,16 +223,17 @@ extern "C" {
 #define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
 #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
 #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
-#define _GUARD_IS_TRUE_POP 388
-#define _GUARD_IS_FALSE_POP 389
-#define _GUARD_IS_NONE_POP 390
-#define _GUARD_IS_NOT_NONE_POP 391
-#define _JUMP_TO_TOP 392
-#define _SAVE_RETURN_OFFSET 393
-#define _INSERT 394
-#define _CHECK_VALIDITY 395
+#define _GUARD_IS_TRUE_POP 373
+#define _GUARD_IS_FALSE_POP 374
+#define _GUARD_IS_NONE_POP 375
+#define _GUARD_IS_NOT_NONE_POP 376
+#define _JUMP_TO_TOP 377
+#define _SAVE_RETURN_OFFSET 378
+#define _INSERT 379
+#define _CHECK_VALIDITY 380
+#define MAX_UOP_ID 380
 
 #ifdef __cplusplus
 }
 #endif
-#endif /* !Py_OPCODE_IDS_H */
+#endif /* !Py_CORE_UOP_IDS_H */
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
new file mode 100644 (file)
index 0000000..300bd3b
--- /dev/null
@@ -0,0 +1,403 @@
+// This file is generated by Tools/cases_generator/uop_metadata_generator.py
+// from:
+//   Python/bytecodes.c
+// Do not edit!
+
+#ifndef Py_CORE_UOP_METADATA_H
+#define Py_CORE_UOP_METADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "pycore_uop_ids.h"
+extern const uint16_t _PyUop_Flags[MAX_UOP_ID+1];
+extern const char * const _PyOpcode_uop_name[MAX_UOP_ID+1];
+
+#ifdef NEED_OPCODE_METADATA
+const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
+    [_NOP] = 0,
+    [_RESUME_CHECK] = HAS_DEOPT_FLAG,
+    [_LOAD_FAST_CHECK] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG,
+    [_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+    [_LOAD_FAST_AND_CLEAR] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+    [_LOAD_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+    [_LOAD_CONST] = HAS_ARG_FLAG | HAS_CONST_FLAG,
+    [_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+    [_STORE_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+    [_STORE_FAST_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+    [_POP_TOP] = 0,
+    [_PUSH_NULL] = 0,
+    [_END_SEND] = 0,
+    [_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_UNARY_NOT] = 0,
+    [_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_TO_BOOL_BOOL] = HAS_DEOPT_FLAG,
+    [_TO_BOOL_INT] = HAS_DEOPT_FLAG,
+    [_TO_BOOL_LIST] = HAS_DEOPT_FLAG,
+    [_TO_BOOL_NONE] = HAS_DEOPT_FLAG,
+    [_TO_BOOL_STR] = HAS_DEOPT_FLAG,
+    [_TO_BOOL_ALWAYS_TRUE] = HAS_DEOPT_FLAG,
+    [_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GUARD_BOTH_INT] = HAS_DEOPT_FLAG,
+    [_BINARY_OP_MULTIPLY_INT] = HAS_ERROR_FLAG,
+    [_BINARY_OP_ADD_INT] = HAS_ERROR_FLAG,
+    [_BINARY_OP_SUBTRACT_INT] = HAS_ERROR_FLAG,
+    [_GUARD_BOTH_FLOAT] = HAS_DEOPT_FLAG,
+    [_BINARY_OP_MULTIPLY_FLOAT] = 0,
+    [_BINARY_OP_ADD_FLOAT] = 0,
+    [_BINARY_OP_SUBTRACT_FLOAT] = 0,
+    [_GUARD_BOTH_UNICODE] = HAS_DEOPT_FLAG,
+    [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BINARY_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BINARY_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG,
+    [_BINARY_SUBSCR_STR_INT] = HAS_DEOPT_FLAG,
+    [_BINARY_SUBSCR_TUPLE_INT] = HAS_DEOPT_FLAG,
+    [_BINARY_SUBSCR_DICT] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LIST_APPEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+    [_SET_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_SUBSCR_DICT] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_POP_FRAME] = HAS_ESCAPES_FLAG,
+    [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GET_AWAITABLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_POP_EXCEPT] = HAS_ESCAPES_FLAG,
+    [_LOAD_ASSERTION_ERROR] = 0,
+    [_LOAD_BUILD_CLASS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DELETE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_UNPACK_SEQUENCE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_UNPACK_EX] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DELETE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DELETE_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_LOCALS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_FROM_DICT_OR_GLOBALS] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG,
+    [_GUARD_BUILTINS_VERSION] = HAS_DEOPT_FLAG,
+    [_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_DELETE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG,
+    [_MAKE_CELL] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DELETE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_FROM_DICT_OR_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_STORE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG,
+    [_COPY_FREE_VARS] = HAS_ARG_FLAG,
+    [_BUILD_STRING] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BUILD_TUPLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BUILD_LIST] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LIST_EXTEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_SET_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BUILD_SET] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BUILD_MAP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_SETUP_ANNOTATIONS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BUILD_CONST_KEY_MAP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DICT_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GUARD_TYPE_VERSION] = HAS_DEOPT_FLAG,
+    [_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_INSTANCE_VALUE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_CHECK_ATTR_MODULE] = HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_CHECK_ATTR_WITH_HINT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_ATTR_SLOT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_CHECK_ATTR_CLASS] = HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_CLASS] = HAS_ARG_FLAG,
+    [_GUARD_DORV_VALUES] = HAS_DEOPT_FLAG,
+    [_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG,
+    [_STORE_ATTR_SLOT] = HAS_ESCAPES_FLAG,
+    [_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_COMPARE_OP_FLOAT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+    [_COMPARE_OP_INT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+    [_COMPARE_OP_STR] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
+    [_IS_OP] = HAS_ARG_FLAG,
+    [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CHECK_EG_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CHECK_EXC_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_IS_NONE] = 0,
+    [_GET_LEN] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_MATCH_MAPPING] = 0,
+    [_MATCH_SEQUENCE] = 0,
+    [_MATCH_KEYS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GET_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_GET_YIELD_FROM_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_FOR_ITER_TIER_TWO] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_ITER_CHECK_LIST] = HAS_DEOPT_FLAG,
+    [_GUARD_NOT_EXHAUSTED_LIST] = HAS_DEOPT_FLAG,
+    [_ITER_NEXT_LIST] = 0,
+    [_ITER_CHECK_TUPLE] = HAS_DEOPT_FLAG,
+    [_GUARD_NOT_EXHAUSTED_TUPLE] = HAS_DEOPT_FLAG,
+    [_ITER_NEXT_TUPLE] = 0,
+    [_ITER_CHECK_RANGE] = HAS_DEOPT_FLAG,
+    [_GUARD_NOT_EXHAUSTED_RANGE] = HAS_DEOPT_FLAG,
+    [_ITER_NEXT_RANGE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BEFORE_ASYNC_WITH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_BEFORE_WITH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_WITH_EXCEPT_START] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_PUSH_EXC_INFO] = 0,
+    [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG,
+    [_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+    [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG,
+    [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_FLAG,
+    [_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
+    [_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+    [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG,
+    [_CHECK_PEP_523] = HAS_DEOPT_FLAG,
+    [_CHECK_FUNCTION_EXACT_ARGS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_CHECK_STACK_SPACE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_INIT_CALL_PY_EXACT_ARGS] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+    [_PUSH_FRAME] = 0,
+    [_CALL_TYPE_1] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+    [_CALL_STR_1] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_EXIT_INIT_CHECK] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_BUILTIN_CLASS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG,
+    [_CALL_BUILTIN_O] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_BUILTIN_FAST] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_LEN] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_ISINSTANCE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_METHOD_DESCRIPTOR_O] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_METHOD_DESCRIPTOR_NOARGS] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CALL_METHOD_DESCRIPTOR_FAST] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+    [_BUILD_SLICE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_CONVERT_VALUE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+    [_FORMAT_SIMPLE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_FORMAT_WITH_SPEC] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+    [_COPY] = HAS_ARG_FLAG,
+    [_BINARY_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+    [_SWAP] = HAS_ARG_FLAG,
+    [_GUARD_IS_TRUE_POP] = HAS_DEOPT_FLAG,
+    [_GUARD_IS_FALSE_POP] = HAS_DEOPT_FLAG,
+    [_GUARD_IS_NONE_POP] = HAS_DEOPT_FLAG,
+    [_GUARD_IS_NOT_NONE_POP] = HAS_DEOPT_FLAG,
+    [_JUMP_TO_TOP] = HAS_EVAL_BREAK_FLAG,
+    [_SET_IP] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+    [_SAVE_RETURN_OFFSET] = HAS_ARG_FLAG,
+    [_EXIT_TRACE] = HAS_DEOPT_FLAG,
+    [_INSERT] = HAS_ARG_FLAG,
+    [_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
+};
+
+const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
+    [_BEFORE_ASYNC_WITH] = "_BEFORE_ASYNC_WITH",
+    [_BEFORE_WITH] = "_BEFORE_WITH",
+    [_BINARY_OP] = "_BINARY_OP",
+    [_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
+    [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
+    [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
+    [_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
+    [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
+    [_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
+    [_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
+    [_BINARY_SLICE] = "_BINARY_SLICE",
+    [_BINARY_SUBSCR] = "_BINARY_SUBSCR",
+    [_BINARY_SUBSCR_DICT] = "_BINARY_SUBSCR_DICT",
+    [_BINARY_SUBSCR_LIST_INT] = "_BINARY_SUBSCR_LIST_INT",
+    [_BINARY_SUBSCR_STR_INT] = "_BINARY_SUBSCR_STR_INT",
+    [_BINARY_SUBSCR_TUPLE_INT] = "_BINARY_SUBSCR_TUPLE_INT",
+    [_BUILD_CONST_KEY_MAP] = "_BUILD_CONST_KEY_MAP",
+    [_BUILD_LIST] = "_BUILD_LIST",
+    [_BUILD_MAP] = "_BUILD_MAP",
+    [_BUILD_SET] = "_BUILD_SET",
+    [_BUILD_SLICE] = "_BUILD_SLICE",
+    [_BUILD_STRING] = "_BUILD_STRING",
+    [_BUILD_TUPLE] = "_BUILD_TUPLE",
+    [_CALL_BUILTIN_CLASS] = "_CALL_BUILTIN_CLASS",
+    [_CALL_BUILTIN_FAST] = "_CALL_BUILTIN_FAST",
+    [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = "_CALL_BUILTIN_FAST_WITH_KEYWORDS",
+    [_CALL_BUILTIN_O] = "_CALL_BUILTIN_O",
+    [_CALL_INTRINSIC_1] = "_CALL_INTRINSIC_1",
+    [_CALL_INTRINSIC_2] = "_CALL_INTRINSIC_2",
+    [_CALL_ISINSTANCE] = "_CALL_ISINSTANCE",
+    [_CALL_LEN] = "_CALL_LEN",
+    [_CALL_METHOD_DESCRIPTOR_FAST] = "_CALL_METHOD_DESCRIPTOR_FAST",
+    [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
+    [_CALL_METHOD_DESCRIPTOR_NOARGS] = "_CALL_METHOD_DESCRIPTOR_NOARGS",
+    [_CALL_METHOD_DESCRIPTOR_O] = "_CALL_METHOD_DESCRIPTOR_O",
+    [_CALL_STR_1] = "_CALL_STR_1",
+    [_CALL_TUPLE_1] = "_CALL_TUPLE_1",
+    [_CALL_TYPE_1] = "_CALL_TYPE_1",
+    [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
+    [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
+    [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
+    [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
+    [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
+    [_CHECK_EG_MATCH] = "_CHECK_EG_MATCH",
+    [_CHECK_EXC_MATCH] = "_CHECK_EXC_MATCH",
+    [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
+    [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
+    [_CHECK_PEP_523] = "_CHECK_PEP_523",
+    [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
+    [_CHECK_VALIDITY] = "_CHECK_VALIDITY",
+    [_COMPARE_OP] = "_COMPARE_OP",
+    [_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
+    [_COMPARE_OP_INT] = "_COMPARE_OP_INT",
+    [_COMPARE_OP_STR] = "_COMPARE_OP_STR",
+    [_CONTAINS_OP] = "_CONTAINS_OP",
+    [_CONVERT_VALUE] = "_CONVERT_VALUE",
+    [_COPY] = "_COPY",
+    [_COPY_FREE_VARS] = "_COPY_FREE_VARS",
+    [_DELETE_ATTR] = "_DELETE_ATTR",
+    [_DELETE_DEREF] = "_DELETE_DEREF",
+    [_DELETE_FAST] = "_DELETE_FAST",
+    [_DELETE_GLOBAL] = "_DELETE_GLOBAL",
+    [_DELETE_NAME] = "_DELETE_NAME",
+    [_DELETE_SUBSCR] = "_DELETE_SUBSCR",
+    [_DICT_MERGE] = "_DICT_MERGE",
+    [_DICT_UPDATE] = "_DICT_UPDATE",
+    [_END_SEND] = "_END_SEND",
+    [_EXIT_INIT_CHECK] = "_EXIT_INIT_CHECK",
+    [_EXIT_TRACE] = "_EXIT_TRACE",
+    [_FORMAT_SIMPLE] = "_FORMAT_SIMPLE",
+    [_FORMAT_WITH_SPEC] = "_FORMAT_WITH_SPEC",
+    [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO",
+    [_GET_AITER] = "_GET_AITER",
+    [_GET_ANEXT] = "_GET_ANEXT",
+    [_GET_AWAITABLE] = "_GET_AWAITABLE",
+    [_GET_ITER] = "_GET_ITER",
+    [_GET_LEN] = "_GET_LEN",
+    [_GET_YIELD_FROM_ITER] = "_GET_YIELD_FROM_ITER",
+    [_GUARD_BOTH_FLOAT] = "_GUARD_BOTH_FLOAT",
+    [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT",
+    [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE",
+    [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION",
+    [_GUARD_DORV_VALUES] = "_GUARD_DORV_VALUES",
+    [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT",
+    [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
+    [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP",
+    [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP",
+    [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP",
+    [_GUARD_IS_TRUE_POP] = "_GUARD_IS_TRUE_POP",
+    [_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION",
+    [_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_EXHAUSTED_LIST",
+    [_GUARD_NOT_EXHAUSTED_RANGE] = "_GUARD_NOT_EXHAUSTED_RANGE",
+    [_GUARD_NOT_EXHAUSTED_TUPLE] = "_GUARD_NOT_EXHAUSTED_TUPLE",
+    [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION",
+    [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS",
+    [_INIT_CALL_PY_EXACT_ARGS] = "_INIT_CALL_PY_EXACT_ARGS",
+    [_INSERT] = "_INSERT",
+    [_IS_NONE] = "_IS_NONE",
+    [_IS_OP] = "_IS_OP",
+    [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
+    [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE",
+    [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE",
+    [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST",
+    [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE",
+    [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE",
+    [_JUMP_TO_TOP] = "_JUMP_TO_TOP",
+    [_LIST_APPEND] = "_LIST_APPEND",
+    [_LIST_EXTEND] = "_LIST_EXTEND",
+    [_LOAD_ASSERTION_ERROR] = "_LOAD_ASSERTION_ERROR",
+    [_LOAD_ATTR] = "_LOAD_ATTR",
+    [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
+    [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
+    [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
+    [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
+    [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
+    [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
+    [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
+    [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
+    [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
+    [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
+    [_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
+    [_LOAD_CONST] = "_LOAD_CONST",
+    [_LOAD_DEREF] = "_LOAD_DEREF",
+    [_LOAD_FAST] = "_LOAD_FAST",
+    [_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR",
+    [_LOAD_FAST_CHECK] = "_LOAD_FAST_CHECK",
+    [_LOAD_FAST_LOAD_FAST] = "_LOAD_FAST_LOAD_FAST",
+    [_LOAD_FROM_DICT_OR_DEREF] = "_LOAD_FROM_DICT_OR_DEREF",
+    [_LOAD_FROM_DICT_OR_GLOBALS] = "_LOAD_FROM_DICT_OR_GLOBALS",
+    [_LOAD_GLOBAL] = "_LOAD_GLOBAL",
+    [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS",
+    [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
+    [_LOAD_LOCALS] = "_LOAD_LOCALS",
+    [_LOAD_NAME] = "_LOAD_NAME",
+    [_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR",
+    [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD",
+    [_MAKE_CELL] = "_MAKE_CELL",
+    [_MAKE_FUNCTION] = "_MAKE_FUNCTION",
+    [_MAP_ADD] = "_MAP_ADD",
+    [_MATCH_CLASS] = "_MATCH_CLASS",
+    [_MATCH_KEYS] = "_MATCH_KEYS",
+    [_MATCH_MAPPING] = "_MATCH_MAPPING",
+    [_MATCH_SEQUENCE] = "_MATCH_SEQUENCE",
+    [_NOP] = "_NOP",
+    [_POP_EXCEPT] = "_POP_EXCEPT",
+    [_POP_FRAME] = "_POP_FRAME",
+    [_POP_TOP] = "_POP_TOP",
+    [_PUSH_EXC_INFO] = "_PUSH_EXC_INFO",
+    [_PUSH_FRAME] = "_PUSH_FRAME",
+    [_PUSH_NULL] = "_PUSH_NULL",
+    [_RESUME_CHECK] = "_RESUME_CHECK",
+    [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET",
+    [_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS",
+    [_SET_ADD] = "_SET_ADD",
+    [_SET_FUNCTION_ATTRIBUTE] = "_SET_FUNCTION_ATTRIBUTE",
+    [_SET_IP] = "_SET_IP",
+    [_SET_UPDATE] = "_SET_UPDATE",
+    [_STORE_ATTR] = "_STORE_ATTR",
+    [_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
+    [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
+    [_STORE_DEREF] = "_STORE_DEREF",
+    [_STORE_FAST] = "_STORE_FAST",
+    [_STORE_FAST_LOAD_FAST] = "_STORE_FAST_LOAD_FAST",
+    [_STORE_FAST_STORE_FAST] = "_STORE_FAST_STORE_FAST",
+    [_STORE_GLOBAL] = "_STORE_GLOBAL",
+    [_STORE_NAME] = "_STORE_NAME",
+    [_STORE_SLICE] = "_STORE_SLICE",
+    [_STORE_SUBSCR] = "_STORE_SUBSCR",
+    [_STORE_SUBSCR_DICT] = "_STORE_SUBSCR_DICT",
+    [_STORE_SUBSCR_LIST_INT] = "_STORE_SUBSCR_LIST_INT",
+    [_SWAP] = "_SWAP",
+    [_TO_BOOL] = "_TO_BOOL",
+    [_TO_BOOL_ALWAYS_TRUE] = "_TO_BOOL_ALWAYS_TRUE",
+    [_TO_BOOL_BOOL] = "_TO_BOOL_BOOL",
+    [_TO_BOOL_INT] = "_TO_BOOL_INT",
+    [_TO_BOOL_LIST] = "_TO_BOOL_LIST",
+    [_TO_BOOL_NONE] = "_TO_BOOL_NONE",
+    [_TO_BOOL_STR] = "_TO_BOOL_STR",
+    [_UNARY_INVERT] = "_UNARY_INVERT",
+    [_UNARY_NEGATIVE] = "_UNARY_NEGATIVE",
+    [_UNARY_NOT] = "_UNARY_NOT",
+    [_UNPACK_EX] = "_UNPACK_EX",
+    [_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE",
+    [_UNPACK_SEQUENCE_LIST] = "_UNPACK_SEQUENCE_LIST",
+    [_UNPACK_SEQUENCE_TUPLE] = "_UNPACK_SEQUENCE_TUPLE",
+    [_UNPACK_SEQUENCE_TWO_TUPLE] = "_UNPACK_SEQUENCE_TWO_TUPLE",
+    [_WITH_EXCEPT_START] = "_WITH_EXCEPT_START",
+};
+#endif // NEED_OPCODE_METADATA
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_UOP_METADATA_H */
index e2e27ca00fd47bfac7347e02154a56043c9a0635..fe969342ee79e75634a81942e7c8c3fb7c879f44 100644 (file)
@@ -231,7 +231,7 @@ extern "C" {
 #define SETUP_WITH                             266
 #define STORE_FAST_MAYBE_NULL                  267
 
-#define HAVE_ARGUMENT                           45
+#define HAVE_ARGUMENT                           44
 #define MIN_INSTRUMENTED_OPCODE                236
 
 #ifdef __cplusplus
index 5dd06ae487dfcfe8656c116f69f93e342446de65..fdb099bd0c2ecfab252b8723fce6e6099f5421a1 100644 (file)
@@ -1,8 +1,7 @@
-# This file is generated by Tools/cases_generator/generate_cases.py
+# This file is generated by Tools/cases_generator/py_metadata_generator.py
 # from:
 #   Python/bytecodes.c
 # Do not edit!
-
 _specializations = {
     "RESUME": [
         "RESUME_CHECK",
@@ -23,6 +22,7 @@ _specializations = {
         "BINARY_OP_ADD_FLOAT",
         "BINARY_OP_SUBTRACT_FLOAT",
         "BINARY_OP_ADD_UNICODE",
+        "BINARY_OP_INPLACE_ADD_UNICODE",
     ],
     "BINARY_SUBSCR": [
         "BINARY_SUBSCR_DICT",
@@ -103,14 +103,11 @@ _specializations = {
     ],
 }
 
-# An irregular case:
-_specializations["BINARY_OP"].append("BINARY_OP_INPLACE_ADD_UNICODE")
-
 _specialized_opmap = {
-    'BINARY_OP_INPLACE_ADD_UNICODE': 3,
     'BINARY_OP_ADD_FLOAT': 150,
     'BINARY_OP_ADD_INT': 151,
     'BINARY_OP_ADD_UNICODE': 152,
+    'BINARY_OP_INPLACE_ADD_UNICODE': 3,
     'BINARY_OP_MULTIPLY_FLOAT': 153,
     'BINARY_OP_MULTIPLY_INT': 154,
     'BINARY_OP_SUBTRACT_FLOAT': 155,
@@ -181,6 +178,9 @@ _specialized_opmap = {
 
 opmap = {
     'CACHE': 0,
+    'RESERVED': 17,
+    'RESUME': 149,
+    'INSTRUMENTED_LINE': 254,
     'BEFORE_ASYNC_WITH': 1,
     'BEFORE_WITH': 2,
     'BINARY_SLICE': 4,
@@ -196,7 +196,6 @@ opmap = {
     'FORMAT_SIMPLE': 14,
     'FORMAT_WITH_SPEC': 15,
     'GET_AITER': 16,
-    'RESERVED': 17,
     'GET_ANEXT': 18,
     'GET_ITER': 19,
     'GET_LEN': 20,
@@ -298,7 +297,6 @@ opmap = {
     'UNPACK_EX': 116,
     'UNPACK_SEQUENCE': 117,
     'YIELD_VALUE': 118,
-    'RESUME': 149,
     'INSTRUMENTED_RESUME': 236,
     'INSTRUMENTED_END_FOR': 237,
     'INSTRUMENTED_END_SEND': 238,
@@ -317,7 +315,6 @@ opmap = {
     'INSTRUMENTED_POP_JUMP_IF_FALSE': 251,
     'INSTRUMENTED_POP_JUMP_IF_NONE': 252,
     'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 253,
-    'INSTRUMENTED_LINE': 254,
     'JUMP': 256,
     'JUMP_NO_INTERRUPT': 257,
     'LOAD_CLOSURE': 258,
@@ -331,5 +328,6 @@ opmap = {
     'SETUP_WITH': 266,
     'STORE_FAST_MAYBE_NULL': 267,
 }
+
+HAVE_ARGUMENT = 44
 MIN_INSTRUMENTED_OPCODE = 236
-HAVE_ARGUMENT = 45
index 9f4731103c9413cec10ec61e37c5b1f092413bb9..5c8c0596610303b90c0d0ec6701653960865ab15 100644 (file)
@@ -176,6 +176,7 @@ class TestExecutorInvalidation(unittest.TestCase):
         with temporary_optimizer(opt):
             f()
         exe = get_first_executor(f)
+        self.assertIsNotNone(exe)
         self.assertTrue(exe.is_valid())
         _testinternalcapi.invalidate_executors(f.__code__)
         self.assertFalse(exe.is_valid())
@@ -196,7 +197,7 @@ class TestUops(unittest.TestCase):
         self.assertIsNotNone(ex)
         uops = {opname for opname, _, _ in ex}
         self.assertIn("_SET_IP", uops)
-        self.assertIn("LOAD_FAST", uops)
+        self.assertIn("_LOAD_FAST", uops)
 
     def test_extended_arg(self):
         "Check EXTENDED_ARG handling in superblock creation"
@@ -243,7 +244,7 @@ class TestUops(unittest.TestCase):
 
         ex = get_first_executor(many_vars)
         self.assertIsNotNone(ex)
-        self.assertIn(("LOAD_FAST", 259, 0), list(ex))
+        self.assertIn(("_LOAD_FAST", 259, 0), list(ex))
 
     def test_unspecialized_unpack(self):
         # An example of an unspecialized opcode
index 195fc0ddddecd30f8fce7bef90ff112ccebf41bc..92827ec3479526df1664462329343c9604a366cb 100644 (file)
@@ -1588,23 +1588,28 @@ regen-cases:
            $(srcdir)/Tools/cases_generator/generate_cases.py \
                $(CASESFLAG) \
                -t $(srcdir)/Python/opcode_targets.h.new \
-               -m $(srcdir)/Include/internal/pycore_opcode_metadata.h.new \
-               -p $(srcdir)/Lib/_opcode_metadata.py.new \
                -a $(srcdir)/Python/abstract_interp_cases.c.h.new \
                $(srcdir)/Python/bytecodes.c
-       $(PYTHON_FOR_REGEN) \
-           $(srcdir)/Tools/cases_generator/opcode_id_generator.py -o $(srcdir)/Include/opcode_ids.h.new $(srcdir)/Python/bytecodes.c
-       $(PYTHON_FOR_REGEN) \
-           $(srcdir)/Tools/cases_generator/uop_id_generator.py -o $(srcdir)/Include/internal/pycore_uop_ids.h.new $(srcdir)/Python/bytecodes.c
-       $(PYTHON_FOR_REGEN) \
-           $(srcdir)/Tools/cases_generator/tier1_generator.py -o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c
-       $(PYTHON_FOR_REGEN) \
-           $(srcdir)/Tools/cases_generator/tier2_generator.py -o $(srcdir)/Python/executor_cases.c.h.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/opcode_id_generator.py \
+           -o $(srcdir)/Include/opcode_ids.h.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/uop_id_generator.py \
+           -o $(srcdir)/Include/internal/pycore_uop_ids.h.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/py_metadata_generator.py \
+           -o $(srcdir)/Lib/_opcode_metadata.py.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier1_generator.py \
+           -o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier2_generator.py \
+           -o $(srcdir)/Python/executor_cases.c.h.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/opcode_metadata_generator.py \
+           -o $(srcdir)/Include/internal/pycore_opcode_metadata.h.new $(srcdir)/Python/bytecodes.c
+       $(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/uop_metadata_generator.py -o \
+           $(srcdir)/Include/internal/pycore_uop_metadata.h.new $(srcdir)/Python/bytecodes.c
        $(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new
        $(UPDATE_FILE) $(srcdir)/Include/opcode_ids.h $(srcdir)/Include/opcode_ids.h.new
        $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_uop_ids.h $(srcdir)/Include/internal/pycore_uop_ids.h.new
        $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new
        $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode_metadata.h $(srcdir)/Include/internal/pycore_opcode_metadata.h.new
+       $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_uop_metadata.h $(srcdir)/Include/internal/pycore_uop_metadata.h.new
        $(UPDATE_FILE) $(srcdir)/Python/executor_cases.c.h $(srcdir)/Python/executor_cases.c.h.new
        $(UPDATE_FILE) $(srcdir)/Python/abstract_interp_cases.c.h $(srcdir)/Python/abstract_interp_cases.c.h.new
        $(UPDATE_FILE) $(srcdir)/Lib/_opcode_metadata.py $(srcdir)/Lib/_opcode_metadata.py.new
index b6fb432aed4a3b43e2dc78f808813609de259229..569454ebf3b9cb03d27ba976d4bbf8005b542c36 100644 (file)
@@ -4,7 +4,7 @@
 #include "pycore_code.h"            // write_location_entry_start()
 #include "pycore_compile.h"
 #include "pycore_opcode_utils.h"    // IS_BACKWARDS_JUMP_OPCODE
-#include "pycore_opcode_metadata.h" // IS_PSEUDO_INSTR, _PyOpcode_Caches
+#include "pycore_opcode_metadata.h" // is_pseudo_target, _PyOpcode_Caches
 
 
 #define DEFAULT_CODE_SIZE 128
@@ -710,13 +710,13 @@ resolve_unconditional_jumps(instr_sequence *instrs)
         bool is_forward = (instr->i_oparg > i);
         switch(instr->i_opcode) {
             case JUMP:
-                assert(SAME_OPCODE_METADATA(JUMP, JUMP_FORWARD));
-                assert(SAME_OPCODE_METADATA(JUMP, JUMP_BACKWARD));
+                assert(is_pseudo_target(JUMP, JUMP_FORWARD));
+                assert(is_pseudo_target(JUMP, JUMP_BACKWARD));
                 instr->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
                 break;
             case JUMP_NO_INTERRUPT:
-                assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_FORWARD));
-                assert(SAME_OPCODE_METADATA(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
+                assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_FORWARD));
+                assert(is_pseudo_target(JUMP_NO_INTERRUPT, JUMP_BACKWARD_NO_INTERRUPT));
                 instr->i_opcode = is_forward ?
                     JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
                 break;
index 19e2268046fcdc733a25595d2e6f4b1975f43a3f..82d7a71d4989a4ce7ecd6a5977ec7a125af7aa24 100644 (file)
@@ -330,14 +330,14 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION */
         }
 
-        op(_TO_BOOL, (unused/2, value -- res)) {
+        op(_TO_BOOL, (value -- res)) {
             int err = PyObject_IsTrue(value);
             DECREF_INPUTS();
             ERROR_IF(err < 0, error);
             res = err ? Py_True : Py_False;
         }
 
-        macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + _TO_BOOL;
+        macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + unused/2 + _TO_BOOL;
 
         inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) {
             DEOPT_IF(!PyBool_Check(value));
@@ -416,7 +416,7 @@ dummy_func(
             DEOPT_IF(!PyLong_CheckExact(right));
         }
 
-        op(_BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             res = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right);
             _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -424,7 +424,7 @@ dummy_func(
             ERROR_IF(res == NULL, error);
         }
 
-        op(_BINARY_OP_ADD_INT, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_ADD_INT, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             res = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right);
             _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -432,7 +432,7 @@ dummy_func(
             ERROR_IF(res == NULL, error);
         }
 
-        op(_BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             res = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right);
             _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
@@ -441,18 +441,18 @@ dummy_func(
         }
 
         macro(BINARY_OP_MULTIPLY_INT) =
-            _GUARD_BOTH_INT + _BINARY_OP_MULTIPLY_INT;
+            _GUARD_BOTH_INT + unused/1 + _BINARY_OP_MULTIPLY_INT;
         macro(BINARY_OP_ADD_INT) =
-            _GUARD_BOTH_INT + _BINARY_OP_ADD_INT;
+            _GUARD_BOTH_INT + unused/1 + _BINARY_OP_ADD_INT;
         macro(BINARY_OP_SUBTRACT_INT) =
-            _GUARD_BOTH_INT + _BINARY_OP_SUBTRACT_INT;
+            _GUARD_BOTH_INT + unused/1 + _BINARY_OP_SUBTRACT_INT;
 
         op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) {
             DEOPT_IF(!PyFloat_CheckExact(left));
             DEOPT_IF(!PyFloat_CheckExact(right));
         }
 
-        op(_BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             double dres =
                 ((PyFloatObject *)left)->ob_fval *
@@ -460,7 +460,7 @@ dummy_func(
             DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res);
         }
 
-        op(_BINARY_OP_ADD_FLOAT, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             double dres =
                 ((PyFloatObject *)left)->ob_fval +
@@ -468,7 +468,7 @@ dummy_func(
             DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res);
         }
 
-        op(_BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             double dres =
                 ((PyFloatObject *)left)->ob_fval -
@@ -477,18 +477,18 @@ dummy_func(
         }
 
         macro(BINARY_OP_MULTIPLY_FLOAT) =
-            _GUARD_BOTH_FLOAT + _BINARY_OP_MULTIPLY_FLOAT;
+            _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_MULTIPLY_FLOAT;
         macro(BINARY_OP_ADD_FLOAT) =
-            _GUARD_BOTH_FLOAT + _BINARY_OP_ADD_FLOAT;
+            _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_ADD_FLOAT;
         macro(BINARY_OP_SUBTRACT_FLOAT) =
-            _GUARD_BOTH_FLOAT + _BINARY_OP_SUBTRACT_FLOAT;
+            _GUARD_BOTH_FLOAT + unused/1 + _BINARY_OP_SUBTRACT_FLOAT;
 
         op(_GUARD_BOTH_UNICODE, (left, right -- left, right)) {
             DEOPT_IF(!PyUnicode_CheckExact(left));
             DEOPT_IF(!PyUnicode_CheckExact(right));
         }
 
-        op(_BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) {
+        op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
             STAT_INC(BINARY_OP, hit);
             res = PyUnicode_Concat(left, right);
             _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc);
@@ -497,7 +497,7 @@ dummy_func(
         }
 
         macro(BINARY_OP_ADD_UNICODE) =
-            _GUARD_BOTH_UNICODE + _BINARY_OP_ADD_UNICODE;
+            _GUARD_BOTH_UNICODE + unused/1 + _BINARY_OP_ADD_UNICODE;
 
         // This is a subtle one. It's a super-instruction for
         // BINARY_OP_ADD_UNICODE followed by STORE_FAST
@@ -505,7 +505,7 @@ dummy_func(
         // So the inputs are the same as for all BINARY_OP
         // specializations, but there is no output.
         // At the end we just skip over the STORE_FAST.
-        op(_BINARY_OP_INPLACE_ADD_UNICODE, (unused/1, left, right --)) {
+        op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
             TIER_ONE_ONLY
             assert(next_instr->op.code == STORE_FAST);
             PyObject **target_local = &GETLOCAL(next_instr->op.arg);
@@ -533,7 +533,7 @@ dummy_func(
         }
 
         macro(BINARY_OP_INPLACE_ADD_UNICODE) =
-            _GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE;
+            _GUARD_BOTH_UNICODE + unused/1 + _BINARY_OP_INPLACE_ADD_UNICODE;
 
         family(BINARY_SUBSCR, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
             BINARY_SUBSCR_DICT,
@@ -1295,14 +1295,14 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION */
         }
 
-        op(_STORE_ATTR, (unused/3, v, owner --)) {
+        op(_STORE_ATTR, (v, owner --)) {
             PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
             int err = PyObject_SetAttr(owner, name, v);
             DECREF_INPUTS();
             ERROR_IF(err, error);
         }
 
-        macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + _STORE_ATTR;
+        macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + unused/3 + _STORE_ATTR;
 
         inst(DELETE_ATTR, (owner --)) {
             PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
@@ -1414,7 +1414,7 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION */
         }
 
-        op(_LOAD_GLOBAL, (unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) {
+        op(_LOAD_GLOBAL, ( -- res, null if (oparg & 1))) {
             PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
             if (PyDict_CheckExact(GLOBALS())
                 && PyDict_CheckExact(BUILTINS()))
@@ -1451,7 +1451,12 @@ dummy_func(
             null = NULL;
         }
 
-        macro(LOAD_GLOBAL) = _SPECIALIZE_LOAD_GLOBAL + _LOAD_GLOBAL;
+        macro(LOAD_GLOBAL) =
+            _SPECIALIZE_LOAD_GLOBAL +
+            counter/1 +
+            globals_version/1 +
+            builtins_version/1 +
+            _LOAD_GLOBAL;
 
         op(_GUARD_GLOBALS_VERSION, (version/1 --)) {
             PyDictObject *dict = (PyDictObject *)GLOBALS();
@@ -1853,7 +1858,7 @@ dummy_func(
             #endif  /* ENABLE_SPECIALIZATION */
         }
 
-        op(_LOAD_ATTR, (unused/8, owner -- attr, self_or_null if (oparg & 1))) {
+        op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
             PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
             if (oparg & 1) {
                 /* Designed to work in tandem with CALL, pushes two values. */
@@ -1886,7 +1891,10 @@ dummy_func(
             }
         }
 
-        macro(LOAD_ATTR) = _SPECIALIZE_LOAD_ATTR + _LOAD_ATTR;
+        macro(LOAD_ATTR) =
+            _SPECIALIZE_LOAD_ATTR +
+            unused/8 +
+            _LOAD_ATTR;
 
         pseudo(LOAD_METHOD) = {
             LOAD_ATTR,
@@ -2369,7 +2377,7 @@ dummy_func(
             stack_pointer = _PyFrame_GetStackPointer(frame);
         }
 
-        replaced op(_POP_JUMP_IF_FALSE, (unused/1, cond -- )) {
+        replaced op(_POP_JUMP_IF_FALSE, (cond -- )) {
             assert(PyBool_Check(cond));
             int flag = Py_IsFalse(cond);
             #if ENABLE_SPECIALIZATION
@@ -2378,7 +2386,7 @@ dummy_func(
             JUMPBY(oparg * flag);
         }
 
-        replaced op(_POP_JUMP_IF_TRUE, (unused/1, cond -- )) {
+        replaced op(_POP_JUMP_IF_TRUE, (cond -- )) {
             assert(PyBool_Check(cond));
             int flag = Py_IsTrue(cond);
             #if ENABLE_SPECIALIZATION
@@ -2397,13 +2405,13 @@ dummy_func(
             }
         }
 
-        macro(POP_JUMP_IF_TRUE) = _POP_JUMP_IF_TRUE;
+        macro(POP_JUMP_IF_TRUE) = unused/1 + _POP_JUMP_IF_TRUE;
 
-        macro(POP_JUMP_IF_FALSE) = _POP_JUMP_IF_FALSE;
+        macro(POP_JUMP_IF_FALSE) = unused/1 + _POP_JUMP_IF_FALSE;
 
-        macro(POP_JUMP_IF_NONE) = _IS_NONE + _POP_JUMP_IF_TRUE;
+        macro(POP_JUMP_IF_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_TRUE;
 
-        macro(POP_JUMP_IF_NOT_NONE) = _IS_NONE + _POP_JUMP_IF_FALSE;
+        macro(POP_JUMP_IF_NOT_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_FALSE;
 
         inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) {
             TIER_ONE_ONLY
@@ -3010,7 +3018,7 @@ dummy_func(
         }
 
         // When calling Python, inline the call using DISPATCH_INLINED().
-        op(_CALL, (unused/2, callable, self_or_null, args[oparg] -- res)) {
+        op(_CALL, (callable, self_or_null, args[oparg] -- res)) {
             // oparg counts all of the args, but *not* self:
             int total_args = oparg;
             if (self_or_null != NULL) {
@@ -3079,7 +3087,7 @@ dummy_func(
             CHECK_EVAL_BREAKER();
         }
 
-        macro(CALL) = _SPECIALIZE_CALL + _CALL;
+        macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL;
 
         op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
             DEOPT_IF(null != NULL);
index 27304d31e2794981d7e7427388396ddd57089676..1fea9747488102e79e3ae8260fb6c961bb44f370 100644 (file)
@@ -24,6 +24,7 @@
 #include "pycore_sysmodule.h"     // _PySys_Audit()
 #include "pycore_tuple.h"         // _PyTuple_ITEMS()
 #include "pycore_typeobject.h"    // _PySuper_Lookup()
+#include "pycore_uop_ids.h"       // Uops
 #include "pycore_uops.h"          // _PyUOpExecutorObject
 #include "pycore_pyerrors.h"
 
index 8b9e2f02048f1110813c87fbaa49e609c06aaaa9..65ac05ad58d4ddc9f4e8515208ad323764922be7 100644 (file)
@@ -796,35 +796,12 @@ stack_effect(int opcode, int oparg, int jump)
             // Specialized instructions are not supported.
             return PY_INVALID_STACK_EFFECT;
         }
-        int popped, pushed;
-        if (jump > 0) {
-            popped = _PyOpcode_num_popped(opcode, oparg, true);
-            pushed = _PyOpcode_num_pushed(opcode, oparg, true);
-        }
-        else {
-            popped = _PyOpcode_num_popped(opcode, oparg, false);
-            pushed = _PyOpcode_num_pushed(opcode, oparg, false);
-        }
+        int popped = _PyOpcode_num_popped(opcode, oparg);
+        int pushed = _PyOpcode_num_pushed(opcode, oparg);
         if (popped < 0 || pushed < 0) {
             return PY_INVALID_STACK_EFFECT;
         }
-        if (jump >= 0) {
-            return pushed - popped;
-        }
-        if (jump < 0) {
-            // Compute max(pushed - popped, alt_pushed - alt_popped)
-            int alt_popped = _PyOpcode_num_popped(opcode, oparg, true);
-            int alt_pushed = _PyOpcode_num_pushed(opcode, oparg, true);
-            if (alt_popped < 0 || alt_pushed < 0) {
-                return PY_INVALID_STACK_EFFECT;
-            }
-            int diff = pushed - popped;
-            int alt_diff = alt_pushed - alt_popped;
-            if (alt_diff > diff) {
-                return alt_diff;
-            }
-            return diff;
-        }
+        return pushed - popped;
     }
 
     // Pseudo ops
@@ -1125,7 +1102,7 @@ compiler_addop_name(struct compiler_unit *u, location loc,
         arg <<= 1;
     }
     if (opcode == LOAD_METHOD) {
-        assert(SAME_OPCODE_METADATA(LOAD_METHOD, LOAD_ATTR));
+        assert(is_pseudo_target(LOAD_METHOD, LOAD_ATTR));
         opcode = LOAD_ATTR;
         arg <<= 1;
         arg |= 1;
@@ -1135,18 +1112,18 @@ compiler_addop_name(struct compiler_unit *u, location loc,
         arg |= 2;
     }
     if (opcode == LOAD_SUPER_METHOD) {
-        assert(SAME_OPCODE_METADATA(LOAD_SUPER_METHOD, LOAD_SUPER_ATTR));
+        assert(is_pseudo_target(LOAD_SUPER_METHOD, LOAD_SUPER_ATTR));
         opcode = LOAD_SUPER_ATTR;
         arg <<= 2;
         arg |= 3;
     }
     if (opcode == LOAD_ZERO_SUPER_ATTR) {
-        assert(SAME_OPCODE_METADATA(LOAD_ZERO_SUPER_ATTR, LOAD_SUPER_ATTR));
+        assert(is_pseudo_target(LOAD_ZERO_SUPER_ATTR, LOAD_SUPER_ATTR));
         opcode = LOAD_SUPER_ATTR;
         arg <<= 2;
     }
     if (opcode == LOAD_ZERO_SUPER_METHOD) {
-        assert(SAME_OPCODE_METADATA(LOAD_ZERO_SUPER_METHOD, LOAD_SUPER_ATTR));
+        assert(is_pseudo_target(LOAD_ZERO_SUPER_METHOD, LOAD_SUPER_ATTR));
         opcode = LOAD_SUPER_ATTR;
         arg <<= 2;
         arg |= 1;
index d2e3a7ae441c7fcec4e5c7b8b68566cd44d8cef4..e6c824a85ef51e04cc49a87dfdd4814836a90e29 100644 (file)
@@ -2258,11 +2258,11 @@ convert_pseudo_ops(basicblock *entryblock)
                 INSTR_SET_OP0(instr, NOP);
             }
             else if (instr->i_opcode == LOAD_CLOSURE) {
-                assert(SAME_OPCODE_METADATA(LOAD_CLOSURE, LOAD_FAST));
+                assert(is_pseudo_target(LOAD_CLOSURE, LOAD_FAST));
                 instr->i_opcode = LOAD_FAST;
             }
             else if (instr->i_opcode == STORE_FAST_MAYBE_NULL) {
-                assert(SAME_OPCODE_METADATA(STORE_FAST_MAYBE_NULL, STORE_FAST));
+                assert(is_pseudo_target(STORE_FAST_MAYBE_NULL, STORE_FAST));
                 instr->i_opcode = STORE_FAST;
             }
         }
index a274427a699a4308e91741b3e937c8a6443f7f97..e935f33fa2131ae2b41eb93a81b982d03c7476b4 100644 (file)
                 DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_ADD_FLOAT
             {
                 STAT_INC(BINARY_OP, hit);
                 DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_ADD_INT
             {
                 STAT_INC(BINARY_OP, hit);
                 DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_ADD_UNICODE
             {
                 STAT_INC(BINARY_OP, hit);
                 DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_INPLACE_ADD_UNICODE
             {
                 TIER_ONE_ONLY
                 DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_MULTIPLY_FLOAT
             {
                 STAT_INC(BINARY_OP, hit);
                 DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_MULTIPLY_INT
             {
                 STAT_INC(BINARY_OP, hit);
                 DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_SUBTRACT_FLOAT
             {
                 STAT_INC(BINARY_OP, hit);
                 DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
                 DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
             }
+            /* Skip 1 cache entry */
             // _BINARY_OP_SUBTRACT_INT
             {
                 STAT_INC(BINARY_OP, hit);
                 DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
                 #endif  /* ENABLE_SPECIALIZATION */
             }
+            /* Skip 2 cache entries */
             // _CALL
             {
                 // oparg counts all of the args, but *not* self:
                 DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
                 #endif  /* ENABLE_SPECIALIZATION */
             }
+            /* Skip 8 cache entries */
             // _LOAD_ATTR
             {
                 PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
                 DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
                 #endif  /* ENABLE_SPECIALIZATION */
             }
+            /* Skip 1 cache entry */
+            /* Skip 1 cache entry */
+            /* Skip 1 cache entry */
             // _LOAD_GLOBAL
             {
                 PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
             next_instr += 2;
             INSTRUCTION_STATS(POP_JUMP_IF_FALSE);
             PyObject *cond;
+            /* Skip 1 cache entry */
             cond = stack_pointer[-1];
             assert(PyBool_Check(cond));
             int flag = Py_IsFalse(cond);
             PyObject *value;
             PyObject *b;
             PyObject *cond;
+            /* Skip 1 cache entry */
             // _IS_NONE
             value = stack_pointer[-1];
             {
             PyObject *value;
             PyObject *b;
             PyObject *cond;
+            /* Skip 1 cache entry */
             // _IS_NONE
             value = stack_pointer[-1];
             {
             next_instr += 2;
             INSTRUCTION_STATS(POP_JUMP_IF_TRUE);
             PyObject *cond;
+            /* Skip 1 cache entry */
             cond = stack_pointer[-1];
             assert(PyBool_Check(cond));
             int flag = Py_IsTrue(cond);
                 DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
                 #endif  /* ENABLE_SPECIALIZATION */
             }
+            /* Skip 3 cache entries */
             // _STORE_ATTR
             v = stack_pointer[-2];
             {
                 DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache);
                 #endif  /* ENABLE_SPECIALIZATION */
             }
+            /* Skip 2 cache entries */
             // _TO_BOOL
             {
                 int err = PyObject_IsTrue(value);
index d44e733bc346fa90292c27b293ef40fa4281fc33..0ff16191680a4b690ae6542c913ae6d43352935e 100644 (file)
@@ -6,14 +6,20 @@
 #include "pycore_opcode_utils.h"  // MAX_REAL_OPCODE
 #include "pycore_optimizer.h"     // _Py_uop_analyze_and_optimize()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
+#include "pycore_uop_ids.h"
 #include "pycore_uops.h"
 #include "cpython/optimizer.h"
 #include <stdbool.h>
 #include <stdint.h>
 #include <stddef.h>
 
+#define NEED_OPCODE_METADATA
+#include "pycore_uop_metadata.h" // Uop tables
+#undef NEED_OPCODE_METADATA
+
 #define MAX_EXECUTORS_SIZE 256
 
+
 static bool
 has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
 {
@@ -327,9 +333,6 @@ uop_dealloc(_PyUOpExecutorObject *self) {
 const char *
 _PyUOpName(int index)
 {
-    if (index <= MAX_REAL_OPCODE) {
-        return _PyOpcode_OpName[index];
-    }
     return _PyOpcode_uop_name[index];
 }
 
@@ -388,7 +391,7 @@ PyTypeObject _PyUOpExecutor_Type = {
 
 /* TO DO -- Generate these tables */
 static const uint16_t
-_PyUOp_Replacements[OPCODE_METADATA_SIZE] = {
+_PyUOp_Replacements[MAX_UOP_ID + 1] = {
     [_ITER_JUMP_RANGE] = _GUARD_NOT_EXHAUSTED_RANGE,
     [_ITER_JUMP_LIST] = _GUARD_NOT_EXHAUSTED_LIST,
     [_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE,
@@ -629,14 +632,6 @@ top:  // Jump here after _PUSH_FRAME or likely branches
                                         oparg += extras;
                                     }
                                 }
-                                if (_PyUOp_Replacements[uop]) {
-                                    uop = _PyUOp_Replacements[uop];
-                                    if (uop == _FOR_ITER_TIER_TWO) {
-                                        target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
-                                        assert(_PyCode_CODE(code)[target-1].op.code == END_FOR ||
-                                               _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR);
-                                    }
-                                }
                                 break;
                             case OPARG_CACHE_1:
                                 operand = read_u16(&instr[offset].cache);
@@ -657,7 +652,15 @@ top:  // Jump here after _PUSH_FRAME or likely branches
                                 oparg = offset;
                                 assert(uop == _SAVE_RETURN_OFFSET);
                                 break;
-
+                            case OPARG_REPLACED:
+                                uop = _PyUOp_Replacements[uop];
+                                assert(uop != 0);
+                                if (uop == _FOR_ITER_TIER_TWO) {
+                                    target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
+                                    assert(_PyCode_CODE(code)[target-1].op.code == END_FOR ||
+                                            _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR);
+                                }
+                                break;
                             default:
                                 fprintf(stderr,
                                         "opcode=%d, oparg=%d; nuops=%d, i=%d; size=%d, offset=%d\n",
@@ -799,7 +802,8 @@ compute_used(_PyUOpInstruction *buffer, uint32_t *used)
         }
         /* All other micro-ops fall through, so i+1 is reachable */
         SET_BIT(used, i+1);
-        if (OPCODE_HAS_JUMP(opcode)) {
+        assert(opcode <= MAX_UOP_ID);
+        if (_PyUop_Flags[opcode] & HAS_JUMP_FLAG) {
             /* Mark target as reachable */
             SET_BIT(used, buffer[i].oparg);
         }
index 7c2a4a42b1dcc3dca0fa8ded667a38c359cf56b7..369b962a545f4e9521610ffae1c32720cc56f576 100644 (file)
@@ -10,6 +10,7 @@
 #include "pycore_moduleobject.h"
 #include "pycore_object.h"
 #include "pycore_opcode_metadata.h" // _PyOpcode_Caches
+#include "pycore_uop_metadata.h"    // _PyOpcode_uop_name
 #include "pycore_opcode_utils.h"  // RESUME_AT_FUNC_START
 #include "pycore_pylifecycle.h"   // _PyOS_URandomNonblock()
 #include "pycore_runtime.h"       // _Py_ID()
index e077eb0a8ed2036681625b713b22850629c7043d..d7aca50d22374893340f2b7411ffeaf4de7fb1ed 100644 (file)
@@ -11,11 +11,16 @@ class Properties:
     deopts: bool
     oparg: bool
     jumps: bool
+    eval_breaker: bool
     ends_with_eval_breaker: bool
     needs_this: bool
     always_exits: bool
     stores_sp: bool
     tier_one_only: bool
+    uses_co_consts: bool
+    uses_co_names: bool
+    uses_locals: bool
+    has_free: bool
 
     def dump(self, indent: str) -> None:
         print(indent, end="")
@@ -30,11 +35,16 @@ class Properties:
             deopts=any(p.deopts for p in properties),
             oparg=any(p.oparg for p in properties),
             jumps=any(p.jumps for p in properties),
+            eval_breaker=any(p.eval_breaker for p in properties),
             ends_with_eval_breaker=any(p.ends_with_eval_breaker for p in properties),
             needs_this=any(p.needs_this for p in properties),
             always_exits=any(p.always_exits for p in properties),
             stores_sp=any(p.stores_sp for p in properties),
             tier_one_only=any(p.tier_one_only for p in properties),
+            uses_co_consts=any(p.uses_co_consts for p in properties),
+            uses_co_names=any(p.uses_co_names for p in properties),
+            uses_locals=any(p.uses_locals for p in properties),
+            has_free=any(p.has_free for p in properties),
         )
 
 
@@ -44,11 +54,16 @@ SKIP_PROPERTIES = Properties(
     deopts=False,
     oparg=False,
     jumps=False,
+    eval_breaker=False,
     ends_with_eval_breaker=False,
     needs_this=False,
     always_exits=False,
     stores_sp=False,
     tier_one_only=False,
+    uses_co_consts=False,
+    uses_co_names=False,
+    uses_locals=False,
+    has_free=False,
 )
 
 
@@ -142,6 +157,12 @@ class Uop:
             return False
         return True
 
+    def is_super(self) -> bool:
+        for tkn in self.body:
+            if tkn.kind == "IDENTIFIER" and tkn.text == "oparg1":
+                return True
+        return False
+
 
 Part = Uop | Skip
 
@@ -153,6 +174,7 @@ class Instruction:
     _properties: Properties | None
     is_target: bool = False
     family: Optional["Family"] = None
+    opcode: int = -1
 
     @property
     def properties(self) -> Properties:
@@ -171,16 +193,30 @@ class Instruction:
     def size(self) -> int:
         return 1 + sum(part.size for part in self.parts)
 
+    def is_super(self) -> bool:
+        if len(self.parts) != 1:
+            return False
+        uop = self.parts[0]
+        if isinstance(uop, Uop):
+            return uop.is_super()
+        else:
+            return False
+
 
 @dataclass
 class PseudoInstruction:
     name: str
     targets: list[Instruction]
     flags: list[str]
+    opcode: int = -1
 
     def dump(self, indent: str) -> None:
         print(indent, self.name, "->", " or ".join([t.name for t in self.targets]))
 
+    @property
+    def properties(self) -> Properties:
+        return Properties.from_list([i.properties for i in self.targets])
+
 
 @dataclass
 class Family:
@@ -198,12 +234,15 @@ class Analysis:
     uops: dict[str, Uop]
     families: dict[str, Family]
     pseudos: dict[str, PseudoInstruction]
+    opmap: dict[str, int]
+    have_arg: int
+    min_instrumented: int
 
 
 def analysis_error(message: str, tkn: lexer.Token) -> SyntaxError:
     # To do -- support file and line output
     # Construct a SyntaxError instance from message and token
-    return lexer.make_syntax_error(message, "", tkn.line, tkn.column, "")
+    return lexer.make_syntax_error(message, tkn.filename, tkn.line, tkn.column, "")
 
 
 def override_error(
@@ -238,6 +277,11 @@ def analyze_caches(inputs: list[parser.InputEffect]) -> list[CacheEntry]:
     caches: list[parser.CacheEffect] = [
         i for i in inputs if isinstance(i, parser.CacheEffect)
     ]
+    for cache in caches:
+        if cache.name == "unused":
+            raise analysis_error(
+                "Unused cache entry in op. Move to enclosing macro.", cache.tokens[0]
+            )
     return [CacheEntry(i.name, int(i.size)) for i in caches]
 
 
@@ -300,17 +344,28 @@ def always_exits(op: parser.InstDef) -> bool:
 
 
 def compute_properties(op: parser.InstDef) -> Properties:
+    has_free = (
+        variable_used(op, "PyCell_New")
+        or variable_used(op, "PyCell_GET")
+        or variable_used(op, "PyCell_SET")
+    )
     return Properties(
         escapes=makes_escaping_api_call(op),
         infallible=is_infallible(op),
         deopts=variable_used(op, "DEOPT_IF"),
         oparg=variable_used(op, "oparg"),
         jumps=variable_used(op, "JUMPBY"),
+        eval_breaker=variable_used(op, "CHECK_EVAL_BREAKER"),
         ends_with_eval_breaker=eval_breaker_at_end(op),
         needs_this=variable_used(op, "this_instr"),
         always_exits=always_exits(op),
         stores_sp=variable_used(op, "STORE_SP"),
         tier_one_only=variable_used(op, "TIER_ONE_ONLY"),
+        uses_co_consts=variable_used(op, "FRAME_CO_CONSTS"),
+        uses_co_names=variable_used(op, "FRAME_CO_NAMES"),
+        uses_locals=(variable_used(op, "GETLOCAL") or variable_used(op, "SETLOCAL"))
+        and not has_free,
+        has_free=has_free,
     )
 
 
@@ -417,6 +472,95 @@ def add_pseudo(
     )
 
 
+def assign_opcodes(
+    instructions: dict[str, Instruction],
+    families: dict[str, Family],
+    pseudos: dict[str, PseudoInstruction],
+) -> tuple[dict[str, int], int, int]:
+    """Assigns opcodes, then returns the opmap,
+    have_arg and min_instrumented values"""
+    instmap: dict[str, int] = {}
+
+    # 0 is reserved for cache entries. This helps debugging.
+    instmap["CACHE"] = 0
+
+    # 17 is reserved as it is the initial value for the specializing counter.
+    # This helps catch cases where we attempt to execute a cache.
+    instmap["RESERVED"] = 17
+
+    # 149 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py
+    instmap["RESUME"] = 149
+
+    # This is an historical oddity.
+    instmap["BINARY_OP_INPLACE_ADD_UNICODE"] = 3
+
+    instmap["INSTRUMENTED_LINE"] = 254
+
+    instrumented = [name for name in instructions if name.startswith("INSTRUMENTED")]
+
+    # Special case: this instruction is implemented in ceval.c
+    # rather than bytecodes.c, so we need to add it explicitly
+    # here (at least until we add something to bytecodes.c to
+    # declare external instructions).
+    instrumented.append("INSTRUMENTED_LINE")
+
+    specialized: set[str] = set()
+    no_arg: list[str] = []
+    has_arg: list[str] = []
+
+    for family in families.values():
+        specialized.update(inst.name for inst in family.members)
+
+    for inst in instructions.values():
+        name = inst.name
+        if name in specialized:
+            continue
+        if name in instrumented:
+            continue
+        if inst.properties.oparg:
+            has_arg.append(name)
+        else:
+            no_arg.append(name)
+
+    # Specialized ops appear in their own section
+    # Instrumented opcodes are at the end of the valid range
+    min_internal = 150
+    min_instrumented = 254 - (len(instrumented) - 1)
+    assert min_internal + len(specialized) < min_instrumented
+
+    next_opcode = 1
+
+    def add_instruction(name: str) -> None:
+        nonlocal next_opcode
+        if name in instmap:
+            return  # Pre-defined name
+        while next_opcode in instmap.values():
+            next_opcode += 1
+        instmap[name] = next_opcode
+        next_opcode += 1
+
+    for name in sorted(no_arg):
+        add_instruction(name)
+    for name in sorted(has_arg):
+        add_instruction(name)
+    # For compatibility
+    next_opcode = min_internal
+    for name in sorted(specialized):
+        add_instruction(name)
+    next_opcode = min_instrumented
+    for name in instrumented:
+        add_instruction(name)
+
+    for name in instructions:
+        instructions[name].opcode = instmap[name]
+
+    for op, name in enumerate(sorted(pseudos), 256):
+        instmap[name] = op
+        pseudos[name].opcode = op
+
+    return instmap, len(no_arg), min_instrumented
+
+
 def analyze_forest(forest: list[parser.AstNode]) -> Analysis:
     instructions: dict[str, Instruction] = {}
     uops: dict[str, Uop] = {}
@@ -460,10 +604,20 @@ def analyze_forest(forest: list[parser.AstNode]) -> Analysis:
                     continue
                 if target.text in instructions:
                     instructions[target.text].is_target = True
-    # Hack
+    # Special case BINARY_OP_INPLACE_ADD_UNICODE
+    # BINARY_OP_INPLACE_ADD_UNICODE is not a normal family member,
+    # as it is the wrong size, but we need it to maintain an
+    # historical optimization.
     if "BINARY_OP_INPLACE_ADD_UNICODE" in instructions:
-        instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"]
-    return Analysis(instructions, uops, families, pseudos)
+        inst = instructions["BINARY_OP_INPLACE_ADD_UNICODE"]
+        inst.family = families["BINARY_OP"]
+        families["BINARY_OP"].members.append(inst)
+    opmap, first_arg, min_instrumented = assign_opcodes(
+        instructions, families, pseudos
+    )
+    return Analysis(
+        instructions, uops, families, pseudos, opmap, first_arg, min_instrumented
+    )
 
 
 def analyze_files(filenames: list[str]) -> Analysis:
index 67b1c9a169024ce8bb48bd0182d235b117132adb..069f0177a74018f3e1e5f8390de9243bdd65ccbb 100644 (file)
@@ -1,5 +1,6 @@
+import contextlib
 from lexer import Token
-from typing import TextIO
+from typing import TextIO, Iterator
 
 
 class CWriter:
@@ -44,9 +45,12 @@ class CWriter:
 
     def maybe_indent(self, txt: str) -> None:
         parens = txt.count("(") - txt.count(")")
-        if parens > 0 and self.last_token:
-            offset = self.last_token.end_column - 1
-            if offset <= self.indents[-1] or offset > 40:
+        if parens > 0:
+            if self.last_token:
+                offset = self.last_token.end_column - 1
+                if offset <= self.indents[-1] or offset > 40:
+                    offset = self.indents[-1] + 4
+            else:
                 offset = self.indents[-1] + 4
             self.indents.append(offset)
         if is_label(txt):
@@ -54,6 +58,7 @@ class CWriter:
         else:
             braces = txt.count("{") - txt.count("}")
             if braces > 0:
+                assert braces == 1
                 if 'extern "C"' in txt:
                     self.indents.append(self.indents[-1])
                 else:
@@ -114,6 +119,28 @@ class CWriter:
         self.newline = True
         self.last_token = None
 
+    @contextlib.contextmanager
+    def header_guard(self, name: str) -> Iterator[None]:
+        self.out.write(
+            f"""
+#ifndef {name}
+#define {name}
+#ifdef __cplusplus
+extern "C" {{
+#endif
+
+"""
+        )
+        yield
+        self.out.write(
+            f"""
+#ifdef __cplusplus
+}}
+#endif
+#endif /* !{name} */
+"""
+        )
+
 
 def is_label(txt: str) -> bool:
     return not txt.startswith("//") and txt.endswith(":")
index 50bc14a57fc5842eeed907d8725cc11ced5f8b90..bb027f3b09b65412cf2d9683d59887be22010e9a 100644 (file)
@@ -840,7 +840,6 @@ def main() -> None:
 
     a.assign_opcode_ids()
     a.write_opcode_targets(args.opcode_targets_h)
-    a.write_metadata(args.metadata, args.pymetadata)
     a.write_abstract_interpreter_instructions(
         args.abstract_interpreter_cases, args.emit_line_directives
     )
index 1b565bff2c56f60a3e6bd4580a88e9bf63aab119..5a42a05c5c2ef28c65bf44e96852e42338b451c0 100644 (file)
@@ -2,14 +2,11 @@ from pathlib import Path
 from typing import TextIO
 
 from analyzer import (
-    Analysis,
     Instruction,
     Uop,
-    Part,
     analyze_files,
+    Properties,
     Skip,
-    StackItem,
-    analysis_error,
 )
 from cwriter import CWriter
 from typing import Callable, Mapping, TextIO, Iterator
@@ -25,14 +22,16 @@ def root_relative_path(filename: str) -> str:
     try:
         return Path(filename).absolute().relative_to(ROOT).as_posix()
     except ValueError:
+        # Not relative to root, just return original path.
         return filename
 
-def write_header(generator: str, sources: list[str], outfile: TextIO) -> None:
+
+def write_header(generator: str, sources: list[str], outfile: TextIO, comment: str = "//") -> None:
     outfile.write(
-        f"""// This file is generated by {root_relative_path(generator)}
-// from:
-//   {", ".join(root_relative_path(src) for src in sources)}
-// Do not edit!
+        f"""{comment} This file is generated by {root_relative_path(generator)}
+{comment} from:
+{comment}   {", ".join(root_relative_path(src) for src in sources)}
+{comment} Do not edit!
 """
     )
 
@@ -186,3 +185,31 @@ def emit_tokens(
             replacement_functions[tkn.text](out, tkn, tkn_iter, uop, stack, inst)
         else:
             out.emit(tkn)
+
+
+def cflags(p: Properties) -> str:
+    flags: list[str] = []
+    if p.oparg:
+        flags.append("HAS_ARG_FLAG")
+    if p.uses_co_consts:
+        flags.append("HAS_CONST_FLAG")
+    if p.uses_co_names:
+        flags.append("HAS_NAME_FLAG")
+    if p.jumps:
+        flags.append("HAS_JUMP_FLAG")
+    if p.has_free:
+        flags.append("HAS_FREE_FLAG")
+    if p.uses_locals:
+        flags.append("HAS_LOCAL_FLAG")
+    if p.eval_breaker:
+        flags.append("HAS_EVAL_BREAK_FLAG")
+    if p.deopts:
+        flags.append("HAS_DEOPT_FLAG")
+    if not p.infallible:
+        flags.append("HAS_ERROR_FLAG")
+    if p.escapes:
+        flags.append("HAS_ESCAPES_FLAG")
+    if flags:
+        return " | ".join(flags)
+    else:
+        return "0"
index ddbb409bbced39cec1793497f1c32986d6d36a24..dbea3d0b622c87f6778db410ab08a05282eac96c 100644 (file)
@@ -24,111 +24,23 @@ from typing import TextIO
 DEFAULT_OUTPUT = ROOT / "Include/opcode_ids.h"
 
 
-def generate_opcode_header(filenames: list[str], analysis: Analysis, outfile: TextIO) -> None:
+def generate_opcode_header(
+    filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
     write_header(__file__, filenames, outfile)
     out = CWriter(outfile, 0, False)
-    out.emit("\n")
-    instmap: dict[str, int] = {}
+    with out.header_guard("Py_OPCODE_IDS_H"):
+        out.emit("/* Instruction opcodes for compiled code */\n")
 
-    # 0 is reserved for cache entries. This helps debugging.
-    instmap["CACHE"] = 0
+        def write_define(name: str, op: int) -> None:
+            out.emit(f"#define {name:<38} {op:>3}\n")
 
-    # 17 is reserved as it is the initial value for the specializing counter.
-    # This helps catch cases where we attempt to execute a cache.
-    instmap["RESERVED"] = 17
+        for op, name in sorted([(op, name) for (name, op) in analysis.opmap.items()]):
+            write_define(name, op)
 
-    # 149 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py
-    instmap["RESUME"] = 149
-    instmap["INSTRUMENTED_LINE"] = 254
-
-    instrumented = [
-        name for name in analysis.instructions if name.startswith("INSTRUMENTED")
-    ]
-
-    # Special case: this instruction is implemented in ceval.c
-    # rather than bytecodes.c, so we need to add it explicitly
-    # here (at least until we add something to bytecodes.c to
-    # declare external instructions).
-    instrumented.append("INSTRUMENTED_LINE")
-
-    specialized: set[str] = set()
-    no_arg: list[str] = []
-    has_arg: list[str] = []
-
-    for family in analysis.families.values():
-        specialized.update(inst.name for inst in family.members)
-
-    for inst in analysis.instructions.values():
-        name = inst.name
-        if name in specialized:
-            continue
-        if name in instrumented:
-            continue
-        if inst.properties.oparg:
-            has_arg.append(name)
-        else:
-            no_arg.append(name)
-
-    # Specialized ops appear in their own section
-    # Instrumented opcodes are at the end of the valid range
-    min_internal = 150
-    min_instrumented = 254 - (len(instrumented) - 1)
-    assert min_internal + len(specialized) < min_instrumented
-
-    next_opcode = 1
-
-    def add_instruction(name: str) -> None:
-        nonlocal next_opcode
-        if name in instmap:
-            return  # Pre-defined name
-        while next_opcode in instmap.values():
-            next_opcode += 1
-        instmap[name] = next_opcode
-        next_opcode += 1
-
-    for name in sorted(no_arg):
-        add_instruction(name)
-    for name in sorted(has_arg):
-        add_instruction(name)
-    # For compatibility
-    next_opcode = min_internal
-    for name in sorted(specialized):
-        add_instruction(name)
-    next_opcode = min_instrumented
-    for name in instrumented:
-        add_instruction(name)
-
-    for op, name in enumerate(sorted(analysis.pseudos), 256):
-        instmap[name] = op
-
-    assert 255 not in instmap.values()
-
-    out.emit(
-        """#ifndef Py_OPCODE_IDS_H
-#define Py_OPCODE_IDS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Instruction opcodes for compiled code */
-"""
-    )
-
-    def write_define(name: str, op: int) -> None:
-        out.emit(f"#define {name:<38} {op:>3}\n")
-
-    for op, name in sorted([(op, name) for (name, op) in instmap.items()]):
-        write_define(name, op)
-
-    out.emit("\n")
-    write_define("HAVE_ARGUMENT", len(no_arg))
-    write_define("MIN_INSTRUMENTED_OPCODE", min_instrumented)
-
-    out.emit("\n")
-    out.emit("#ifdef __cplusplus\n")
-    out.emit("}\n")
-    out.emit("#endif\n")
-    out.emit("#endif /* !Py_OPCODE_IDS_H */\n")
+        out.emit("\n")
+        write_define("HAVE_ARGUMENT", analysis.have_arg)
+        write_define("MIN_INSTRUMENTED_OPCODE", analysis.min_instrumented)
 
 
 arg_parser = argparse.ArgumentParser(
diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py
new file mode 100644 (file)
index 0000000..427bb54
--- /dev/null
@@ -0,0 +1,386 @@
+"""Generate uop metedata.
+Reads the instruction definitions from bytecodes.c.
+Writes the metadata to pycore_uop_metadata.h by default.
+"""
+
+import argparse
+import os.path
+import sys
+
+from analyzer import (
+    Analysis,
+    Instruction,
+    analyze_files,
+    Skip,
+    Uop,
+)
+from generators_common import (
+    DEFAULT_INPUT,
+    ROOT,
+    write_header,
+    cflags,
+    StackOffset,
+)
+from cwriter import CWriter
+from typing import TextIO
+from stack import get_stack_effect
+
+# Constants used instead of size for macro expansions.
+# Note: 1, 2, 4 must match actual cache entry sizes.
+OPARG_KINDS = {
+    "OPARG_FULL": 0,
+    "OPARG_CACHE_1": 1,
+    "OPARG_CACHE_2": 2,
+    "OPARG_CACHE_4": 4,
+    "OPARG_TOP": 5,
+    "OPARG_BOTTOM": 6,
+    "OPARG_SAVE_RETURN_OFFSET": 7,
+    # Skip 8 as the other powers of 2 are sizes
+    "OPARG_REPLACED": 9,
+}
+
+FLAGS = [
+    "ARG",
+    "CONST",
+    "NAME",
+    "JUMP",
+    "FREE",
+    "LOCAL",
+    "EVAL_BREAK",
+    "DEOPT",
+    "ERROR",
+    "ESCAPES",
+]
+
+
+def generate_flag_macros(out: CWriter) -> None:
+    for i, flag in enumerate(FLAGS):
+        out.emit(f"#define HAS_{flag}_FLAG ({1<<i})\n")
+    for i, flag in enumerate(FLAGS):
+        out.emit(
+            f"#define OPCODE_HAS_{flag}(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_{flag}_FLAG))\n"
+        )
+    out.emit("\n")
+
+
+def generate_oparg_macros(out: CWriter) -> None:
+    for name, value in OPARG_KINDS.items():
+        out.emit(f"#define {name} {value}\n")
+    out.emit("\n")
+
+
+def emit_stack_effect_function(
+    out: CWriter, direction: str, data: list[tuple[str, str]]
+) -> None:
+    out.emit(f"extern int _PyOpcode_num_{direction}(int opcode, int oparg);\n")
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit(f"int _PyOpcode_num_{direction}(int opcode, int oparg)  {{\n")
+    out.emit("switch(opcode) {\n")
+    for name, effect in data:
+        out.emit(f"case {name}:\n")
+        out.emit(f"    return {effect};\n")
+    out.emit("default:\n")
+    out.emit("    return -1;\n")
+    out.emit("}\n")
+    out.emit("}\n\n")
+    out.emit("#endif\n\n")
+
+
+def generate_stack_effect_functions(analysis: Analysis, out: CWriter) -> None:
+    popped_data: list[tuple[str, str]] = []
+    pushed_data: list[tuple[str, str]] = []
+    for inst in analysis.instructions.values():
+        stack = get_stack_effect(inst)
+        popped = (-stack.base_offset).to_c()
+        pushed = (stack.top_offset - stack.base_offset).to_c()
+        popped_data.append((inst.name, popped))
+        pushed_data.append((inst.name, pushed))
+    emit_stack_effect_function(out, "popped", sorted(popped_data))
+    emit_stack_effect_function(out, "pushed", sorted(pushed_data))
+
+
+def generate_is_pseudo(analysis: Analysis, out: CWriter) -> None:
+    """Write the IS_PSEUDO_INSTR macro"""
+    out.emit("\n\n#define IS_PSEUDO_INSTR(OP)  ( \\\n")
+    for op in analysis.pseudos:
+        out.emit(f"((OP) == {op}) || \\\n")
+    out.emit("0")
+    out.emit(")\n\n")
+
+
+def get_format(inst: Instruction) -> str:
+    if inst.properties.oparg:
+        format = "INSTR_FMT_IB"
+    else:
+        format = "INSTR_FMT_IX"
+    if inst.size > 1:
+        format += "C"
+    format += "0" * (inst.size - 2)
+    return format
+
+
+def generate_instruction_formats(analysis: Analysis, out: CWriter) -> None:
+    # Compute the set of all instruction formats.
+    formats: set[str] = set()
+    for inst in analysis.instructions.values():
+        formats.add(get_format(inst))
+    # Generate an enum for it
+    out.emit("enum InstructionFormat {\n")
+    next_id = 1
+    for format in sorted(formats):
+        out.emit(f"{format} = {next_id},\n")
+        next_id += 1
+    out.emit("};\n\n")
+
+
+def generate_deopt_table(analysis: Analysis, out: CWriter) -> None:
+    out.emit("extern const uint8_t _PyOpcode_Deopt[256];\n")
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit("const uint8_t _PyOpcode_Deopt[256] = {\n")
+    deopts: list[tuple[str, str]] = []
+    for inst in analysis.instructions.values():
+        deopt = inst.name
+        if inst.family is not None:
+            deopt = inst.family.name
+        deopts.append((inst.name, deopt))
+    deopts.append(("INSTRUMENTED_LINE", "INSTRUMENTED_LINE"))
+    for name, deopt in sorted(deopts):
+        out.emit(f"[{name}] = {deopt},\n")
+    out.emit("};\n\n")
+    out.emit("#endif // NEED_OPCODE_METADATA\n\n")
+
+
+def generate_cache_table(analysis: Analysis, out: CWriter) -> None:
+    out.emit("extern const uint8_t _PyOpcode_Caches[256];\n")
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit("const uint8_t _PyOpcode_Caches[256] = {\n")
+    for inst in analysis.instructions.values():
+        if inst.family and inst.family.name != inst.name:
+            continue
+        if inst.name.startswith("INSTRUMENTED"):
+            continue
+        if inst.size > 1:
+            out.emit(f"[{inst.name}] = {inst.size-1},\n")
+    out.emit("};\n")
+    out.emit("#endif\n\n")
+
+
+def generate_name_table(analysis: Analysis, out: CWriter) -> None:
+    table_size = 256 + len(analysis.pseudos)
+    out.emit(f"extern const char *_PyOpcode_OpName[{table_size}];\n")
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit(f"const char *_PyOpcode_OpName[{table_size}] = {{\n")
+    names = list(analysis.instructions) + list(analysis.pseudos)
+    names.append("INSTRUMENTED_LINE")
+    for name in sorted(names):
+        out.emit(f'[{name}] = "{name}",\n')
+    out.emit("};\n")
+    out.emit("#endif\n\n")
+
+
+def generate_metadata_table(analysis: Analysis, out: CWriter) -> None:
+    table_size = 256 + len(analysis.pseudos)
+    out.emit("struct opcode_metadata {\n")
+    out.emit("uint8_t valid_entry;\n")
+    out.emit("int8_t instr_format;\n")
+    out.emit("int16_t flags;\n")
+    out.emit("};\n\n")
+    out.emit(
+        f"extern const struct opcode_metadata _PyOpcode_opcode_metadata[{table_size}];\n"
+    )
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit(
+        f"const struct opcode_metadata _PyOpcode_opcode_metadata[{table_size}] = {{\n"
+    )
+    for inst in sorted(analysis.instructions.values(), key=lambda t: t.name):
+        out.emit(
+            f"[{inst.name}] = {{ true, {get_format(inst)}, {cflags(inst.properties)} }},\n"
+        )
+    for pseudo in sorted(analysis.pseudos.values(), key=lambda t: t.name):
+        flags = cflags(pseudo.properties)
+        for flag in pseudo.flags:
+            if flags == "0":
+                flags = f"{flag}_FLAG"
+            else:
+                flags += f" | {flag}_FLAG"
+        out.emit(f"[{pseudo.name}] = {{ true, -1, {flags} }},\n")
+    out.emit("};\n")
+    out.emit("#endif\n\n")
+
+
+def generate_expansion_table(analysis: Analysis, out: CWriter) -> None:
+    expansions_table: dict[str, list[tuple[str, int, int]]] = {}
+    for inst in sorted(analysis.instructions.values(), key=lambda t: t.name):
+        offset: int = 0  # Cache effect offset
+        expansions: list[tuple[str, int, int]] = []  # [(name, size, offset), ...]
+        if inst.is_super():
+            pieces = inst.name.split("_")
+            assert len(pieces) == 4, f"{inst.name} doesn't look like a super-instr"
+            name1 = "_".join(pieces[:2])
+            name2 = "_".join(pieces[2:])
+            assert name1 in analysis.instructions, f"{name1} doesn't match any instr"
+            assert name2 in analysis.instructions, f"{name2} doesn't match any instr"
+            instr1 = analysis.instructions[name1]
+            instr2 = analysis.instructions[name2]
+            assert (
+                len(instr1.parts) == 1
+            ), f"{name1} is not a good superinstruction part"
+            assert (
+                len(instr2.parts) == 1
+            ), f"{name2} is not a good superinstruction part"
+            expansions.append((instr1.parts[0].name, OPARG_KINDS["OPARG_TOP"], 0))
+            expansions.append((instr2.parts[0].name, OPARG_KINDS["OPARG_BOTTOM"], 0))
+        elif not is_viable_expansion(inst):
+            continue
+        else:
+            for part in inst.parts:
+                size = part.size
+                if part.name == "_SAVE_RETURN_OFFSET":
+                    size = OPARG_KINDS["OPARG_SAVE_RETURN_OFFSET"]
+                if isinstance(part, Uop):
+                    # Skip specializations
+                    if "specializing" in part.annotations:
+                        continue
+                    if "replaced" in part.annotations:
+                        size = OPARG_KINDS["OPARG_REPLACED"]
+                    expansions.append((part.name, size, offset if size else 0))
+                offset += part.size
+        expansions_table[inst.name] = expansions
+    max_uops = max(len(ex) for ex in expansions_table.values())
+    out.emit(f"#define MAX_UOP_PER_EXPANSION {max_uops}\n")
+    out.emit("struct opcode_macro_expansion {\n")
+    out.emit("int nuops;\n")
+    out.emit(
+        "struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];\n"
+    )
+    out.emit("};\n")
+    out.emit(
+        "extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256];\n\n"
+    )
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit("const struct opcode_macro_expansion\n")
+    out.emit("_PyOpcode_macro_expansion[256] = {\n")
+    for inst_name, expansions in expansions_table.items():
+        uops = [
+            f"{{ {name}, {size}, {offset} }}" for (name, size, offset) in expansions
+        ]
+        out.emit(
+            f'[{inst_name}] = {{ .nuops = {len(expansions)}, .uops = {{ {", ".join(uops)} }} }},\n'
+        )
+    out.emit("};\n")
+    out.emit("#endif // NEED_OPCODE_METADATA\n\n")
+
+
+def is_viable_expansion(inst: Instruction) -> bool:
+    "An instruction can be expanded if all its parts are viable for tier 2"
+    for part in inst.parts:
+        if isinstance(part, Uop):
+            # Skip specializing and replaced uops
+            if "specializing" in part.annotations:
+                continue
+            if "replaced" in part.annotations:
+                continue
+            if part.properties.tier_one_only or not part.is_viable():
+                return False
+    return True
+
+
+def generate_extra_cases(analysis: Analysis, out: CWriter) -> None:
+    out.emit("#define EXTRA_CASES \\\n")
+    valid_opcodes = set(analysis.opmap.values())
+    for op in range(256):
+        if op not in valid_opcodes:
+            out.emit(f"    case {op}: \\\n")
+    out.emit("        ;\n")
+
+
+def generate_pseudo_targets(analysis: Analysis, out: CWriter) -> None:
+    table_size = len(analysis.pseudos)
+    max_targets = max(len(pseudo.targets) for pseudo in analysis.pseudos.values())
+    out.emit("struct pseudo_targets {\n")
+    out.emit(f"uint8_t targets[{max_targets + 1}];\n")
+    out.emit("};\n")
+    out.emit(
+        f"extern const struct pseudo_targets _PyOpcode_PseudoTargets[{table_size}];\n"
+    )
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit(
+        f"const struct pseudo_targets _PyOpcode_PseudoTargets[{table_size}] = {{\n"
+    )
+    for pseudo in analysis.pseudos.values():
+        targets = ["0"] * (max_targets + 1)
+        for i, target in enumerate(pseudo.targets):
+            targets[i] = target.name
+        out.emit(f"[{pseudo.name}-256] = {{ {{ {', '.join(targets)} }} }},\n")
+    out.emit("};\n\n")
+    out.emit("#endif // NEED_OPCODE_METADATA\n")
+    out.emit("static inline bool\n")
+    out.emit("is_pseudo_target(int pseudo, int target) {\n")
+    out.emit(f"if (pseudo < 256 || pseudo >= {256+table_size}) {{\n")
+    out.emit(f"return false;\n")
+    out.emit("}\n")
+    out.emit(
+        f"for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) {{\n"
+    )
+    out.emit(
+        f"if (_PyOpcode_PseudoTargets[pseudo-256].targets[i] == target) return true;\n"
+    )
+    out.emit("}\n")
+    out.emit(f"return false;\n")
+    out.emit("}\n\n")
+
+
+def generate_opcode_metadata(
+    filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
+    write_header(__file__, filenames, outfile)
+    out = CWriter(outfile, 0, False)
+    with out.header_guard("Py_CORE_OPCODE_METADATA_H"):
+        out.emit("#ifndef Py_BUILD_CORE\n")
+        out.emit('#  error "this header requires Py_BUILD_CORE define"\n')
+        out.emit("#endif\n\n")
+        out.emit("#include <stdbool.h>              // bool\n")
+        out.emit('#include "opcode_ids.h"\n')
+        generate_is_pseudo(analysis, out)
+        out.emit('#include "pycore_uop_ids.h"\n')
+        generate_stack_effect_functions(analysis, out)
+        generate_instruction_formats(analysis, out)
+        table_size = 256 + len(analysis.pseudos)
+        out.emit("#define IS_VALID_OPCODE(OP) \\\n")
+        out.emit(f"    (((OP) >= 0) && ((OP) < {table_size}) && \\\n")
+        out.emit("     (_PyOpcode_opcode_metadata[(OP)].valid_entry))\n\n")
+        generate_flag_macros(out)
+        generate_oparg_macros(out)
+        generate_metadata_table(analysis, out)
+        generate_expansion_table(analysis, out)
+        generate_name_table(analysis, out)
+        generate_cache_table(analysis, out)
+        generate_deopt_table(analysis, out)
+        generate_extra_cases(analysis, out)
+        generate_pseudo_targets(analysis, out)
+
+
+arg_parser = argparse.ArgumentParser(
+    description="Generate the header file with opcode metadata.",
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+
+
+DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_metadata.h"
+
+
+arg_parser.add_argument(
+    "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
+)
+
+arg_parser.add_argument(
+    "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
+)
+
+if __name__ == "__main__":
+    args = arg_parser.parse_args()
+    if len(args.input) == 0:
+        args.input.append(DEFAULT_INPUT)
+    data = analyze_files(args.input)
+    with open(args.output, "w") as outfile:
+        generate_opcode_metadata(args.input, data, outfile)
diff --git a/Tools/cases_generator/py_metadata_generator.py b/Tools/cases_generator/py_metadata_generator.py
new file mode 100644 (file)
index 0000000..43811fd
--- /dev/null
@@ -0,0 +1,97 @@
+"""Generate uop metedata.
+Reads the instruction definitions from bytecodes.c.
+Writes the metadata to pycore_uop_metadata.h by default.
+"""
+
+import argparse
+
+from analyzer import (
+    Analysis,
+    analyze_files,
+)
+from generators_common import (
+    DEFAULT_INPUT,
+    ROOT,
+    root_relative_path,
+    write_header,
+)
+from cwriter import CWriter
+from typing import TextIO
+
+
+
+DEFAULT_OUTPUT = ROOT / "Lib/_opcode_metadata.py"
+
+
+def get_specialized(analysis: Analysis) -> set[str]:
+    specialized: set[str] = set()
+    for family in analysis.families.values():
+        for member in family.members:
+            specialized.add(member.name)
+    return specialized
+
+
+def generate_specializations(analysis: Analysis, out: CWriter) -> None:
+    out.emit("_specializations = {\n")
+    for family in analysis.families.values():
+        out.emit(f'"{family.name}": [\n')
+        for member in family.members:
+            out.emit(f'    "{member.name}",\n')
+        out.emit("],\n")
+    out.emit("}\n\n")
+
+
+def generate_specialized_opmap(analysis: Analysis, out: CWriter) -> None:
+    out.emit("_specialized_opmap = {\n")
+    names = []
+    for family in analysis.families.values():
+        for member in family.members:
+            if member.name == family.name:
+                continue
+            names.append(member.name)
+    for name in sorted(names):
+        out.emit(f"'{name}': {analysis.opmap[name]},\n")
+    out.emit("}\n\n")
+
+
+def generate_opmap(analysis: Analysis, out: CWriter) -> None:
+    specialized = get_specialized(analysis)
+    out.emit("opmap = {\n")
+    for inst, op in analysis.opmap.items():
+        if inst not in specialized:
+            out.emit(f"'{inst}': {analysis.opmap[inst]},\n")
+    out.emit("}\n\n")
+
+
+def generate_py_metadata(
+    filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
+    write_header(__file__, filenames, outfile, "#")
+    out = CWriter(outfile, 0, False)
+    generate_specializations(analysis, out)
+    generate_specialized_opmap(analysis, out)
+    generate_opmap(analysis, out)
+    out.emit(f"HAVE_ARGUMENT = {analysis.have_arg}\n")
+    out.emit(f"MIN_INSTRUMENTED_OPCODE = {analysis.min_instrumented}\n")
+
+
+arg_parser = argparse.ArgumentParser(
+    description="Generate the Python file with opcode metadata.",
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+
+arg_parser.add_argument(
+    "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
+)
+
+arg_parser.add_argument(
+    "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
+)
+
+if __name__ == "__main__":
+    args = arg_parser.parse_args()
+    if len(args.input) == 0:
+        args.input.append(DEFAULT_INPUT)
+    data = analyze_files(args.input)
+    with open(args.output, "w") as outfile:
+        generate_py_metadata(args.input, data, outfile)
index 0b31ce4090f552a516704e82876153de56a7e0ed..94fb82d1139b689d398c1ed8a91d3fc30b42ef03 100644 (file)
@@ -1,5 +1,5 @@
 import sys
-from analyzer import StackItem
+from analyzer import StackItem, Instruction, Uop
 from dataclasses import dataclass
 from formatting import maybe_parenthesize
 from cwriter import CWriter
@@ -15,13 +15,16 @@ def var_size(var: StackItem) -> str:
     else:
         return var.size
 
-
+@dataclass
 class StackOffset:
     "The stack offset of the virtual base of the stack from the physical stack pointer"
 
-    def __init__(self) -> None:
-        self.popped: list[str] = []
-        self.pushed: list[str] = []
+    popped: list[str]
+    pushed: list[str]
+
+    @staticmethod
+    def empty() -> "StackOffset":
+        return StackOffset([], [])
 
     def pop(self, item: StackItem) -> None:
         self.popped.append(var_size(item))
@@ -29,6 +32,15 @@ class StackOffset:
     def push(self, item: StackItem) -> None:
         self.pushed.append(var_size(item))
 
+    def __sub__(self, other: "StackOffset") -> "StackOffset":
+        return StackOffset(
+            self.popped + other.pushed,
+            self.pushed + other.popped
+        )
+
+    def __neg__(self) -> "StackOffset":
+        return StackOffset(self.pushed, self.popped)
+
     def simplify(self) -> None:
         "Remove matching values from both the popped and pushed list"
         if not self.popped or not self.pushed:
@@ -88,9 +100,9 @@ class SizeMismatch(Exception):
 
 class Stack:
     def __init__(self) -> None:
-        self.top_offset = StackOffset()
-        self.base_offset = StackOffset()
-        self.peek_offset = StackOffset()
+        self.top_offset = StackOffset.empty()
+        self.base_offset = StackOffset.empty()
+        self.peek_offset = StackOffset.empty()
         self.variables: list[StackItem] = []
         self.defined: set[str] = set()
 
@@ -166,3 +178,15 @@ class Stack:
 
     def as_comment(self) -> str:
         return f"/* Variables: {[v.name for v in self.variables]}. Base offset: {self.base_offset.to_c()}. Top offset: {self.top_offset.to_c()} */"
+
+
+def get_stack_effect(inst: Instruction) -> Stack:
+    stack = Stack()
+    for uop in inst.parts:
+        if not isinstance(uop, Uop):
+            continue
+        for var in reversed(uop.stack.inputs):
+            stack.pop(var)
+        for i, var in enumerate(uop.stack.outputs):
+            stack.push(var)
+    return stack
index 49cede978d821a32704d70c3ac68017727d84cb8..aba36ec74e5766ebdffa0581a6ccd46a96657b7d 100644 (file)
@@ -190,6 +190,7 @@ def generate_tier1_from_files(
     with open(outfilename, "w") as outfile:
         generate_tier1(filenames, data, outfile, lines)
 
+
 if __name__ == "__main__":
     args = arg_parser.parse_args()
     if len(args.input) == 0:
index a22fb6dd932503a74d7ffcc8d54757b6bc29dfe4..7897b89b2752a72b3c01e6a58b34238b3959e761 100644 (file)
@@ -103,13 +103,6 @@ TIER2_REPLACEMENT_FUNCTIONS["ERROR_IF"] = tier2_replace_error
 TIER2_REPLACEMENT_FUNCTIONS["DEOPT_IF"] = tier2_replace_deopt
 
 
-def is_super(uop: Uop) -> bool:
-    for tkn in uop.body:
-        if tkn.kind == "IDENTIFIER" and tkn.text == "oparg1":
-            return True
-    return False
-
-
 def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None:
     try:
         out.start_line()
@@ -123,7 +116,7 @@ def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None:
         for cache in uop.caches:
             if cache.name != "unused":
                 if cache.size == 4:
-                    type = cast ="PyObject *"
+                    type = cast = "PyObject *"
                 else:
                     type = f"uint{cache.size*16}_t "
                     cast = f"uint{cache.size*16}_t"
@@ -156,7 +149,7 @@ def generate_tier2(
     for name, uop in analysis.uops.items():
         if uop.properties.tier_one_only:
             continue
-        if is_super(uop):
+        if uop.is_super():
             continue
         if not uop.is_viable():
             out.emit(f"/* {uop.name} is not a viable micro-op for tier 2 */\n\n")
index 277da25835f6fbb465fb8c2589993adfc75dd6e6..633249f1c6b1febe1a82bbe678a398dc3a11464e 100644 (file)
@@ -24,50 +24,32 @@ from typing import TextIO
 DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_ids.h"
 
 
-OMIT = {"_CACHE", "_RESERVED", "_EXTENDED_ARG"}
-
-
 def generate_uop_ids(
     filenames: list[str], analysis: Analysis, outfile: TextIO, distinct_namespace: bool
 ) -> None:
     write_header(__file__, filenames, outfile)
     out = CWriter(outfile, 0, False)
-    out.emit(
-        """#ifndef Py_CORE_UOP_IDS_H
-#define Py_CORE_UOP_IDS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-"""
-    )
-
-    next_id = 1 if distinct_namespace else 300
-    # These two are first by convention
-    out.emit(f"#define _EXIT_TRACE {next_id}\n")
-    next_id += 1
-    out.emit(f"#define _SET_IP {next_id}\n")
-    next_id += 1
-    PRE_DEFINED = {"_EXIT_TRACE", "_SET_IP"}
-
-    for uop in analysis.uops.values():
-        if uop.name in PRE_DEFINED:
-            continue
-        # TODO: We should omit all tier-1 only uops, but
-        # generate_cases.py still generates code for those.
-        if uop.name in OMIT:
-            continue
-        if uop.implicitly_created and not distinct_namespace:
-            out.emit(f"#define {uop.name} {uop.name[1:]}\n")
-        else:
-            out.emit(f"#define {uop.name} {next_id}\n")
-            next_id += 1
-
-    out.emit("\n")
-    out.emit("#ifdef __cplusplus\n")
-    out.emit("}\n")
-    out.emit("#endif\n")
-    out.emit("#endif /* !Py_OPCODE_IDS_H */\n")
+    with out.header_guard("Py_CORE_UOP_IDS_H"):
+        next_id = 1 if distinct_namespace else 300
+        # These two are first by convention
+        out.emit(f"#define _EXIT_TRACE {next_id}\n")
+        next_id += 1
+        out.emit(f"#define _SET_IP {next_id}\n")
+        next_id += 1
+        PRE_DEFINED = {"_EXIT_TRACE", "_SET_IP"}
+
+        for uop in analysis.uops.values():
+            if uop.name in PRE_DEFINED:
+                continue
+            if uop.properties.tier_one_only:
+                continue
+            if uop.implicitly_created and not distinct_namespace:
+                out.emit(f"#define {uop.name} {uop.name[1:]}\n")
+            else:
+                out.emit(f"#define {uop.name} {next_id}\n")
+                next_id += 1
+
+        out.emit(f"#define MAX_UOP_ID {next_id-1}\n")
 
 
 arg_parser = argparse.ArgumentParser(
diff --git a/Tools/cases_generator/uop_metadata_generator.py b/Tools/cases_generator/uop_metadata_generator.py
new file mode 100644 (file)
index 0000000..d4f3a09
--- /dev/null
@@ -0,0 +1,73 @@
+"""Generate uop metedata.
+Reads the instruction definitions from bytecodes.c.
+Writes the metadata to pycore_uop_metadata.h by default.
+"""
+
+import argparse
+
+from analyzer import (
+    Analysis,
+    analyze_files,
+)
+from generators_common import (
+    DEFAULT_INPUT,
+    ROOT,
+    write_header,
+    cflags,
+)
+from cwriter import CWriter
+from typing import TextIO
+
+
+DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_metadata.h"
+
+
+def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None:
+    out.emit("extern const uint16_t _PyUop_Flags[MAX_UOP_ID+1];\n")
+    out.emit("extern const char * const _PyOpcode_uop_name[MAX_UOP_ID+1];\n\n")
+    out.emit("#ifdef NEED_OPCODE_METADATA\n")
+    out.emit("const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {\n")
+    for uop in analysis.uops.values():
+        if uop.is_viable() and not uop.properties.tier_one_only:
+            out.emit(f"[{uop.name}] = {cflags(uop.properties)},\n")
+
+    out.emit("};\n\n")
+    out.emit("const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {\n")
+    for uop in sorted(analysis.uops.values(), key=lambda t: t.name):
+        if uop.is_viable() and not uop.properties.tier_one_only:
+            out.emit(f'[{uop.name}] = "{uop.name}",\n')
+    out.emit("};\n")
+    out.emit("#endif // NEED_OPCODE_METADATA\n\n")
+
+
+def generate_uop_metadata(
+    filenames: list[str], analysis: Analysis, outfile: TextIO
+) -> None:
+    write_header(__file__, filenames, outfile)
+    out = CWriter(outfile, 0, False)
+    with out.header_guard("Py_CORE_UOP_METADATA_H"):
+        out.emit("#include <stdint.h>\n")
+        out.emit('#include "pycore_uop_ids.h"\n')
+        generate_names_and_flags(analysis, out)
+
+
+arg_parser = argparse.ArgumentParser(
+    description="Generate the header file with uop metadata.",
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+)
+
+arg_parser.add_argument(
+    "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
+)
+
+arg_parser.add_argument(
+    "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
+)
+
+if __name__ == "__main__":
+    args = arg_parser.parse_args()
+    if len(args.input) == 0:
+        args.input.append(DEFAULT_INPUT)
+    data = analyze_files(args.input)
+    with open(args.output, "w") as outfile:
+        generate_uop_metadata(args.input, data, outfile)