]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-129715: Remove _DYNAMIC_EXIT (GH-129716)
authorBrandt Bucher <brandtbucher@microsoft.com>
Fri, 7 Feb 2025 19:41:17 +0000 (11:41 -0800)
committerGitHub <noreply@github.com>
Fri, 7 Feb 2025 19:41:17 +0000 (11:41 -0800)
13 files changed:
Include/cpython/pystats.h
Include/internal/pycore_optimizer.h
Include/internal/pycore_uop_ids.h
Include/internal/pycore_uop_metadata.h
Lib/test/test_capi/test_opt.py
Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst [new file with mode: 0644]
Python/bytecodes.c
Python/executor_cases.c.h
Python/optimizer.c
Python/optimizer_analysis.c
Python/optimizer_cases.c.h
Python/specialize.c
Tools/scripts/summarize_stats.py

index f52348e42b1330f115bd897912e6a25009c25ce8..4421b4d6e91dad4de7da879c1183e3fdafdeb098 100644 (file)
@@ -129,6 +129,7 @@ typedef struct _optimization_stats {
     uint64_t inner_loop;
     uint64_t recursive_call;
     uint64_t low_confidence;
+    uint64_t unknown_callee;
     uint64_t executors_invalidated;
     UOpStats opcode[PYSTATS_MAX_UOP_ID + 1];
     uint64_t unsupported_opcode[256];
index 00fc4338b0a412ade9e47884db30183cdc1701fc..25c3d3e5a224423804e0e34dd4073e15b82bdf3d 100644 (file)
@@ -289,8 +289,7 @@ static inline int is_terminator(const _PyUOpInstruction *uop)
     int opcode = uop->opcode;
     return (
         opcode == _EXIT_TRACE ||
-        opcode == _JUMP_TO_TOP ||
-        opcode == _DYNAMIC_EXIT
+        opcode == _JUMP_TO_TOP
     );
 }
 
index ca40af55406089eceb6f03aff240b2bb6281469e..554e3439e0b1da7e2363c9adba54b9eaac42b802 100644 (file)
@@ -101,57 +101,56 @@ extern "C" {
 #define _DO_CALL 358
 #define _DO_CALL_FUNCTION_EX 359
 #define _DO_CALL_KW 360
-#define _DYNAMIC_EXIT 361
 #define _END_FOR END_FOR
 #define _END_SEND END_SEND
-#define _ERROR_POP_N 362
+#define _ERROR_POP_N 361
 #define _EXIT_INIT_CHECK EXIT_INIT_CHECK
-#define _EXPAND_METHOD 363
-#define _EXPAND_METHOD_KW 364
-#define _FATAL_ERROR 365
+#define _EXPAND_METHOD 362
+#define _EXPAND_METHOD_KW 363
+#define _FATAL_ERROR 364
 #define _FORMAT_SIMPLE FORMAT_SIMPLE
 #define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
-#define _FOR_ITER 366
-#define _FOR_ITER_GEN_FRAME 367
-#define _FOR_ITER_TIER_TWO 368
+#define _FOR_ITER 365
+#define _FOR_ITER_GEN_FRAME 366
+#define _FOR_ITER_TIER_TWO 367
 #define _GET_AITER GET_AITER
 #define _GET_ANEXT GET_ANEXT
 #define _GET_AWAITABLE GET_AWAITABLE
 #define _GET_ITER GET_ITER
 #define _GET_LEN GET_LEN
 #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
-#define _GUARD_BINARY_OP_EXTEND 369
-#define _GUARD_BOTH_FLOAT 370
-#define _GUARD_BOTH_INT 371
-#define _GUARD_BOTH_UNICODE 372
-#define _GUARD_BUILTINS_VERSION_PUSH_KEYS 373
-#define _GUARD_DORV_NO_DICT 374
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 375
-#define _GUARD_GLOBALS_VERSION 376
-#define _GUARD_GLOBALS_VERSION_PUSH_KEYS 377
-#define _GUARD_IS_FALSE_POP 378
-#define _GUARD_IS_NONE_POP 379
-#define _GUARD_IS_NOT_NONE_POP 380
-#define _GUARD_IS_TRUE_POP 381
-#define _GUARD_KEYS_VERSION 382
-#define _GUARD_NOS_FLOAT 383
-#define _GUARD_NOS_INT 384
-#define _GUARD_NOT_EXHAUSTED_LIST 385
-#define _GUARD_NOT_EXHAUSTED_RANGE 386
-#define _GUARD_NOT_EXHAUSTED_TUPLE 387
-#define _GUARD_TOS_FLOAT 388
-#define _GUARD_TOS_INT 389
-#define _GUARD_TYPE_VERSION 390
-#define _GUARD_TYPE_VERSION_AND_LOCK 391
+#define _GUARD_BINARY_OP_EXTEND 368
+#define _GUARD_BOTH_FLOAT 369
+#define _GUARD_BOTH_INT 370
+#define _GUARD_BOTH_UNICODE 371
+#define _GUARD_BUILTINS_VERSION_PUSH_KEYS 372
+#define _GUARD_DORV_NO_DICT 373
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 374
+#define _GUARD_GLOBALS_VERSION 375
+#define _GUARD_GLOBALS_VERSION_PUSH_KEYS 376
+#define _GUARD_IS_FALSE_POP 377
+#define _GUARD_IS_NONE_POP 378
+#define _GUARD_IS_NOT_NONE_POP 379
+#define _GUARD_IS_TRUE_POP 380
+#define _GUARD_KEYS_VERSION 381
+#define _GUARD_NOS_FLOAT 382
+#define _GUARD_NOS_INT 383
+#define _GUARD_NOT_EXHAUSTED_LIST 384
+#define _GUARD_NOT_EXHAUSTED_RANGE 385
+#define _GUARD_NOT_EXHAUSTED_TUPLE 386
+#define _GUARD_TOS_FLOAT 387
+#define _GUARD_TOS_INT 388
+#define _GUARD_TYPE_VERSION 389
+#define _GUARD_TYPE_VERSION_AND_LOCK 390
 #define _IMPORT_FROM IMPORT_FROM
 #define _IMPORT_NAME IMPORT_NAME
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 392
-#define _INIT_CALL_PY_EXACT_ARGS 393
-#define _INIT_CALL_PY_EXACT_ARGS_0 394
-#define _INIT_CALL_PY_EXACT_ARGS_1 395
-#define _INIT_CALL_PY_EXACT_ARGS_2 396
-#define _INIT_CALL_PY_EXACT_ARGS_3 397
-#define _INIT_CALL_PY_EXACT_ARGS_4 398
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 391
+#define _INIT_CALL_PY_EXACT_ARGS 392
+#define _INIT_CALL_PY_EXACT_ARGS_0 393
+#define _INIT_CALL_PY_EXACT_ARGS_1 394
+#define _INIT_CALL_PY_EXACT_ARGS_2 395
+#define _INIT_CALL_PY_EXACT_ARGS_3 396
+#define _INIT_CALL_PY_EXACT_ARGS_4 397
 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
 #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
 #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -161,137 +160,137 @@ extern "C" {
 #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 _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
-#define _IS_NONE 399
+#define _IS_NONE 398
 #define _IS_OP IS_OP
-#define _ITER_CHECK_LIST 400
-#define _ITER_CHECK_RANGE 401
-#define _ITER_CHECK_TUPLE 402
-#define _ITER_JUMP_LIST 403
-#define _ITER_JUMP_RANGE 404
-#define _ITER_JUMP_TUPLE 405
-#define _ITER_NEXT_LIST 406
-#define _ITER_NEXT_RANGE 407
-#define _ITER_NEXT_TUPLE 408
-#define _JUMP_TO_TOP 409
+#define _ITER_CHECK_LIST 399
+#define _ITER_CHECK_RANGE 400
+#define _ITER_CHECK_TUPLE 401
+#define _ITER_JUMP_LIST 402
+#define _ITER_JUMP_RANGE 403
+#define _ITER_JUMP_TUPLE 404
+#define _ITER_NEXT_LIST 405
+#define _ITER_NEXT_RANGE 406
+#define _ITER_NEXT_TUPLE 407
+#define _JUMP_TO_TOP 408
 #define _LIST_APPEND LIST_APPEND
 #define _LIST_EXTEND LIST_EXTEND
-#define _LOAD_ATTR 410
-#define _LOAD_ATTR_CLASS 411
+#define _LOAD_ATTR 409
+#define _LOAD_ATTR_CLASS 410
 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _LOAD_ATTR_INSTANCE_VALUE 412
-#define _LOAD_ATTR_METHOD_LAZY_DICT 413
-#define _LOAD_ATTR_METHOD_NO_DICT 414
-#define _LOAD_ATTR_METHOD_WITH_VALUES 415
-#define _LOAD_ATTR_MODULE 416
-#define _LOAD_ATTR_MODULE_FROM_KEYS 417
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 418
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 419
-#define _LOAD_ATTR_PROPERTY_FRAME 420
-#define _LOAD_ATTR_SLOT 421
-#define _LOAD_ATTR_WITH_HINT 422
+#define _LOAD_ATTR_INSTANCE_VALUE 411
+#define _LOAD_ATTR_METHOD_LAZY_DICT 412
+#define _LOAD_ATTR_METHOD_NO_DICT 413
+#define _LOAD_ATTR_METHOD_WITH_VALUES 414
+#define _LOAD_ATTR_MODULE 415
+#define _LOAD_ATTR_MODULE_FROM_KEYS 416
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 417
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 418
+#define _LOAD_ATTR_PROPERTY_FRAME 419
+#define _LOAD_ATTR_SLOT 420
+#define _LOAD_ATTR_WITH_HINT 421
 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 423
+#define _LOAD_BYTECODE 422
 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
 #define _LOAD_CONST LOAD_CONST
 #define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
-#define _LOAD_CONST_INLINE 424
-#define _LOAD_CONST_INLINE_BORROW 425
+#define _LOAD_CONST_INLINE 423
+#define _LOAD_CONST_INLINE_BORROW 424
 #define _LOAD_CONST_MORTAL LOAD_CONST_MORTAL
 #define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 426
-#define _LOAD_FAST_0 427
-#define _LOAD_FAST_1 428
-#define _LOAD_FAST_2 429
-#define _LOAD_FAST_3 430
-#define _LOAD_FAST_4 431
-#define _LOAD_FAST_5 432
-#define _LOAD_FAST_6 433
-#define _LOAD_FAST_7 434
+#define _LOAD_FAST 425
+#define _LOAD_FAST_0 426
+#define _LOAD_FAST_1 427
+#define _LOAD_FAST_2 428
+#define _LOAD_FAST_3 429
+#define _LOAD_FAST_4 430
+#define _LOAD_FAST_5 431
+#define _LOAD_FAST_6 432
+#define _LOAD_FAST_7 433
 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK
 #define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
 #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
 #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
-#define _LOAD_GLOBAL 435
-#define _LOAD_GLOBAL_BUILTINS 436
-#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 437
-#define _LOAD_GLOBAL_MODULE 438
-#define _LOAD_GLOBAL_MODULE_FROM_KEYS 439
+#define _LOAD_GLOBAL 434
+#define _LOAD_GLOBAL_BUILTINS 435
+#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 436
+#define _LOAD_GLOBAL_MODULE 437
+#define _LOAD_GLOBAL_MODULE_FROM_KEYS 438
 #define _LOAD_LOCALS LOAD_LOCALS
 #define _LOAD_NAME LOAD_NAME
-#define _LOAD_SMALL_INT 440
-#define _LOAD_SMALL_INT_0 441
-#define _LOAD_SMALL_INT_1 442
-#define _LOAD_SMALL_INT_2 443
-#define _LOAD_SMALL_INT_3 444
+#define _LOAD_SMALL_INT 439
+#define _LOAD_SMALL_INT_0 440
+#define _LOAD_SMALL_INT_1 441
+#define _LOAD_SMALL_INT_2 442
+#define _LOAD_SMALL_INT_3 443
 #define _LOAD_SPECIAL LOAD_SPECIAL
 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
 #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 445
+#define _MAKE_CALLARGS_A_TUPLE 444
 #define _MAKE_CELL MAKE_CELL
 #define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 446
+#define _MAKE_WARM 445
 #define _MAP_ADD MAP_ADD
 #define _MATCH_CLASS MATCH_CLASS
 #define _MATCH_KEYS MATCH_KEYS
 #define _MATCH_MAPPING MATCH_MAPPING
 #define _MATCH_SEQUENCE MATCH_SEQUENCE
-#define _MAYBE_EXPAND_METHOD 447
-#define _MAYBE_EXPAND_METHOD_KW 448
-#define _MONITOR_CALL 449
-#define _MONITOR_CALL_KW 450
-#define _MONITOR_JUMP_BACKWARD 451
-#define _MONITOR_RESUME 452
+#define _MAYBE_EXPAND_METHOD 446
+#define _MAYBE_EXPAND_METHOD_KW 447
+#define _MONITOR_CALL 448
+#define _MONITOR_CALL_KW 449
+#define _MONITOR_JUMP_BACKWARD 450
+#define _MONITOR_RESUME 451
 #define _NOP NOP
 #define _POP_EXCEPT POP_EXCEPT
-#define _POP_JUMP_IF_FALSE 453
-#define _POP_JUMP_IF_TRUE 454
+#define _POP_JUMP_IF_FALSE 452
+#define _POP_JUMP_IF_TRUE 453
 #define _POP_TOP POP_TOP
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW 455
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 454
 #define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 456
+#define _PUSH_FRAME 455
 #define _PUSH_NULL PUSH_NULL
-#define _PUSH_NULL_CONDITIONAL 457
-#define _PY_FRAME_GENERAL 458
-#define _PY_FRAME_KW 459
-#define _QUICKEN_RESUME 460
-#define _REPLACE_WITH_TRUE 461
+#define _PUSH_NULL_CONDITIONAL 456
+#define _PY_FRAME_GENERAL 457
+#define _PY_FRAME_KW 458
+#define _QUICKEN_RESUME 459
+#define _REPLACE_WITH_TRUE 460
 #define _RESUME_CHECK RESUME_CHECK
 #define _RETURN_GENERATOR RETURN_GENERATOR
 #define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 462
-#define _SEND 463
-#define _SEND_GEN_FRAME 464
+#define _SAVE_RETURN_OFFSET 461
+#define _SEND 462
+#define _SEND_GEN_FRAME 463
 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
 #define _SET_ADD SET_ADD
 #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
 #define _SET_UPDATE SET_UPDATE
-#define _START_EXECUTOR 465
-#define _STORE_ATTR 466
-#define _STORE_ATTR_INSTANCE_VALUE 467
-#define _STORE_ATTR_SLOT 468
-#define _STORE_ATTR_WITH_HINT 469
+#define _START_EXECUTOR 464
+#define _STORE_ATTR 465
+#define _STORE_ATTR_INSTANCE_VALUE 466
+#define _STORE_ATTR_SLOT 467
+#define _STORE_ATTR_WITH_HINT 468
 #define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 470
-#define _STORE_FAST_0 471
-#define _STORE_FAST_1 472
-#define _STORE_FAST_2 473
-#define _STORE_FAST_3 474
-#define _STORE_FAST_4 475
-#define _STORE_FAST_5 476
-#define _STORE_FAST_6 477
-#define _STORE_FAST_7 478
+#define _STORE_FAST 469
+#define _STORE_FAST_0 470
+#define _STORE_FAST_1 471
+#define _STORE_FAST_2 472
+#define _STORE_FAST_3 473
+#define _STORE_FAST_4 474
+#define _STORE_FAST_5 475
+#define _STORE_FAST_6 476
+#define _STORE_FAST_7 477
 #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
 #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
 #define _STORE_GLOBAL STORE_GLOBAL
 #define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 479
-#define _STORE_SUBSCR 480
+#define _STORE_SLICE 478
+#define _STORE_SUBSCR 479
 #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
 #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
 #define _SWAP SWAP
-#define _TIER2_RESUME_CHECK 481
-#define _TO_BOOL 482
+#define _TIER2_RESUME_CHECK 480
+#define _TO_BOOL 481
 #define _TO_BOOL_BOOL TO_BOOL_BOOL
 #define _TO_BOOL_INT TO_BOOL_INT
 #define _TO_BOOL_LIST TO_BOOL_LIST
@@ -301,13 +300,13 @@ extern "C" {
 #define _UNARY_NEGATIVE UNARY_NEGATIVE
 #define _UNARY_NOT UNARY_NOT
 #define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 483
+#define _UNPACK_SEQUENCE 482
 #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
 #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
 #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
 #define _WITH_EXCEPT_START WITH_EXCEPT_START
 #define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 483
+#define MAX_UOP_ID 482
 
 #ifdef __cplusplus
 }
index 2f957afb259b0f82ebd3d87e80e7a22002d8529f..2e126b57aa7dbd62b808fca6b7d1ebdd5067a93f 100644 (file)
@@ -281,7 +281,6 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_LOAD_GLOBAL_MODULE] = HAS_DEOPT_FLAG,
     [_LOAD_GLOBAL_BUILTINS] = HAS_DEOPT_FLAG,
     [_LOAD_ATTR_MODULE] = HAS_DEOPT_FLAG,
-    [_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
     [_START_EXECUTOR] = HAS_ESCAPES_FLAG,
     [_MAKE_WARM] = 0,
     [_FATAL_ERROR] = 0,
@@ -386,7 +385,6 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
     [_DEOPT] = "_DEOPT",
     [_DICT_MERGE] = "_DICT_MERGE",
     [_DICT_UPDATE] = "_DICT_UPDATE",
-    [_DYNAMIC_EXIT] = "_DYNAMIC_EXIT",
     [_END_FOR] = "_END_FOR",
     [_END_SEND] = "_END_SEND",
     [_ERROR_POP_N] = "_ERROR_POP_N",
@@ -1097,8 +1095,6 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _LOAD_ATTR_MODULE:
             return 1;
-        case _DYNAMIC_EXIT:
-            return 0;
         case _START_EXECUTOR:
             return 0;
         case _MAKE_WARM:
index 02e534caec1162bffb8ea3ed01a8614246faba66..2a9b777862c84a6bc0afc3b2308726a9e5b2f47d 100644 (file)
@@ -1160,6 +1160,7 @@ class TestUopsOptimization(unittest.TestCase):
         self.assertIsNotNone(ex)
         self.assertIn("_RETURN_GENERATOR", get_opnames(ex))
 
+    @unittest.skip("Tracing into generators currently isn't supported.")
     def test_for_iter_gen(self):
         def gen(n):
             for i in range(n):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst
new file mode 100644 (file)
index 0000000..f8eb748
--- /dev/null
@@ -0,0 +1 @@
+Improve JIT performance for generators.
index 9fb58b9cdcc0220017ed5c70cb23e1d340e4870d..bef120b64779d9c0ce19e0bb9ee820ece0de882b 100644 (file)
@@ -5117,42 +5117,6 @@ dummy_func(
             DECREF_INPUTS();
         }
 
-        tier2 op(_DYNAMIC_EXIT, (exit_p/4 --)) {
-            tstate->previous_executor = (PyObject *)current_executor;
-            _PyExitData *exit = (_PyExitData *)exit_p;
-            _Py_CODEUNIT *target = frame->instr_ptr;
-        #if defined(Py_DEBUG) && !defined(_Py_JIT)
-            OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
-            if (frame->lltrace >= 2) {
-                printf("DYNAMIC EXIT: [UOp ");
-                _PyUOpPrint(&next_uop[-1]);
-                printf(", exit %lu, temp %d, target %d -> %s]\n",
-                    exit - current_executor->exits, exit->temperature.value_and_backoff,
-                    (int)(target - _PyFrame_GetBytecode(frame)),
-                    _PyOpcode_OpName[target->op.code]);
-            }
-        #endif
-            _PyExecutorObject *executor;
-            if (target->op.code == ENTER_EXECUTOR) {
-                PyCodeObject *code = _PyFrame_GetCode(frame);
-                executor = code->co_executors->executors[target->op.arg];
-                Py_INCREF(executor);
-            }
-            else {
-                if (!backoff_counter_triggers(exit->temperature)) {
-                    exit->temperature = advance_backoff_counter(exit->temperature);
-                    GOTO_TIER_ONE(target);
-                }
-                int optimized = _PyOptimizer_Optimize(frame, target, &executor, 0);
-                if (optimized <= 0) {
-                    exit->temperature = restart_backoff_counter(exit->temperature);
-                    GOTO_TIER_ONE(optimized < 0 ? NULL : target);
-                }
-                exit->temperature = initial_temperature_backoff_counter();
-            }
-            GOTO_TIER_TWO(executor);
-        }
-
         tier2 op(_START_EXECUTOR, (executor/4 --)) {
             Py_CLEAR(tstate->previous_executor);
 #ifndef _Py_JIT
index 2e7f5ecc7aa4da8d51b871f4bcc16653bd231489..dc6572813212aa5f2ac2763f579476736e3c675d 100644 (file)
             break;
         }
 
-        case _DYNAMIC_EXIT: {
-            PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
-            tstate->previous_executor = (PyObject *)current_executor;
-            _PyExitData *exit = (_PyExitData *)exit_p;
-            _Py_CODEUNIT *target = frame->instr_ptr;
-            #if defined(Py_DEBUG) && !defined(_Py_JIT)
-            OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
-            if (frame->lltrace >= 2) {
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                printf("DYNAMIC EXIT: [UOp ");
-                _PyUOpPrint(&next_uop[-1]);
-                printf(", exit %lu, temp %d, target %d -> %s]\n",
-                       exit - current_executor->exits, exit->temperature.value_and_backoff,
-                       (int)(target - _PyFrame_GetBytecode(frame)),
-                       _PyOpcode_OpName[target->op.code]);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-            }
-            #endif
-            _PyExecutorObject *executor;
-            if (target->op.code == ENTER_EXECUTOR) {
-                PyCodeObject *code = _PyFrame_GetCode(frame);
-                executor = code->co_executors->executors[target->op.arg];
-                Py_INCREF(executor);
-            }
-            else {
-                if (!backoff_counter_triggers(exit->temperature)) {
-                    exit->temperature = advance_backoff_counter(exit->temperature);
-                    GOTO_TIER_ONE(target);
-                }
-                _PyFrame_SetStackPointer(frame, stack_pointer);
-                int optimized = _PyOptimizer_Optimize(frame, target, &executor, 0);
-                stack_pointer = _PyFrame_GetStackPointer(frame);
-                if (optimized <= 0) {
-                    exit->temperature = restart_backoff_counter(exit->temperature);
-                    GOTO_TIER_ONE(optimized < 0 ? NULL : target);
-                }
-                exit->temperature = initial_temperature_backoff_counter();
-            }
-            GOTO_TIER_TWO(executor);
-            break;
-        }
-
         case _START_EXECUTOR: {
             PyObject *executor = (PyObject *)CURRENT_OPERAND0();
             _PyFrame_SetStackPointer(frame, stack_pointer);
index 97831f58098c95c80ee56ef9047878d8ce9cc47f..340770ae55ec579464abee1e8c6ee8888654fe88 100644 (file)
@@ -757,9 +757,8 @@ translate_bytecode_to_trace(
                                 opcode == SEND_GEN)
                             {
                                 DPRINTF(2, "Bailing due to dynamic target\n");
-                                ADD_TO_TRACE(uop, oparg, 0, target);
-                                ADD_TO_TRACE(_DYNAMIC_EXIT, 0, 0, 0);
-                                goto done;
+                                OPT_STAT_INC(unknown_callee);
+                                return 0;
                             }
                             assert(_PyOpcode_Deopt[opcode] == CALL || _PyOpcode_Deopt[opcode] == CALL_KW);
                             int func_version_offset =
@@ -825,9 +824,8 @@ translate_bytecode_to_trace(
                                 goto top;
                             }
                             DPRINTF(2, "Bail, new_code == NULL\n");
-                            ADD_TO_TRACE(uop, oparg, 0, target);
-                            ADD_TO_TRACE(_DYNAMIC_EXIT, 0, 0, 0);
-                            goto done;
+                            OPT_STAT_INC(unknown_callee);
+                            return 0;
                         }
 
                         if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) {
@@ -914,7 +912,7 @@ count_exits(_PyUOpInstruction *buffer, int length)
     int exit_count = 0;
     for (int i = 0; i < length; i++) {
         int opcode = buffer[i].opcode;
-        if (opcode == _EXIT_TRACE || opcode == _DYNAMIC_EXIT) {
+        if (opcode == _EXIT_TRACE) {
             exit_count++;
         }
     }
@@ -1119,12 +1117,6 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil
             dest->operand0 = (uint64_t)exit;
             next_exit--;
         }
-        if (opcode == _DYNAMIC_EXIT) {
-            _PyExitData *exit = &executor->exits[next_exit];
-            exit->target = 0;
-            dest->operand0 = (uint64_t)exit;
-            next_exit--;
-        }
     }
     assert(next_exit == -1);
     assert(dest == executor->trace);
index 5dd7725f398cd1dad7ed6e50d8cf274897b59c7d..6c0aadb87e67411b8c6ac088a87e85b371aff4da 100644 (file)
@@ -616,7 +616,6 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
             }
             case _JUMP_TO_TOP:
             case _EXIT_TRACE:
-            case _DYNAMIC_EXIT:
                 return pc + 1;
             default:
             {
index dde41d9407ee33e72a0e300cc7897d10e8ed73c9..2383be8ea3086eea7a8cffcb1338d39978a5e2ff 100644 (file)
             break;
         }
 
-        case _DYNAMIC_EXIT: {
-            break;
-        }
-
         case _START_EXECUTOR: {
             break;
         }
index 8831cfaa82be9b66521d569f22988533742caf53..4f84b2970ba98a38c4e8072ede474c24ef1c132c 100644 (file)
@@ -260,6 +260,7 @@ print_optimization_stats(FILE *out, OptimizationStats *stats)
     fprintf(out, "Optimization inner loop: %" PRIu64 "\n", stats->inner_loop);
     fprintf(out, "Optimization recursive call: %" PRIu64 "\n", stats->recursive_call);
     fprintf(out, "Optimization low confidence: %" PRIu64 "\n", stats->low_confidence);
+    fprintf(out, "Optimization unknown callee: %" PRIu64 "\n", stats->unknown_callee);
     fprintf(out, "Executors invalidated: %" PRIu64 "\n", stats->executors_invalidated);
 
     print_histogram(out, "Trace length", stats->trace_length_hist);
index 161af09183a282da56d8fc861036c16b3cc60ec4..4243b53850b3de9089c3abad21cc3e0787c9f5e0 100644 (file)
@@ -457,6 +457,7 @@ class Stats:
         inner_loop = self._data["Optimization inner loop"]
         recursive_call = self._data["Optimization recursive call"]
         low_confidence = self._data["Optimization low confidence"]
+        unknown_callee = self._data["Optimization unknown callee"]
         executors_invalidated = self._data["Executors invalidated"]
 
         return {
@@ -497,6 +498,10 @@ class Stats:
                 "A trace is abandoned because the likelihood of the jump to top being taken "
                 "is too low.",
             ): (low_confidence, attempts),
+            Doc(
+                "Unknown callee",
+                "A trace is abandoned because the target of a call is unknown.",
+            ): (unknown_callee, attempts),
             Doc(
                 "Executors invalidated",
                 "The number of executors that were invalidated due to watched "