]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Sink LOAD_IP into guards
authorKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Mon, 27 Oct 2025 22:27:46 +0000 (22:27 +0000)
committerKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Mon, 27 Oct 2025 22:27:46 +0000 (22:27 +0000)
Include/internal/pycore_uop_ids.h
Include/internal/pycore_uop_metadata.h
Python/bytecodes.c
Python/executor_cases.c.h
Python/optimizer.c
Python/optimizer_cases.c.h
Tools/cases_generator/tier2_generator.py

index 9f4ae71a313aa07dd6104b16744f6953188dc16d..067da4209f01024ff26de6e634f5e26284948725 100644 (file)
@@ -137,47 +137,49 @@ extern "C" {
 #define _GUARD_DORV_NO_DICT 392
 #define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 393
 #define _GUARD_GLOBALS_VERSION 394
-#define _GUARD_IP 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 _GUARD_IP_PUSH_FRAME 395
+#define _GUARD_IP_RETURN_VALUE 396
+#define _GUARD_IP_YIELD_VALUE 397
+#define _GUARD_IS_FALSE_POP 398
+#define _GUARD_IS_NONE_POP 399
+#define _GUARD_IS_NOT_NONE_POP 400
+#define _GUARD_IS_TRUE_POP 401
+#define _GUARD_KEYS_VERSION 402
+#define _GUARD_NOS_DICT 403
+#define _GUARD_NOS_FLOAT 404
+#define _GUARD_NOS_INT 405
+#define _GUARD_NOS_LIST 406
+#define _GUARD_NOS_NOT_NULL 407
+#define _GUARD_NOS_NULL 408
+#define _GUARD_NOS_OVERFLOWED 409
+#define _GUARD_NOS_TUPLE 410
+#define _GUARD_NOS_UNICODE 411
+#define _GUARD_NOT_EXHAUSTED_LIST 412
+#define _GUARD_NOT_EXHAUSTED_RANGE 413
+#define _GUARD_NOT_EXHAUSTED_TUPLE 414
+#define _GUARD_THIRD_NULL 415
+#define _GUARD_TOS_ANY_SET 416
+#define _GUARD_TOS_DICT 417
+#define _GUARD_TOS_FLOAT 418
+#define _GUARD_TOS_INT 419
+#define _GUARD_TOS_LIST 420
+#define _GUARD_TOS_OVERFLOWED 421
+#define _GUARD_TOS_SLICE 422
+#define _GUARD_TOS_TUPLE 423
+#define _GUARD_TOS_UNICODE 424
+#define _GUARD_TYPE_VERSION 425
+#define _GUARD_TYPE_VERSION_AND_LOCK 426
+#define _HANDLE_PENDING_AND_DEOPT 427
 #define _IMPORT_FROM IMPORT_FROM
 #define _IMPORT_NAME IMPORT_NAME
-#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 _INIT_CALL_BOUND_METHOD_EXACT_ARGS 428
+#define _INIT_CALL_PY_EXACT_ARGS 429
+#define _INIT_CALL_PY_EXACT_ARGS_0 430
+#define _INIT_CALL_PY_EXACT_ARGS_1 431
+#define _INIT_CALL_PY_EXACT_ARGS_2 432
+#define _INIT_CALL_PY_EXACT_ARGS_3 433
+#define _INIT_CALL_PY_EXACT_ARGS_4 434
+#define _INSERT_NULL 435
 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
 #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
 #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -187,178 +189,178 @@ 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 434
+#define _IS_NONE 436
 #define _IS_OP IS_OP
-#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 _ITER_CHECK_LIST 437
+#define _ITER_CHECK_RANGE 438
+#define _ITER_CHECK_TUPLE 439
+#define _ITER_JUMP_LIST 440
+#define _ITER_JUMP_RANGE 441
+#define _ITER_JUMP_TUPLE 442
+#define _ITER_NEXT_LIST 443
+#define _ITER_NEXT_LIST_TIER_TWO 444
+#define _ITER_NEXT_RANGE 445
+#define _ITER_NEXT_TUPLE 446
 #define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT
-#define _JUMP_TO_TOP 445
+#define _JUMP_TO_TOP 447
 #define _LIST_APPEND LIST_APPEND
 #define _LIST_EXTEND LIST_EXTEND
-#define _LOAD_ATTR 446
-#define _LOAD_ATTR_CLASS 447
+#define _LOAD_ATTR 448
+#define _LOAD_ATTR_CLASS 449
 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#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_ATTR_INSTANCE_VALUE 450
+#define _LOAD_ATTR_METHOD_LAZY_DICT 451
+#define _LOAD_ATTR_METHOD_NO_DICT 452
+#define _LOAD_ATTR_METHOD_WITH_VALUES 453
+#define _LOAD_ATTR_MODULE 454
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 455
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 456
+#define _LOAD_ATTR_PROPERTY_FRAME 457
+#define _LOAD_ATTR_SLOT 458
+#define _LOAD_ATTR_WITH_HINT 459
 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 458
+#define _LOAD_BYTECODE 460
 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
 #define _LOAD_CONST LOAD_CONST
-#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_CONST_INLINE 461
+#define _LOAD_CONST_INLINE_BORROW 462
+#define _LOAD_CONST_UNDER_INLINE 463
+#define _LOAD_CONST_UNDER_INLINE_BORROW 464
 #define _LOAD_DEREF LOAD_DEREF
-#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 465
+#define _LOAD_FAST_0 466
+#define _LOAD_FAST_1 467
+#define _LOAD_FAST_2 468
+#define _LOAD_FAST_3 469
+#define _LOAD_FAST_4 470
+#define _LOAD_FAST_5 471
+#define _LOAD_FAST_6 472
+#define _LOAD_FAST_7 473
 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
-#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 474
+#define _LOAD_FAST_BORROW_0 475
+#define _LOAD_FAST_BORROW_1 476
+#define _LOAD_FAST_BORROW_2 477
+#define _LOAD_FAST_BORROW_3 478
+#define _LOAD_FAST_BORROW_4 479
+#define _LOAD_FAST_BORROW_5 480
+#define _LOAD_FAST_BORROW_6 481
+#define _LOAD_FAST_BORROW_7 482
 #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 481
-#define _LOAD_GLOBAL_BUILTINS 482
-#define _LOAD_GLOBAL_MODULE 483
+#define _LOAD_GLOBAL 483
+#define _LOAD_GLOBAL_BUILTINS 484
+#define _LOAD_GLOBAL_MODULE 485
 #define _LOAD_LOCALS LOAD_LOCALS
 #define _LOAD_NAME LOAD_NAME
-#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_SMALL_INT 486
+#define _LOAD_SMALL_INT_0 487
+#define _LOAD_SMALL_INT_1 488
+#define _LOAD_SMALL_INT_2 489
+#define _LOAD_SMALL_INT_3 490
+#define _LOAD_SPECIAL 491
 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
 #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 490
+#define _MAKE_CALLARGS_A_TUPLE 492
 #define _MAKE_CELL MAKE_CELL
 #define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 491
+#define _MAKE_WARM 493
 #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 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 _MAYBE_EXPAND_METHOD 494
+#define _MAYBE_EXPAND_METHOD_KW 495
+#define _MONITOR_CALL 496
+#define _MONITOR_CALL_KW 497
+#define _MONITOR_JUMP_BACKWARD 498
+#define _MONITOR_RESUME 499
 #define _NOP NOP
-#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_CALL 500
+#define _POP_CALL_LOAD_CONST_INLINE_BORROW 501
+#define _POP_CALL_ONE 502
+#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 503
+#define _POP_CALL_TWO 504
+#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 505
 #define _POP_EXCEPT POP_EXCEPT
 #define _POP_ITER POP_ITER
-#define _POP_JUMP_IF_FALSE 504
-#define _POP_JUMP_IF_TRUE 505
+#define _POP_JUMP_IF_FALSE 506
+#define _POP_JUMP_IF_TRUE 507
 #define _POP_TOP POP_TOP
-#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 _POP_TOP_FLOAT 508
+#define _POP_TOP_INT 509
+#define _POP_TOP_LOAD_CONST_INLINE 510
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 511
+#define _POP_TOP_NOP 512
+#define _POP_TOP_UNICODE 513
+#define _POP_TWO 514
+#define _POP_TWO_LOAD_CONST_INLINE_BORROW 515
 #define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 514
+#define _PUSH_FRAME 516
 #define _PUSH_NULL PUSH_NULL
-#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 _PUSH_NULL_CONDITIONAL 517
+#define _PY_FRAME_GENERAL 518
+#define _PY_FRAME_KW 519
+#define _QUICKEN_RESUME 520
+#define _REPLACE_WITH_TRUE 521
 #define _RESUME_CHECK RESUME_CHECK
 #define _RETURN_GENERATOR RETURN_GENERATOR
 #define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 520
-#define _SEND 521
-#define _SEND_GEN_FRAME 522
+#define _SAVE_RETURN_OFFSET 522
+#define _SEND 523
+#define _SEND_GEN_FRAME 524
 #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 523
-#define _STORE_ATTR 524
-#define _STORE_ATTR_INSTANCE_VALUE 525
-#define _STORE_ATTR_SLOT 526
-#define _STORE_ATTR_WITH_HINT 527
+#define _START_EXECUTOR 525
+#define _STORE_ATTR 526
+#define _STORE_ATTR_INSTANCE_VALUE 527
+#define _STORE_ATTR_SLOT 528
+#define _STORE_ATTR_WITH_HINT 529
 #define _STORE_DEREF STORE_DEREF
-#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 530
+#define _STORE_FAST_0 531
+#define _STORE_FAST_1 532
+#define _STORE_FAST_2 533
+#define _STORE_FAST_3 534
+#define _STORE_FAST_4 535
+#define _STORE_FAST_5 536
+#define _STORE_FAST_6 537
+#define _STORE_FAST_7 538
 #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 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 _STORE_SLICE 539
+#define _STORE_SUBSCR 540
+#define _STORE_SUBSCR_DICT 541
+#define _STORE_SUBSCR_LIST_INT 542
+#define _SWAP 543
+#define _SWAP_2 544
+#define _SWAP_3 545
+#define _TIER2_RESUME_CHECK 546
+#define _TO_BOOL 547
 #define _TO_BOOL_BOOL TO_BOOL_BOOL
 #define _TO_BOOL_INT TO_BOOL_INT
-#define _TO_BOOL_LIST 546
+#define _TO_BOOL_LIST 548
 #define _TO_BOOL_NONE TO_BOOL_NONE
-#define _TO_BOOL_STR 547
+#define _TO_BOOL_STR 549
 #define _UNARY_INVERT UNARY_INVERT
 #define _UNARY_NEGATIVE UNARY_NEGATIVE
 #define _UNARY_NOT UNARY_NOT
 #define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 548
-#define _UNPACK_SEQUENCE_LIST 549
-#define _UNPACK_SEQUENCE_TUPLE 550
-#define _UNPACK_SEQUENCE_TWO_TUPLE 551
+#define _UNPACK_SEQUENCE 550
+#define _UNPACK_SEQUENCE_LIST 551
+#define _UNPACK_SEQUENCE_TUPLE 552
+#define _UNPACK_SEQUENCE_TWO_TUPLE 553
 #define _WITH_EXCEPT_START WITH_EXCEPT_START
 #define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 551
+#define MAX_UOP_ID 553
 
 #ifdef __cplusplus
 }
index 82a0fa92652524ddbef1dafbe8e32b7529e0056a..67c5827ffd0c008ddf30d2fb0342686d928ebbed 100644 (file)
@@ -337,7 +337,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
     [_ERROR_POP_N] = HAS_ARG_FLAG,
     [_TIER2_RESUME_CHECK] = HAS_PERIODIC_FLAG,
     [_COLD_EXIT] = 0,
-    [_GUARD_IP] = HAS_EXIT_FLAG,
+    [_GUARD_IP_PUSH_FRAME] = HAS_EXIT_FLAG,
+    [_GUARD_IP_YIELD_VALUE] = HAS_EXIT_FLAG,
+    [_GUARD_IP_RETURN_VALUE] = HAS_EXIT_FLAG,
     [_DYNAMIC_EXIT] = HAS_ESCAPES_FLAG,
 };
 
@@ -474,7 +476,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
     [_GUARD_DORV_NO_DICT] = "_GUARD_DORV_NO_DICT",
     [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT",
     [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
-    [_GUARD_IP] = "_GUARD_IP",
+    [_GUARD_IP_PUSH_FRAME] = "_GUARD_IP_PUSH_FRAME",
+    [_GUARD_IP_RETURN_VALUE] = "_GUARD_IP_RETURN_VALUE",
+    [_GUARD_IP_YIELD_VALUE] = "_GUARD_IP_YIELD_VALUE",
     [_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",
@@ -1309,7 +1313,11 @@ int _PyUop_num_popped(int opcode, int oparg)
             return 0;
         case _COLD_EXIT:
             return 0;
-        case _GUARD_IP:
+        case _GUARD_IP_PUSH_FRAME:
+            return 0;
+        case _GUARD_IP_YIELD_VALUE:
+            return 0;
+        case _GUARD_IP_RETURN_VALUE:
             return 0;
         case _DYNAMIC_EXIT:
             return 0;
index 971660ace56ab0e1b164dd49bee5a25550418e57..b3977e5613b4dc88004c2a9a4dc61ab4545bf619 100644 (file)
@@ -5443,10 +5443,24 @@ dummy_func(
             TIER2_TO_TIER2(exit->executor);
         }
 
-        tier2 op(_GUARD_IP, (ip/4 --)) {
+        tier2 op(_GUARD_IP_PUSH_FRAME, (ip/4 --)) {
             EXIT_IF(frame->instr_ptr != (_Py_CODEUNIT *)ip);
         }
 
+        tier2 op(_GUARD_IP_YIELD_VALUE, (ip/4 --)) {
+            if (frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND != (_Py_CODEUNIT *)ip) {
+                frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
+                EXIT_IF(true);
+            }
+        }
+
+        tier2 op(_GUARD_IP_RETURN_VALUE, (ip/4 --)) {
+            if (frame->instr_ptr + frame->return_offset != (_Py_CODEUNIT *)ip) {
+                frame->instr_ptr += frame->return_offset;
+                EXIT_IF(true);
+            }
+        }
+
         // Note: this is different than _COLD_EXIT/_EXIT_TRACE, as it may lead to multiple executors
         // from a single exit!
         tier2 op(_DYNAMIC_EXIT, (exit_p/4 --)) {
index 5273670008c029c3cd9f9b1e9c1cdf17dfb13205..7f915e31b12108e6e0ed9b484c12c5c3293450de 100644 (file)
             frame = tstate->current_frame = dying->previous;
             _PyEval_FrameClearAndPop(tstate, dying);
             stack_pointer = _PyFrame_GetStackPointer(frame);
-            frame->instr_ptr += (frame->return_offset);
+            LOAD_IP(frame->return_offset);
             res = temp;
             LLTRACE_RESUME_FRAME();
             stack_pointer[0] = res;
                   _PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR);
             #endif
             stack_pointer = _PyFrame_GetStackPointer(frame);
-            frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND);
+            LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
             value = PyStackRef_MakeHeapSafe(temp);
             LLTRACE_RESUME_FRAME();
             stack_pointer[0] = value;
             frame = tstate->current_frame = temp;
             tstate->py_recursion_remaining--;
             LOAD_SP();
-            frame->instr_ptr += (0);
+            LOAD_IP(0);
             LLTRACE_RESUME_FRAME();
             break;
         }
             _PyInterpreterFrame *prev = frame->previous;
             _PyThreadState_PopFrame(tstate, frame);
             frame = tstate->current_frame = prev;
-            frame->instr_ptr += (frame->return_offset);
+            LOAD_IP(frame->return_offset);
             stack_pointer = _PyFrame_GetStackPointer(frame);
             res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen);
             LLTRACE_RESUME_FRAME();
             break;
         }
 
-        case _GUARD_IP: {
+        case _GUARD_IP_PUSH_FRAME: {
             PyObject *ip = (PyObject *)CURRENT_OPERAND0();
             if (frame->instr_ptr != (_Py_CODEUNIT *)ip) {
                 UOP_STAT_INC(uopcode, miss);
             break;
         }
 
+        case _GUARD_IP_YIELD_VALUE: {
+            PyObject *ip = (PyObject *)CURRENT_OPERAND0();
+            if (frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND != (_Py_CODEUNIT *)ip) {
+                frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
+                if (true) {
+                    UOP_STAT_INC(uopcode, miss);
+                    JUMP_TO_JUMP_TARGET();
+                }
+            }
+            break;
+        }
+
+        case _GUARD_IP_RETURN_VALUE: {
+            PyObject *ip = (PyObject *)CURRENT_OPERAND0();
+            if (frame->instr_ptr + frame->return_offset != (_Py_CODEUNIT *)ip) {
+                frame->instr_ptr += frame->return_offset;
+                if (true) {
+                    UOP_STAT_INC(uopcode, miss);
+                    JUMP_TO_JUMP_TARGET();
+                }
+            }
+            break;
+        }
+
         case _DYNAMIC_EXIT: {
             PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
             _Py_CODEUNIT *target = frame->instr_ptr;
index 12bb803d18d87e49f24bf0a1e77cc735314f050a..e6955edbc194c31a0bc75cbafe38fe1eae9e3482 100644 (file)
@@ -901,7 +901,21 @@ _PyJit_translate_single_bytecode_to_trace(
     }  // End switch (opcode)
 
     if (needs_guard_ip) {
-        ADD_TO_TRACE(_GUARD_IP, 0, (uintptr_t)next_instr, 0);
+        switch (trace[trace_length-1].opcode) {
+            case _PUSH_FRAME:
+                ADD_TO_TRACE(_GUARD_IP_PUSH_FRAME, 0, (uintptr_t)next_instr, 0);
+                break;
+            case _RETURN_GENERATOR:
+            case _RETURN_VALUE:
+                ADD_TO_TRACE(_GUARD_IP_RETURN_VALUE, 0, (uintptr_t)next_instr, 0);
+                break;
+            case _YIELD_VALUE:
+                ADD_TO_TRACE(_GUARD_IP_YIELD_VALUE, 0, (uintptr_t)next_instr, 0);
+                break;
+            default:
+                DPRINTF(1, "Unknown uop needing guard ip %s\n", _PyOpcode_uop_name[trace[trace_length-1].opcode]);
+                Py_UNREACHABLE();
+        }
     }
     // Loop back to the start
     int is_first_instr = tstate->interp->jit_state.close_loop_instr == next_instr || tstate->interp->jit_state.insert_exec_instr == next_instr;
@@ -1074,7 +1088,10 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length)
             if (opcode == _FOR_ITER_TIER_TWO) {
                 exit_op = _DYNAMIC_EXIT;
             }
-            else if (opcode == _GUARD_IP) {
+            else if (
+                opcode == _GUARD_IP_PUSH_FRAME ||
+                opcode == _GUARD_IP_RETURN_VALUE ||
+                opcode == _GUARD_IP_YIELD_VALUE) {
                 exit_op = _DYNAMIC_EXIT;
                 unique_target = true;
             }
index 5f7d600b3cd2a91d367fc14c48ce8c51378e2856..9fc77dd4b6ed0ca3575eaddf1529d2950051fea3 100644 (file)
             break;
         }
 
-        case _GUARD_IP: {
+        case _GUARD_IP_PUSH_FRAME: {
+            break;
+        }
+
+        case _GUARD_IP_YIELD_VALUE: {
+            break;
+        }
+
+        case _GUARD_IP_RETURN_VALUE: {
             break;
         }
 
index e95a070b163f4c988b393eb78297616c12187950..4bf04154df16236b880f4afeb97c879ae8933f5a 100644 (file)
@@ -65,7 +65,6 @@ class Tier2Emitter(Emitter):
         self._replacers["oparg"] = self.oparg
         self._replacers["JUMPBY"] = self.jumpby
         self._replacers["DISPATCH"] = self.dispatch
-        self._replacers["LOAD_IP"] = self.load_ip
 
     def goto_error(self, offset: int, storage: Storage) -> str:
         # To do: Add jump targets for popping values.
@@ -170,19 +169,6 @@ class Tier2Emitter(Emitter):
         next(tkn_iter)
         return False
 
-    def load_ip(
-        self,
-        tkn: Token,
-        tkn_iter: TokenIterator,
-        uop: CodeSection,
-        storage: Storage,
-        inst: Instruction | None,
-    ) -> bool:
-        self.out.start_line()
-        self.emit("frame->instr_ptr += ")
-        emit_to(self.out, tkn_iter, "SEMI")
-        self.emit(";\n")
-        return True
 
 def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> Stack:
     locals: dict[str, Local] = {}