diff options
author | Guido van Rossum <guido@python.org> | 2023-07-12 17:23:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-12 17:23:59 (GMT) |
commit | dd1884dc5dc1a540c60e98ea1bc482a51d996564 (patch) | |
tree | 7b32b0062a4d1f3734c0a9b6ba4473e51fe4aa59 /Python/optimizer.c | |
parent | 7f55f58b6c97306da350f5b441d26f859e9d8f16 (diff) | |
download | cpython-dd1884dc5dc1a540c60e98ea1bc482a51d996564.zip cpython-dd1884dc5dc1a540c60e98ea1bc482a51d996564.tar.gz cpython-dd1884dc5dc1a540c60e98ea1bc482a51d996564.tar.bz2 |
gh-106529: Split FOR_ITER_RANGE into uops (#106638)
For an example of what this does for Tier 1 and Tier 2, see
https://github.com/python/cpython/issues/106529#issuecomment-1631649920
Diffstat (limited to 'Python/optimizer.c')
-rw-r--r-- | Python/optimizer.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/Python/optimizer.c b/Python/optimizer.c index c3fdee6..abd2351 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -479,6 +479,28 @@ translate_bytecode_to_trace( break; } + case FOR_ITER_RANGE: + { + // Assume jump unlikely (can a for-loop exit be likely?) + // Reserve 9 entries (4 here, 3 stub, plus SAVE_IP + EXIT_TRACE) + if (trace_length + 9 > max_length) { + DPRINTF(1, "Ran out of space for FOR_ITER_RANGE\n"); + goto done; + } + _Py_CODEUNIT *target_instr = // +1 at the end skips over END_FOR + instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + oparg + 1; + max_length -= 3; // Really the start of the stubs + ADD_TO_TRACE(_ITER_CHECK_RANGE, 0); + ADD_TO_TRACE(_ITER_EXHAUSTED_RANGE, 0); + ADD_TO_TRACE(_POP_JUMP_IF_TRUE, max_length); + ADD_TO_TRACE(_ITER_NEXT_RANGE, 0); + + ADD_TO_STUB(max_length + 0, POP_TOP, 0); + ADD_TO_STUB(max_length + 1, SAVE_IP, INSTR_IP(target_instr, code)); + ADD_TO_STUB(max_length + 2, EXIT_TRACE, 0); + break; + } + default: { const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; @@ -574,8 +596,8 @@ done: } } } - trace_length += buffer_size - max_length; } + trace_length += buffer_size - max_length; return trace_length; } else { |