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
This commit is contained in:
Guido van Rossum 2023-07-12 10:23:59 -07:00 committed by GitHub
parent 7f55f58b6c
commit dd1884dc5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 146 additions and 28 deletions

View file

@ -3092,29 +3092,47 @@
}
TARGET(FOR_ITER_RANGE) {
PyObject *iter = stack_pointer[-1];
PyObject *next;
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
STAT_INC(FOR_ITER, hit);
if (r->len <= 0) {
STACK_SHRINK(1);
Py_DECREF(r);
SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
// Jump over END_FOR instruction.
JUMPBY(oparg + 1);
DISPATCH();
PyObject *_tmp_1;
PyObject *_tmp_2 = stack_pointer[-1];
{
PyObject *iter = _tmp_2;
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
_tmp_2 = iter;
}
long value = r->start;
r->start = value + r->step;
r->len--;
next = PyLong_FromLong(value);
if (next == NULL) {
goto error;
{
PyObject *iter = _tmp_2;
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
assert(Py_TYPE(r) == &PyRangeIter_Type);
STAT_INC(FOR_ITER, hit);
if (r->len <= 0) {
STACK_SHRINK(1);
Py_DECREF(r);
SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER);
// Jump over END_FOR instruction.
JUMPBY(oparg + 1);
DISPATCH();
}
_tmp_2 = iter;
}
{
PyObject *iter = _tmp_2;
PyObject *next;
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
assert(Py_TYPE(r) == &PyRangeIter_Type);
assert(r->len > 0);
long value = r->start;
r->start = value + r->step;
r->len--;
next = PyLong_FromLong(value);
if (next == NULL) goto error;
_tmp_2 = iter;
_tmp_1 = next;
}
STACK_GROW(1);
stack_pointer[-1] = next;
next_instr += 1;
STACK_GROW(1);
stack_pointer[-1] = _tmp_1;
stack_pointer[-2] = _tmp_2;
DISPATCH();
}