diff options
-rw-r--r-- | Include/cpython/pystats.h | 1 | ||||
-rw-r--r-- | Include/internal/pycore_optimizer.h | 3 | ||||
-rw-r--r-- | Include/internal/pycore_uop_ids.h | 247 | ||||
-rw-r--r-- | Include/internal/pycore_uop_metadata.h | 4 | ||||
-rw-r--r-- | Lib/test/test_capi/test_opt.py | 1 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst | 1 | ||||
-rw-r--r-- | Python/bytecodes.c | 36 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 42 | ||||
-rw-r--r-- | Python/optimizer.c | 18 | ||||
-rw-r--r-- | Python/optimizer_analysis.c | 1 | ||||
-rw-r--r-- | Python/optimizer_cases.c.h | 4 | ||||
-rw-r--r-- | Python/specialize.c | 1 | ||||
-rw-r--r-- | Tools/scripts/summarize_stats.py | 5 |
13 files changed, 138 insertions, 226 deletions
diff --git a/Include/cpython/pystats.h b/Include/cpython/pystats.h index f52348e42b1..4421b4d6e91 100644 --- a/Include/cpython/pystats.h +++ b/Include/cpython/pystats.h @@ -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]; diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 00fc4338b0a..25c3d3e5a22 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -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 ); } diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index ca40af55406..554e3439e0b 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -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 } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 2f957afb259..2e126b57aa7 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -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: diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 02e534caec1..2a9b777862c 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -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 index 00000000000..f8eb7481aea --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-22-58-18.gh-issue-129715.mLlpIO.rst @@ -0,0 +1 @@ +Improve JIT performance for generators. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 9fb58b9cdcc..bef120b6477 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -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 diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 2e7f5ecc7aa..dc657281321 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -6510,48 +6510,6 @@ 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); diff --git a/Python/optimizer.c b/Python/optimizer.c index 97831f58098..340770ae55e 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -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); diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 5dd7725f398..6c0aadb87e6 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -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: { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index dde41d9407e..2383be8ea30 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2469,10 +2469,6 @@ break; } - case _DYNAMIC_EXIT: { - break; - } - case _START_EXECUTOR: { break; } diff --git a/Python/specialize.c b/Python/specialize.c index 8831cfaa82b..4f84b2970ba 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -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); diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index 161af09183a..4243b53850b 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -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 { @@ -498,6 +499,10 @@ class Stats: "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 " "dictionary changes.", |