8000 Specialize GET_ITER for range · faster-cpython/cpython@a684067 · GitHub
[go: up one dir, main page]

Skip to content

Commit a684067

Browse files
committed
Specialize GET_ITER for range
1 parent aa5b0bd commit a684067

13 files changed

+244
-80
lines changed

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,8 @@ Known values:
279279
Python 3.14b1 3624 (Don't optimize LOAD_FAST when local is killed by DELETE_FAST)
280280
Python 3.15a0 3650 (Initial version)
281281
Python 3.15a1 3651 (Simplify LOAD_CONST)
282-
283-
Python 3.14a7 3652 (Virtual iterators)
284-
Python 3.14a7 3653 (Specialize GET_ITER)
282+
Python 3.15a1 3652 (Virtual iterators)
283+
Python 3.15a1 3653 (Specialize GET_ITER)
285284
286285
287286
Python 3.16 will start with 3700

Include/internal/pycore_opcode_metadata.h

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_ids.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/opcode_ids.h

Lines changed: 37 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/_opcode_metadata.py

Lines changed: 38 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_opcache.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1852,7 +1852,7 @@ def for_iter1():
18521852
self.assert_specialized(for_iter1, "FOR_ITER_RANGE")
18531853
self.assert_no_opcode(for_iter1, "FOR_ITER")
18541854

1855-
r = range(-10, 0)
1855+
r = range(-20, -10)
18561856
def for_iter2():
18571857
for i in r:
18581858
self.assertIn(i, r)
@@ -1878,6 +1878,55 @@ def for_iter4():
18781878
for_iter4()
18791879
self.assert_specialized(for_iter4, "FOR_ITER")
18801880

1881+
@cpython_only
1882+
@requires_specialization_ft
1883+
def test_get_iter(self):
1884+
1885+
L = list(range(2))
1886+
def for_iter_list():
1887+
n = 0
1888+
while n < _testinternalcapi.SPECIALIZATION_THRESHOLD:
1889+
n += 1
1890+
for i in L:
1891+
self.assertIn(i, L)
1892+
1893+
for_iter_list()
1894+
self.assert_specialized(for_iter_list, "GET_ITER_LIST_OR_TUPLE")
1895+
self.assert_no_opcode(for_iter_list, "GET_ITER")
1896+
1897+
t = tuple(range(2))
1898+
def for_iter_tuple():
1899+ n = 0
1900+
while n < _testinternalcapi.SPECIALIZATION_THRESHOLD:
1901+
n += 1
1902+
for i in t:
1903+
self.assertIn(i, t)
1904+
1905+
for_iter_tuple()
1906+
self.assert_specialized(for_iter_tuple, "GET_ITER_LIST_OR_TUPLE")
1907+
self.assert_no_opcode(for_iter_tuple, "GET_ITER")
1908+
1909+
def for_iter_generator():
1910+
n = 0
1911+
while n < _testinternalcapi.SPECIALIZATION_THRESHOLD:
1912+
n += 1
1913+
for i in (i for i in range(2)):
1914+
i + 1
1915+
1916+
for_iter_generator()
1917+
self.assert_specialized(for_iter_generator, "GET_ITER_SELF")
1918+
self.assert_no_opcode(for_iter_generator, "GET_ITER")
1919+
1920+
def for_iter_range():
1921+
n = 0
1922+
while n < _testinternalcapi.SPECIALIZATION_THRESHOLD:
1923+
n += 1
1924+
for i in range(2):
1925+
i + 1
1926+
1927+
for_iter_range()
1928+
self.assert_specialized(for_iter_range, "GET_ITER_RANGE")
1929+
self.assert_no_opcode(for_iter_range, "GET_ITER")
18811930

18821931
if __name__ == "__main__":
18831932
unittest.main()

Python/bytecodes.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,6 +3052,7 @@ dummy_func(
30523052
family(GET_ITER, 1) = {
30533053
GET_ITER_LIST_OR_TUPLE,
30543054
GET_ITER_SELF,
3055+
GET_ITER_RANGE,
30553056
};
30563057

30573058
specializing op(_SPECIALIZE_GET_ITER, (counter/1, iter -- iter)) {
@@ -3112,6 +3113,16 @@ dummy_func(
31123113
index0 = PyStackRef_TagInt(0);
31133114
}
31143115

3116+
inst(GET_ITER_RANGE, (unused/1, iter -- stop, index)) {
3117+
PyTypeObject *tp = PyStackRef_TYPE(iter);
3118+
DEOPT_IF(tp != &PyRange_Type);
3119+
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
3120+
DEOPT_IF(!_PyRange_IsSimpleCompact(iter_o));
3121+
index = PyStackRef_TagInt(_PyRange_GetStartIfCompact(iter_o));
3122+
stop = PyStackRef_TagInt(_PyRange_GetStopIfCompact(iter_o));
3123+
PyStackRef_CLOSE(iter);
3124+
}
3125+
31153126
inst(GET_YIELD_FROM_ITER, (iterable -- iter)) {
31163127
/* before: [obj]; after [getiter(obj)] */
31173128
PyObject *iterable_o = PyStackRef_AsPyObjectBorrow(iterable);

0 commit comments

Comments
 (0)
155D
0