Skip to content

gh-131798: Optimize _ITER_CHECK_RANGE and _ITER_CHECK_LIST#144583

Open
Sacul0457 wants to merge 3 commits intopython:mainfrom
Sacul0457:Optimize_ITER_CHECKs
Open

gh-131798: Optimize _ITER_CHECK_RANGE and _ITER_CHECK_LIST#144583
Sacul0457 wants to merge 3 commits intopython:mainfrom
Sacul0457:Optimize_ITER_CHECKs

Conversation

@Sacul0457
Copy link
Contributor

@Sacul0457 Sacul0457 commented Feb 8, 2026

Adds _ITER_CHECK_RANGE and _ITER_CHECK_LIST to the optimizer.

Regarding testing, as far as I know, we can't accurately test for this optimization, similar to #134803.
But if I am mistaken, please let me know :)

@bedevere-app
Copy link

bedevere-app bot commented Feb 8, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@Sacul0457
Copy link
Contributor Author

Sacul0457 commented Feb 18, 2026

Regarding testing, as far as I know, we can't accurately test for this optimization, similar to #134803.
But if I am mistaken, please let me know :)Regarding testing, as far as I know, we can't accurately test for this optimization, similar to #134803.

Oops, we in fact can test for _ITER_CHECK_LIST as _BUILD_LIST sets the symbolic type to a PyList_Type.

But for _ITER_CHECK_RANGE, we need to iterate the range twice but the trace produced seems to show 2/3 iterations

Testcase:

def testfunc(n):
    x = 0
    for _ in range(n):
        r = range(1, 2)
        for num in r: # guarded
            x += num
        for num in r: # unguarded
            x += num
    return x
Trace Produced:

   1 ADD_TO_TRACE: _START_EXECUTOR (0, target=42, operand0=0x259268c8764, operand1=0)
   2 ADD_TO_TRACE: _MAKE_WARM (0, target=0, operand0=0, operand1=0)
00000259268C8640 42: JUMP_BACKWARD(13) 0
   3 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=42, operand0=0, operand1=0)
   4 ADD_TO_TRACE: _SET_IP (0, target=42, operand0=0x259268c8764, operand1=0)
   5 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=42, operand0=0, operand1=0)
Trace continuing
Unsupported: dynamic jump taken FOR_ITER_RANGE
Trace done
   5 ADD_TO_TRACE: _EXIT_TRACE (0, target=31, operand0=0, operand1=0)
Tracing TestUopsOptimization.test_iter_check_range.<locals>.testfunc (...) at byte offset 28 at chain depth 0
   1 ADD_TO_TRACE: _START_EXECUTOR (0, target=46, operand0=0x259268c876c, operand1=0)
   2 ADD_TO_TRACE: _MAKE_WARM (0, target=0, operand0=0, operand1=0)
00000259268C8640 46: JUMP_BACKWARD(34) 0
   3 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=46, operand0=0, operand1=0)
   4 ADD_TO_TRACE: _SET_IP (0, target=46, operand0=0x259268c876c, operand1=0)
   5 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=46, operand0=0, operand1=0x1)
Trace continuing
00000259268C8640 14: FOR_ITER_RANGE(32) 0
   6 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=14, operand0=0, operand1=0)
   7 ADD_TO_TRACE: _SET_IP (0, target=14, operand0=0x259268c872c, operand1=0)
   8 ADD_TO_TRACE: _ITER_CHECK_RANGE (32, target=14, operand0=0, operand1=0)
   9 ADD_TO_TRACE: _GUARD_NOT_EXHAUSTED_RANGE (32, target=49, operand0=0, operand1=0)
  10 ADD_TO_TRACE: _ITER_NEXT_RANGE (32, target=14, operand0=0, operand1=0)
Trace continuing
00000259268C8640 16: STORE_FAST(2) 0
  11 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=16, operand0=0, operand1=0)
  12 ADD_TO_TRACE: _SET_IP (0, target=16, operand0=0x259268c8730, operand1=0)
  13 ADD_TO_TRACE: _SWAP_FAST (2, target=16, operand0=0, operand1=0)
  14 ADD_TO_TRACE: _POP_TOP (2, target=16, operand0=0, operand1=0)
Trace continuing
00000259268C8640 17: LOAD_GLOBAL_BUILTIN(1) 0
  15 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=17, operand0=0, operand1=0)
  16 ADD_TO_TRACE: _SET_IP (0, target=17, operand0=0x259268c8732, operand1=0)
  17 ADD_TO_TRACE: _GUARD_GLOBALS_VERSION (1, target=17, operand0=0xa9, operand1=0)
  18 ADD_TO_TRACE: _LOAD_GLOBAL_BUILTINS (1, target=17, operand0=0x2e, operand1=0)
  19 ADD_TO_TRACE: _PUSH_NULL_CONDITIONAL (1, target=17, operand0=0, operand1=0)
Trace continuing
00000259268C8640 22: LOAD_SMALL_INT(1) 0
  20 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=22, operand0=0, operand1=0)
  21 ADD_TO_TRACE: _SET_IP (0, target=22, operand0=0x259268c873c, operand1=0)
  22 ADD_TO_TRACE: _LOAD_SMALL_INT (1, target=22, operand0=0, operand1=0)
Trace continuing
00000259268C8640 23: LOAD_SMALL_INT(2) 0
  23 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=23, operand0=0, operand1=0)
  24 ADD_TO_TRACE: _SET_IP (0, target=23, operand0=0x259268c873e, operand1=0)
  25 ADD_TO_TRACE: _LOAD_SMALL_INT (2, target=23, operand0=0, operand1=0)
Trace continuing
00000259268C8640 24: CALL_BUILTIN_CLASS(2) 0
  26 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=24, operand0=0, operand1=0)
  27 ADD_TO_TRACE: _SET_IP (0, target=24, operand0=0x259268c8740, operand1=0)
  28 ADD_TO_TRACE: _RECORD_CALLABLE (2, target=24, operand0=0x7fff265dd6b0, operand1=0)
  29 ADD_TO_TRACE: _CALL_BUILTIN_CLASS (2, target=24, operand0=0, operand1=0)
  30 ADD_TO_TRACE: _TIER2_RESUME_CHECK (2, target=28, operand0=0, operand1=0)
Trace continuing
00000259268C8640 28: STORE_FAST(3) 0
  31 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=28, operand0=0, operand1=0)
  32 ADD_TO_TRACE: _SET_IP (0, target=28, operand0=0x259268c8748, operand1=0)
  33 ADD_TO_TRACE: _SWAP_FAST (3, target=28, operand0=0, operand1=0)
  34 ADD_TO_TRACE: _POP_TOP (3, target=28, operand0=0, operand1=0)
Trace continuing
00000259268C8640 29: LOAD_FAST(3) 0
  35 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=29, operand0=0, operand1=0)
  36 ADD_TO_TRACE: _SET_IP (0, target=29, operand0=0x259268c874a, operand1=0)
  37 ADD_TO_TRACE: _LOAD_FAST (3, target=29, operand0=0, operand1=0)
Trace continuing
00000259268C8640 30: GET_ITER(0) 0
  38 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=30, operand0=0, operand1=0)
  39 ADD_TO_TRACE: _SET_IP (0, target=30, operand0=0x259268c874c, operand1=0)
  40 ADD_TO_TRACE: _GET_ITER (0, target=30, operand0=0, operand1=0)
Trace continuing
00000259268C8640 31: FOR_ITER_RANGE(11) 0
  41 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=31, operand0=0, operand1=0)
  42 ADD_TO_TRACE: _SET_IP (0, target=31, operand0=0x259268c874e, operand1=0)
  43 ADD_TO_TRACE: _ITER_CHECK_RANGE (11, target=31, operand0=0, operand1=0)
  44 ADD_TO_TRACE: _GUARD_NOT_EXHAUSTED_RANGE (11, target=45, operand0=0, operand1=0)
  45 ADD_TO_TRACE: _ITER_NEXT_RANGE (11, target=31, operand0=0, operand1=0)
Trace continuing
00000259268C8640 33: STORE_FAST(4) 0
  46 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=33, operand0=0, operand1=0)
  47 ADD_TO_TRACE: _SET_IP (0, target=33, operand0=0x259268c8752, operand1=0)
  48 ADD_TO_TRACE: _SWAP_FAST (4, target=33, operand0=0, operand1=0)
  49 ADD_TO_TRACE: _POP_TOP (4, target=33, operand0=0, operand1=0)
Trace continuing
00000259268C8640 34: LOAD_FAST_BORROW_LOAD_FAST_BORROW(20) 0
  50 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0)
  51 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x259268c8754, operand1=0)
  52 ADD_TO_TRACE: _LOAD_FAST_BORROW (1, target=34, operand0=0, operand1=0)
  53 ADD_TO_TRACE: _LOAD_FAST_BORROW (4, target=34, operand0=0, operand1=0)
Trace continuing
00000259268C8640 35: BINARY_OP_ADD_INT(13) 0
  54 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=35, operand0=0, operand1=0)
  55 ADD_TO_TRACE: _SET_IP (0, target=35, operand0=0x259268c8756, operand1=0)
  56 ADD_TO_TRACE: _GUARD_TOS_INT (13, target=35, operand0=0, operand1=0)
  57 ADD_TO_TRACE: _GUARD_NOS_INT (13, target=35, operand0=0, operand1=0)
  58 ADD_TO_TRACE: _BINARY_OP_ADD_INT (13, target=35, operand0=0, operand1=0)
  59 ADD_TO_TRACE: _POP_TOP_INT (13, target=35, operand0=0, operand1=0)
  60 ADD_TO_TRACE: _POP_TOP_INT (13, target=35, operand0=0, operand1=0)
Trace continuing
00000259268C8640 41: STORE_FAST(1) 0
  61 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=41, operand0=0, operand1=0)
  62 ADD_TO_TRACE: _SET_IP (0, target=41, operand0=0x259268c8762, operand1=0)
  63 ADD_TO_TRACE: _SWAP_FAST (1, target=41, operand0=0, operand1=0)
  64 ADD_TO_TRACE: _POP_TOP (1, target=41, operand0=0, operand1=0)
Trace continuing
00000259268C8640 42: JUMP_BACKWARD(13) 0
  65 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=42, operand0=0, operand1=0)
  66 ADD_TO_TRACE: _SET_IP (0, target=42, operand0=0x259268c8764, operand1=0)
  67 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=42, operand0=0, operand1=0)
  68 ADD_TO_TRACE: _EXIT_TRACE (0, target=42, operand0=0, operand1=0)
JUMP_BACKWARD not to top ends trace 00000259268C874E 00000259268C872C 00000259268C876C
Trace done
  69 ADD_TO_TRACE: _EXIT_TRACE (0, target=42, operand0=0, operand1=0)
Optimized trace (length 72):
   0 OPTIMIZED: _START_EXECUTOR_r00 (0, jump_target=52, operand0=0x259265a7570, operand1=0)
   1 OPTIMIZED: _MAKE_WARM_r00 (0, target=0, operand0=0, operand1=0)
   2 OPTIMIZED: _SET_IP_r00 (0, target=46, operand0=0x259268c876c, operand1=0)
   3 OPTIMIZED: _CHECK_PERIODIC_r00 (0, jump_target=0, operand0=0, operand1=0x1, error_target=53)
   4 OPTIMIZED: _CHECK_VALIDITY_r00 (0, jump_target=54, operand0=0, operand1=0)
   5 OPTIMIZED: _ITER_CHECK_RANGE_r02 (32, jump_target=55, operand0=0, operand1=0)
   6 OPTIMIZED: _GUARD_NOT_EXHAUSTED_RANGE_r22 (32, jump_target=56, operand0=0, operand1=0)
   7 OPTIMIZED: _ITER_NEXT_RANGE_r23 (32, jump_target=0, operand0=0, operand1=0, error_target=57)
   8 OPTIMIZED: _SET_IP_r33 (0, target=16, operand0=0x259268c8730, operand1=0)
   9 OPTIMIZED: _SWAP_FAST_2_r33 (2, target=16, operand0=0, operand1=0)
  10 OPTIMIZED: _SPILL_OR_RELOAD_r31 (0, target=0, operand0=0, operand1=0)
  11 OPTIMIZED: _POP_TOP_r10 (2, target=16, operand0=0, operand1=0)
  12 OPTIMIZED: _CHECK_VALIDITY_r00 (0, jump_target=58, operand0=0, operand1=0)
  13 OPTIMIZED: _GUARD_GLOBALS_VERSION_r00 (1, jump_target=58, operand0=0xa9, operand1=0)
  14 OPTIMIZED: _LOAD_CONST_INLINE_BORROW_r01 (1, target=17, operand0=0x7fff265dd6b0, operand1=0x46)
  15 OPTIMIZED: _PUSH_NULL_r12 (0, target=17, operand0=0, operand1=0)
  16 OPTIMIZED: _LOAD_CONST_INLINE_BORROW_r23 (0, target=22, operand0=0x7fff266ca3e0, operand1=0)
  17 OPTIMIZED: _SPILL_OR_RELOAD_r32 (0, target=0, operand0=0x7fff265dd6b0, operand1=0x46)
  18 OPTIMIZED: _LOAD_CONST_INLINE_BORROW_r23 (0, target=23, operand0=0x7fff266ca400, operand1=0)
  19 OPTIMIZED: _SET_IP_r33 (0, target=24, operand0=0x259268c8740, operand1=0)
  20 OPTIMIZED: _SPILL_OR_RELOAD_r30 (0, target=0, operand0=0x259268c873c, operand1=0)
  21 OPTIMIZED: _CALL_BUILTIN_CLASS_r01 (2, jump_target=59, operand0=0, operand1=0, error_target=60)
  22 OPTIMIZED: _TIER2_RESUME_CHECK_r11 (2, jump_target=61, operand0=0, operand1=0)
  23 OPTIMIZED: _CHECK_VALIDITY_r11 (0, jump_target=62, operand0=0, operand1=0)
  24 OPTIMIZED: _SET_IP_r11 (0, target=28, operand0=0x259268c8748, operand1=0)
  25 OPTIMIZED: _SWAP_FAST_3_r11 (3, target=28, operand0=0, operand1=0)
  26 OPTIMIZED: _POP_TOP_r10 (3, target=28, operand0=0, operand1=0)
  27 OPTIMIZED: _CHECK_VALIDITY_r00 (0, jump_target=63, operand0=0, operand1=0)
  28 OPTIMIZED: _LOAD_FAST_3_r01 (3, target=29, operand0=0, operand1=0)
  29 OPTIMIZED: _SET_IP_r11 (0, target=30, operand0=0x259268c874c, operand1=0)
  30 OPTIMIZED: _GET_ITER_r12 (0, jump_target=0, operand0=0, operand1=0, error_target=64)
  31 OPTIMIZED: _CHECK_VALIDITY_r22 (0, jump_target=65, operand0=0, operand1=0)
  32 OPTIMIZED: _ITER_CHECK_RANGE_r22 (11, jump_target=66, operand0=0, operand1=0)
  33 OPTIMIZED: _GUARD_NOT_EXHAUSTED_RANGE_r22 (11, jump_target=67, operand0=0, operand1=0)
  34 OPTIMIZED: _ITER_NEXT_RANGE_r23 (11, jump_target=0, operand0=0, operand1=0, error_target=68)
  35 OPTIMIZED: _SET_IP_r33 (0, target=33, operand0=0x259268c8752, operand1=0)
  36 OPTIMIZED: _SWAP_FAST_4_r33 (4, target=33, operand0=0, operand1=0)
  37 OPTIMIZED: _SPILL_OR_RELOAD_r31 (0, target=0, operand0=0, operand1=0)
  38 OPTIMIZED: _POP_TOP_r10 (4, target=33, operand0=0, operand1=0)
  39 OPTIMIZED: _CHECK_VALIDITY_r00 (0, jump_target=69, operand0=0, operand1=0)
  40 OPTIMIZED: _LOAD_FAST_BORROW_1_r01 (1, target=34, operand0=0, operand1=0)
  41 OPTIMIZED: _LOAD_FAST_BORROW_4_r12 (4, target=34, operand0=0, operand1=0)
  42 OPTIMIZED: _GUARD_TOS_OVERFLOWED_r22 (0, jump_target=70, operand0=0, operand1=0)
  43 OPTIMIZED: _GUARD_NOS_INT_r22 (13, jump_target=70, operand0=0, operand1=0)
  44 OPTIMIZED: _BINARY_OP_ADD_INT_r23 (13, jump_target=70, operand0=0, operand1=0)
  45 OPTIMIZED: _POP_TOP_NOP_r32 (0, target=35, operand0=0, operand1=0)
  46 OPTIMIZED: _POP_TOP_NOP_r21 (0, target=35, operand0=0, operand1=0)
  47 OPTIMIZED: _SWAP_FAST_1_r11 (1, target=41, operand0=0, operand1=0)
  48 OPTIMIZED: _POP_TOP_INT_r10 (0, target=41, operand0=0, operand1=0)
  49 OPTIMIZED: _SET_IP_r00 (0, target=42, operand0=0x259268c8764, operand1=0)
  50 OPTIMIZED: _CHECK_PERIODIC_r00 (0, jump_target=0, operand0=0, operand1=0, error_target=71)
  51 OPTIMIZED: _EXIT_TRACE_r00 (0, target=42, operand0=0x259265a75f0, operand1=0x1)
  52 OPTIMIZED: _DEOPT_r00 (0, target=46, operand0=0, operand1=0)
  53 OPTIMIZED: _ERROR_POP_N_r00 (0, target=0, operand0=0x2e, operand1=0)
  54 OPTIMIZED: _DEOPT_r00 (0, target=14, operand0=0, operand1=0)
  55 OPTIMIZED: _EXIT_TRACE_r00 (0, target=14, operand0=0x259265a7600, operand1=0)
  56 OPTIMIZED: _EXIT_TRACE_r20 (0, target=49, operand0=0x259265a7610, operand1=0x1)
  57 OPTIMIZED: _ERROR_POP_N_r00 (0, target=0, operand0=0xe, operand1=0)
  58 OPTIMIZED: _DEOPT_r00 (0, target=17, operand0=0, operand1=0)
  59 OPTIMIZED: _DEOPT_r00 (0, target=24, operand0=0, operand1=0)
  60 OPTIMIZED: _ERROR_POP_N_r00 (0, target=0, operand0=0x18, operand1=0)
  61 OPTIMIZED: _HANDLE_PENDING_AND_DEOPT_r10 (0, target=28, operand0=0, operand1=0)
  62 OPTIMIZED: _DEOPT_r10 (0, target=28, operand0=0, operand1=0)
  63 OPTIMIZED: _DEOPT_r00 (0, target=29, operand0=0, operand1=0)
  64 OPTIMIZED: _ERROR_POP_N_r00 (0, target=0, operand0=0x1e, operand1=0)
  65 OPTIMIZED: _DEOPT_r20 (0, target=31, operand0=0, operand1=0)
  66 OPTIMIZED: _EXIT_TRACE_r20 (0, target=31, operand0=0x259265a7620, operand1=0)
  67 OPTIMIZED: _EXIT_TRACE_r20 (0, target=45, operand0=0x259265a7630, operand1=0x1)
  68 OPTIMIZED: _ERROR_POP_N_r00 (0, target=0, operand0=0x1f, operand1=0)
  69 OPTIMIZED: _DEOPT_r00 (0, target=34, operand0=0, operand1=0)
  70 OPTIMIZED: _EXIT_TRACE_r20 (0, target=35, operand0=0x259265a7640, operand1=0)
  71 OPTIMIZED: _ERROR_POP_N_r00 (0, target=0, operand0=0x2a, operand1=0)
  
  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments