diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 7f468bbb932184..36df6b14d1029c 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1330,7 +1330,7 @@ _PyOpcode_macro_expansion[256] = { [BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 3, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBSCR_STR_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 } } }, - [BINARY_OP_SUBSCR_TUPLE_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_TUPLE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_TUPLE_INT, OPARG_SIMPLE, 5 } } }, + [BINARY_OP_SUBSCR_TUPLE_INT] = { .nuops = 4, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_TUPLE, OPARG_SIMPLE, 0 }, { _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_TUPLE_INT, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 3, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, OPARG_SIMPLE, 5 } } }, [BINARY_OP_SUBTRACT_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_INT, OPARG_SIMPLE, 5 } } }, [BINARY_SLICE] = { .nuops = 1, .uops = { { _BINARY_SLICE, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 749369a40aecdd..3b34697c879ef8 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -128,55 +128,56 @@ extern "C" { #define _GET_LEN GET_LEN #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER #define _GUARD_BINARY_OP_EXTEND 385 -#define _GUARD_CALLABLE_ISINSTANCE 386 -#define _GUARD_CALLABLE_LEN 387 -#define _GUARD_CALLABLE_LIST_APPEND 388 -#define _GUARD_CALLABLE_STR_1 389 -#define _GUARD_CALLABLE_TUPLE_1 390 -#define _GUARD_CALLABLE_TYPE_1 391 -#define _GUARD_DORV_NO_DICT 392 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 393 -#define _GUARD_GLOBALS_VERSION 394 -#define _GUARD_IS_FALSE_POP 395 -#define _GUARD_IS_NONE_POP 396 -#define _GUARD_IS_NOT_NONE_POP 397 -#define _GUARD_IS_TRUE_POP 398 -#define _GUARD_KEYS_VERSION 399 -#define _GUARD_NOS_DICT 400 -#define _GUARD_NOS_FLOAT 401 -#define _GUARD_NOS_INT 402 -#define _GUARD_NOS_LIST 403 -#define _GUARD_NOS_NOT_NULL 404 -#define _GUARD_NOS_NULL 405 -#define _GUARD_NOS_OVERFLOWED 406 -#define _GUARD_NOS_TUPLE 407 -#define _GUARD_NOS_UNICODE 408 -#define _GUARD_NOT_EXHAUSTED_LIST 409 -#define _GUARD_NOT_EXHAUSTED_RANGE 410 -#define _GUARD_NOT_EXHAUSTED_TUPLE 411 -#define _GUARD_THIRD_NULL 412 -#define _GUARD_TOS_ANY_SET 413 -#define _GUARD_TOS_DICT 414 -#define _GUARD_TOS_FLOAT 415 -#define _GUARD_TOS_INT 416 -#define _GUARD_TOS_LIST 417 -#define _GUARD_TOS_OVERFLOWED 418 -#define _GUARD_TOS_SLICE 419 -#define _GUARD_TOS_TUPLE 420 -#define _GUARD_TOS_UNICODE 421 -#define _GUARD_TYPE_VERSION 422 -#define _GUARD_TYPE_VERSION_AND_LOCK 423 -#define _HANDLE_PENDING_AND_DEOPT 424 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS 386 +#define _GUARD_CALLABLE_ISINSTANCE 387 +#define _GUARD_CALLABLE_LEN 388 +#define _GUARD_CALLABLE_LIST_APPEND 389 +#define _GUARD_CALLABLE_STR_1 390 +#define _GUARD_CALLABLE_TUPLE_1 391 +#define _GUARD_CALLABLE_TYPE_1 392 +#define _GUARD_DORV_NO_DICT 393 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 394 +#define _GUARD_GLOBALS_VERSION 395 +#define _GUARD_IS_FALSE_POP 396 +#define _GUARD_IS_NONE_POP 397 +#define _GUARD_IS_NOT_NONE_POP 398 +#define _GUARD_IS_TRUE_POP 399 +#define _GUARD_KEYS_VERSION 400 +#define _GUARD_NOS_DICT 401 +#define _GUARD_NOS_FLOAT 402 +#define _GUARD_NOS_INT 403 +#define _GUARD_NOS_LIST 404 +#define _GUARD_NOS_NOT_NULL 405 +#define _GUARD_NOS_NULL 406 +#define _GUARD_NOS_OVERFLOWED 407 +#define _GUARD_NOS_TUPLE 408 +#define _GUARD_NOS_UNICODE 409 +#define _GUARD_NOT_EXHAUSTED_LIST 410 +#define _GUARD_NOT_EXHAUSTED_RANGE 411 +#define _GUARD_NOT_EXHAUSTED_TUPLE 412 +#define _GUARD_THIRD_NULL 413 +#define _GUARD_TOS_ANY_SET 414 +#define _GUARD_TOS_DICT 415 +#define _GUARD_TOS_FLOAT 416 +#define _GUARD_TOS_INT 417 +#define _GUARD_TOS_LIST 418 +#define _GUARD_TOS_OVERFLOWED 419 +#define _GUARD_TOS_SLICE 420 +#define _GUARD_TOS_TUPLE 421 +#define _GUARD_TOS_UNICODE 422 +#define _GUARD_TYPE_VERSION 423 +#define _GUARD_TYPE_VERSION_AND_LOCK 424 +#define _HANDLE_PENDING_AND_DEOPT 425 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 425 -#define _INIT_CALL_PY_EXACT_ARGS 426 -#define _INIT_CALL_PY_EXACT_ARGS_0 427 -#define _INIT_CALL_PY_EXACT_ARGS_1 428 -#define _INIT_CALL_PY_EXACT_ARGS_2 429 -#define _INIT_CALL_PY_EXACT_ARGS_3 430 -#define _INIT_CALL_PY_EXACT_ARGS_4 431 -#define _INSERT_NULL 432 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 426 +#define _INIT_CALL_PY_EXACT_ARGS 427 +#define _INIT_CALL_PY_EXACT_ARGS_0 428 +#define _INIT_CALL_PY_EXACT_ARGS_1 429 +#define _INIT_CALL_PY_EXACT_ARGS_2 430 +#define _INIT_CALL_PY_EXACT_ARGS_3 431 +#define _INIT_CALL_PY_EXACT_ARGS_4 432 +#define _INSERT_NULL 433 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -186,177 +187,177 @@ 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 433 +#define _IS_NONE 434 #define _IS_OP IS_OP -#define _ITER_CHECK_LIST 434 -#define _ITER_CHECK_RANGE 435 -#define _ITER_CHECK_TUPLE 436 -#define _ITER_JUMP_LIST 437 -#define _ITER_JUMP_RANGE 438 -#define _ITER_JUMP_TUPLE 439 -#define _ITER_NEXT_LIST 440 -#define _ITER_NEXT_LIST_TIER_TWO 441 -#define _ITER_NEXT_RANGE 442 -#define _ITER_NEXT_TUPLE 443 -#define _JUMP_TO_TOP 444 +#define _ITER_CHECK_LIST 435 +#define _ITER_CHECK_RANGE 436 +#define _ITER_CHECK_TUPLE 437 +#define _ITER_JUMP_LIST 438 +#define _ITER_JUMP_RANGE 439 +#define _ITER_JUMP_TUPLE 440 +#define _ITER_NEXT_LIST 441 +#define _ITER_NEXT_LIST_TIER_TWO 442 +#define _ITER_NEXT_RANGE 443 +#define _ITER_NEXT_TUPLE 444 +#define _JUMP_TO_TOP 445 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 445 -#define _LOAD_ATTR_CLASS 446 +#define _LOAD_ATTR 446 +#define _LOAD_ATTR_CLASS 447 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 447 -#define _LOAD_ATTR_METHOD_LAZY_DICT 448 -#define _LOAD_ATTR_METHOD_NO_DICT 449 -#define _LOAD_ATTR_METHOD_WITH_VALUES 450 -#define _LOAD_ATTR_MODULE 451 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 452 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 453 -#define _LOAD_ATTR_PROPERTY_FRAME 454 -#define _LOAD_ATTR_SLOT 455 -#define _LOAD_ATTR_WITH_HINT 456 +#define _LOAD_ATTR_INSTANCE_VALUE 448 +#define _LOAD_ATTR_METHOD_LAZY_DICT 449 +#define _LOAD_ATTR_METHOD_NO_DICT 450 +#define _LOAD_ATTR_METHOD_WITH_VALUES 451 +#define _LOAD_ATTR_MODULE 452 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 453 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 454 +#define _LOAD_ATTR_PROPERTY_FRAME 455 +#define _LOAD_ATTR_SLOT 456 +#define _LOAD_ATTR_WITH_HINT 457 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 457 +#define _LOAD_BYTECODE 458 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 458 -#define _LOAD_CONST_INLINE_BORROW 459 -#define _LOAD_CONST_UNDER_INLINE 460 -#define _LOAD_CONST_UNDER_INLINE_BORROW 461 +#define _LOAD_CONST_INLINE 459 +#define _LOAD_CONST_INLINE_BORROW 460 +#define _LOAD_CONST_UNDER_INLINE 461 +#define _LOAD_CONST_UNDER_INLINE_BORROW 462 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 462 -#define _LOAD_FAST_0 463 -#define _LOAD_FAST_1 464 -#define _LOAD_FAST_2 465 -#define _LOAD_FAST_3 466 -#define _LOAD_FAST_4 467 -#define _LOAD_FAST_5 468 -#define _LOAD_FAST_6 469 -#define _LOAD_FAST_7 470 +#define _LOAD_FAST 463 +#define _LOAD_FAST_0 464 +#define _LOAD_FAST_1 465 +#define _LOAD_FAST_2 466 +#define _LOAD_FAST_3 467 +#define _LOAD_FAST_4 468 +#define _LOAD_FAST_5 469 +#define _LOAD_FAST_6 470 +#define _LOAD_FAST_7 471 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 471 -#define _LOAD_FAST_BORROW_0 472 -#define _LOAD_FAST_BORROW_1 473 -#define _LOAD_FAST_BORROW_2 474 -#define _LOAD_FAST_BORROW_3 475 -#define _LOAD_FAST_BORROW_4 476 -#define _LOAD_FAST_BORROW_5 477 -#define _LOAD_FAST_BORROW_6 478 -#define _LOAD_FAST_BORROW_7 479 +#define _LOAD_FAST_BORROW 472 +#define _LOAD_FAST_BORROW_0 473 +#define _LOAD_FAST_BORROW_1 474 +#define _LOAD_FAST_BORROW_2 475 +#define _LOAD_FAST_BORROW_3 476 +#define _LOAD_FAST_BORROW_4 477 +#define _LOAD_FAST_BORROW_5 478 +#define _LOAD_FAST_BORROW_6 479 +#define _LOAD_FAST_BORROW_7 480 #define _LOAD_FAST_BORROW_LOAD_FAST_BORROW LOAD_FAST_BORROW_LOAD_FAST_BORROW #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 480 -#define _LOAD_GLOBAL_BUILTINS 481 -#define _LOAD_GLOBAL_MODULE 482 +#define _LOAD_GLOBAL 481 +#define _LOAD_GLOBAL_BUILTINS 482 +#define _LOAD_GLOBAL_MODULE 483 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 483 -#define _LOAD_SMALL_INT_0 484 -#define _LOAD_SMALL_INT_1 485 -#define _LOAD_SMALL_INT_2 486 -#define _LOAD_SMALL_INT_3 487 -#define _LOAD_SPECIAL 488 +#define _LOAD_SMALL_INT 484 +#define _LOAD_SMALL_INT_0 485 +#define _LOAD_SMALL_INT_1 486 +#define _LOAD_SMALL_INT_2 487 +#define _LOAD_SMALL_INT_3 488 +#define _LOAD_SPECIAL 489 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 489 +#define _MAKE_CALLARGS_A_TUPLE 490 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 490 +#define _MAKE_WARM 491 #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 491 -#define _MAYBE_EXPAND_METHOD_KW 492 -#define _MONITOR_CALL 493 -#define _MONITOR_CALL_KW 494 -#define _MONITOR_JUMP_BACKWARD 495 -#define _MONITOR_RESUME 496 +#define _MAYBE_EXPAND_METHOD 492 +#define _MAYBE_EXPAND_METHOD_KW 493 +#define _MONITOR_CALL 494 +#define _MONITOR_CALL_KW 495 +#define _MONITOR_JUMP_BACKWARD 496 +#define _MONITOR_RESUME 497 #define _NOP NOP -#define _POP_CALL 497 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 498 -#define _POP_CALL_ONE 499 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 500 -#define _POP_CALL_TWO 501 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 502 +#define _POP_CALL 498 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 499 +#define _POP_CALL_ONE 500 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 501 +#define _POP_CALL_TWO 502 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 503 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 503 -#define _POP_JUMP_IF_TRUE 504 +#define _POP_JUMP_IF_FALSE 504 +#define _POP_JUMP_IF_TRUE 505 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 505 -#define _POP_TOP_INT 506 -#define _POP_TOP_LOAD_CONST_INLINE 507 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 508 -#define _POP_TOP_NOP 509 -#define _POP_TOP_UNICODE 510 -#define _POP_TWO 511 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 512 +#define _POP_TOP_FLOAT 506 +#define _POP_TOP_INT 507 +#define _POP_TOP_LOAD_CONST_INLINE 508 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 509 +#define _POP_TOP_NOP 510 +#define _POP_TOP_UNICODE 511 +#define _POP_TWO 512 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 513 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 513 +#define _PUSH_FRAME 514 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 514 -#define _PY_FRAME_GENERAL 515 -#define _PY_FRAME_KW 516 -#define _QUICKEN_RESUME 517 -#define _REPLACE_WITH_TRUE 518 +#define _PUSH_NULL_CONDITIONAL 515 +#define _PY_FRAME_GENERAL 516 +#define _PY_FRAME_KW 517 +#define _QUICKEN_RESUME 518 +#define _REPLACE_WITH_TRUE 519 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 519 -#define _SEND 520 -#define _SEND_GEN_FRAME 521 +#define _SAVE_RETURN_OFFSET 520 +#define _SEND 521 +#define _SEND_GEN_FRAME 522 #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 522 -#define _STORE_ATTR 523 -#define _STORE_ATTR_INSTANCE_VALUE 524 -#define _STORE_ATTR_SLOT 525 -#define _STORE_ATTR_WITH_HINT 526 +#define _START_EXECUTOR 523 +#define _STORE_ATTR 524 +#define _STORE_ATTR_INSTANCE_VALUE 525 +#define _STORE_ATTR_SLOT 526 +#define _STORE_ATTR_WITH_HINT 527 #define _STORE_DEREF STORE_DEREF -#define _STORE_FAST 527 -#define _STORE_FAST_0 528 -#define _STORE_FAST_1 529 -#define _STORE_FAST_2 530 -#define _STORE_FAST_3 531 -#define _STORE_FAST_4 532 -#define _STORE_FAST_5 533 -#define _STORE_FAST_6 534 -#define _STORE_FAST_7 535 +#define _STORE_FAST 528 +#define _STORE_FAST_0 529 +#define _STORE_FAST_1 530 +#define _STORE_FAST_2 531 +#define _STORE_FAST_3 532 +#define _STORE_FAST_4 533 +#define _STORE_FAST_5 534 +#define _STORE_FAST_6 535 +#define _STORE_FAST_7 536 #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 536 -#define _STORE_SUBSCR 537 -#define _STORE_SUBSCR_DICT 538 -#define _STORE_SUBSCR_LIST_INT 539 -#define _SWAP 540 -#define _SWAP_2 541 -#define _SWAP_3 542 -#define _TIER2_RESUME_CHECK 543 -#define _TO_BOOL 544 +#define _STORE_SLICE 537 +#define _STORE_SUBSCR 538 +#define _STORE_SUBSCR_DICT 539 +#define _STORE_SUBSCR_LIST_INT 540 +#define _SWAP 541 +#define _SWAP_2 542 +#define _SWAP_3 543 +#define _TIER2_RESUME_CHECK 544 +#define _TO_BOOL 545 #define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_INT TO_BOOL_INT -#define _TO_BOOL_LIST 545 +#define _TO_BOOL_LIST 546 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 546 +#define _TO_BOOL_STR 547 #define _UNARY_INVERT UNARY_INVERT #define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 547 -#define _UNPACK_SEQUENCE_LIST 548 -#define _UNPACK_SEQUENCE_TUPLE 549 -#define _UNPACK_SEQUENCE_TWO_TUPLE 550 +#define _UNPACK_SEQUENCE 548 +#define _UNPACK_SEQUENCE_LIST 549 +#define _UNPACK_SEQUENCE_TUPLE 550 +#define _UNPACK_SEQUENCE_TWO_TUPLE 551 #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 550 +#define MAX_UOP_ID 551 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index bf361233560c55..aa39bfbe7657d1 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -114,7 +114,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_BINARY_OP_SUBSCR_STR_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_GUARD_NOS_TUPLE] = HAS_EXIT_FLAG, [_GUARD_TOS_TUPLE] = HAS_EXIT_FLAG, - [_BINARY_OP_SUBSCR_TUPLE_INT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, + [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = HAS_DEOPT_FLAG, + [_BINARY_OP_SUBSCR_TUPLE_INT] = HAS_ESCAPES_FLAG, [_GUARD_NOS_DICT] = HAS_EXIT_FLAG, [_GUARD_TOS_DICT] = HAS_EXIT_FLAG, [_BINARY_OP_SUBSCR_DICT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -464,6 +465,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_GET_LEN] = "_GET_LEN", [_GET_YIELD_FROM_ITER] = "_GET_YIELD_FROM_ITER", [_GUARD_BINARY_OP_EXTEND] = "_GUARD_BINARY_OP_EXTEND", + [_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS] = "_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS", [_GUARD_CALLABLE_ISINSTANCE] = "_GUARD_CALLABLE_ISINSTANCE", [_GUARD_CALLABLE_LEN] = "_GUARD_CALLABLE_LEN", [_GUARD_CALLABLE_LIST_APPEND] = "_GUARD_CALLABLE_LIST_APPEND", @@ -861,6 +863,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _GUARD_TOS_TUPLE: return 0; + case _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS: + return 0; case _BINARY_OP_SUBSCR_TUPLE_INT: return 2; case _GUARD_NOS_DICT: diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index c796b0dd4b5b7e..a48f16d026e149 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1807,6 +1807,21 @@ def f(n): self.assertNotIn("_GUARD_NOS_TUPLE", uops) self.assertIn("_BINARY_OP_SUBSCR_TUPLE_INT", uops) + def test_remove_guard_for_tuple_bounds_check(self): + def f(n): + x = 0 + for _ in range(n): + t = (1, 2, 3) + x += t[0] + return x + + res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertNotIn("_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS", uops) + self.assertIn("_BINARY_OP_SUBSCR_TUPLE_INT", uops) + def test_binary_subcsr_str_int_narrows_to_str(self): def testfunc(n): x = [] diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-08-10-12-46-36.gh-issue-131798.5ys0H_.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-10-12-46-36.gh-issue-131798.5ys0H_.rst new file mode 100644 index 00000000000000..5a04d143a29724 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-10-12-46-36.gh-issue-131798.5ys0H_.rst @@ -0,0 +1 @@ +Remove bounds check when indexing into tuples with a constant index. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4d6dbe5116626d..0e100b24f88890 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -996,10 +996,8 @@ dummy_func( EXIT_IF(!PyTuple_CheckExact(o)); } - macro(BINARY_OP_SUBSCR_TUPLE_INT) = - _GUARD_TOS_INT + _GUARD_NOS_TUPLE + unused/5 + _BINARY_OP_SUBSCR_TUPLE_INT; - - op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) { + // A guard that checks that the tuple subscript is within bounds + op(_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS, (tuple_st, sub_st -- tuple_st, sub_st)) { PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); PyObject *tuple = PyStackRef_AsPyObjectBorrow(tuple_st); @@ -1010,7 +1008,17 @@ dummy_func( DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; DEOPT_IF(index >= PyTuple_GET_SIZE(tuple)); + } + + op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) { + PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); + PyObject *tuple = PyStackRef_AsPyObjectBorrow(tuple_st); + + assert(PyLong_CheckExact(sub)); + assert(PyTuple_CheckExact(tuple)); + STAT_INC(BINARY_OP, hit); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; PyObject *res_o = PyTuple_GET_ITEM(tuple, index); assert(res_o != NULL); PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc); @@ -1018,6 +1026,13 @@ dummy_func( DECREF_INPUTS(); } + macro(BINARY_OP_SUBSCR_TUPLE_INT) = + _GUARD_TOS_INT + + _GUARD_NOS_TUPLE + + _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS + + unused/5 + + _BINARY_OP_SUBSCR_TUPLE_INT; + op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) { PyObject *o = PyStackRef_AsPyObjectBorrow(nos); EXIT_IF(!PyDict_CheckExact(o)); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 182289922c7637..894668a5e74d0d 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1544,10 +1544,9 @@ break; } - case _BINARY_OP_SUBSCR_TUPLE_INT: { + case _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS: { _PyStackRef sub_st; _PyStackRef tuple_st; - _PyStackRef res; sub_st = stack_pointer[-1]; tuple_st = stack_pointer[-2]; PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); @@ -1563,7 +1562,21 @@ UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } + break; + } + + case _BINARY_OP_SUBSCR_TUPLE_INT: { + _PyStackRef sub_st; + _PyStackRef tuple_st; + _PyStackRef res; + sub_st = stack_pointer[-1]; + tuple_st = stack_pointer[-2]; + PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); + PyObject *tuple = PyStackRef_AsPyObjectBorrow(tuple_st); + assert(PyLong_CheckExact(sub)); + assert(PyTuple_CheckExact(tuple)); STAT_INC(BINARY_OP, hit); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; PyObject *res_o = PyTuple_GET_ITEM(tuple, index); assert(res_o != NULL); PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index d683582761295a..48aef53ab153ab 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -950,8 +950,7 @@ JUMP_TO_PREDICTED(BINARY_OP); } } - /* Skip 5 cache entries */ - // _BINARY_OP_SUBSCR_TUPLE_INT + // _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS { sub_st = value; tuple_st = nos; @@ -970,7 +969,16 @@ assert(_PyOpcode_Deopt[opcode] == (BINARY_OP)); JUMP_TO_PREDICTED(BINARY_OP); } + } + /* Skip 5 cache entries */ + // _BINARY_OP_SUBSCR_TUPLE_INT + { + PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st); + PyObject *tuple = PyStackRef_AsPyObjectBorrow(tuple_st); + assert(PyLong_CheckExact(sub)); + assert(PyTuple_CheckExact(tuple)); STAT_INC(BINARY_OP, hit); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; PyObject *res_o = PyTuple_GET_ITEM(tuple, index); assert(res_o != NULL); PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 77759f67532f80..bee2fb4e2ca0bc 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -310,6 +310,19 @@ dummy_func(void) { res = sym_new_type(ctx, &PyUnicode_Type); } + op(_GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS, (tuple_st, sub_st -- tuple_st, sub_st)) { + assert(sym_matches_type(tuple_st, &PyTuple_Type)); + if (sym_is_const(ctx, sub_st)) { + assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); + long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); + assert(index >= 0); + int tuple_length = sym_tuple_length(tuple_st); + if (tuple_length != -1 && index < tuple_length) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + } + } + op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) { assert(sym_matches_type(tuple_st, &PyTuple_Type)); if (sym_is_const(ctx, sub_st)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 2477ede3e68017..440c32baa04cef 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -927,6 +927,24 @@ break; } + case _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS: { + JitOptRef sub_st; + JitOptRef tuple_st; + sub_st = stack_pointer[-1]; + tuple_st = stack_pointer[-2]; + assert(sym_matches_type(tuple_st, &PyTuple_Type)); + if (sym_is_const(ctx, sub_st)) { + assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); + long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); + assert(index >= 0); + int tuple_length = sym_tuple_length(tuple_st); + if (tuple_length != -1 && index < tuple_length) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + } + break; + } + case _BINARY_OP_SUBSCR_TUPLE_INT: { JitOptRef sub_st; JitOptRef tuple_st;