Skip to content

Commit 06efb60

Browse files
authored
GH-111848: Tidy up tier 2 handling of FOR_ITER specialization by using DEOPT_IF instead of jumps. (GH-111849)
1 parent 11e8348 commit 06efb60

File tree

8 files changed

+59
-136
lines changed

8 files changed

+59
-136
lines changed

Include/internal/pycore_opcode_metadata.h

+21-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_capi/test_misc.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2712,7 +2712,7 @@ def testfunc(n):
27122712
# for i, (opname, oparg) in enumerate(ex):
27132713
# print(f"{i:4d}: {opname:<20s} {oparg:3d}")
27142714
uops = {opname for opname, _, _ in ex}
2715-
self.assertIn("_IS_ITER_EXHAUSTED_RANGE", uops)
2715+
self.assertIn("_GUARD_NOT_EXHAUSTED_RANGE", uops)
27162716
# Verification that the jump goes past END_FOR
27172717
# is done by manual inspection of the output
27182718

@@ -2734,7 +2734,7 @@ def testfunc(a):
27342734
# for i, (opname, oparg) in enumerate(ex):
27352735
# print(f"{i:4d}: {opname:<20s} {oparg:3d}")
27362736
uops = {opname for opname, _, _ in ex}
2737-
self.assertIn("_IS_ITER_EXHAUSTED_LIST", uops)
2737+
self.assertIn("_GUARD_NOT_EXHAUSTED_LIST", uops)
27382738
# Verification that the jump goes past END_FOR
27392739
# is done by manual inspection of the output
27402740

@@ -2756,7 +2756,7 @@ def testfunc(a):
27562756
# for i, (opname, oparg) in enumerate(ex):
27572757
# print(f"{i:4d}: {opname:<20s} {oparg:3d}")
27582758
uops = {opname for opname, _, _ in ex}
2759-
self.assertIn("_IS_ITER_EXHAUSTED_TUPLE", uops)
2759+
self.assertIn("_GUARD_NOT_EXHAUSTED_TUPLE", uops)
27602760
# Verification that the jump goes past END_FOR
27612761
# is done by manual inspection of the output
27622762

Python/abstract_interp_cases.c.h

+3-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

+11-29
Original file line numberDiff line numberDiff line change
@@ -2580,7 +2580,7 @@ dummy_func(
25802580
DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type);
25812581
}
25822582

2583-
op(_ITER_JUMP_LIST, (iter -- iter)) {
2583+
replaced op(_ITER_JUMP_LIST, (iter -- iter)) {
25842584
_PyListIterObject *it = (_PyListIterObject *)iter;
25852585
assert(Py_TYPE(iter) == &PyListIter_Type);
25862586
STAT_INC(FOR_ITER, hit);
@@ -2599,21 +2599,12 @@ dummy_func(
25992599
}
26002600

26012601
// Only used by Tier 2
2602-
op(_IS_ITER_EXHAUSTED_LIST, (iter -- iter, exhausted)) {
2602+
op(_GUARD_NOT_EXHAUSTED_LIST, (iter -- iter)) {
26032603
_PyListIterObject *it = (_PyListIterObject *)iter;
26042604
assert(Py_TYPE(iter) == &PyListIter_Type);
26052605
PyListObject *seq = it->it_seq;
2606-
if (seq == NULL) {
2607-
exhausted = Py_True;
2608-
}
2609-
else if (it->it_index >= PyList_GET_SIZE(seq)) {
2610-
Py_DECREF(seq);
2611-
it->it_seq = NULL;
2612-
exhausted = Py_True;
2613-
}
2614-
else {
2615-
exhausted = Py_False;
2616-
}
2606+
DEOPT_IF(seq == NULL);
2607+
DEOPT_IF(it->it_index >= PyList_GET_SIZE(seq));
26172608
}
26182609

26192610
op(_ITER_NEXT_LIST, (iter -- iter, next)) {
@@ -2635,7 +2626,7 @@ dummy_func(
26352626
DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type);
26362627
}
26372628

2638-
op(_ITER_JUMP_TUPLE, (iter -- iter)) {
2629+
replaced op(_ITER_JUMP_TUPLE, (iter -- iter)) {
26392630
_PyTupleIterObject *it = (_PyTupleIterObject *)iter;
26402631
assert(Py_TYPE(iter) == &PyTupleIter_Type);
26412632
STAT_INC(FOR_ITER, hit);
@@ -2654,21 +2645,12 @@ dummy_func(
26542645
}
26552646

26562647
// Only used by Tier 2
2657-
op(_IS_ITER_EXHAUSTED_TUPLE, (iter -- iter, exhausted)) {
2648+
op(_GUARD_NOT_EXHAUSTED_TUPLE, (iter -- iter)) {
26582649
_PyTupleIterObject *it = (_PyTupleIterObject *)iter;
26592650
assert(Py_TYPE(iter) == &PyTupleIter_Type);
26602651
PyTupleObject *seq = it->it_seq;
2661-
if (seq == NULL) {
2662-
exhausted = Py_True;
2663-
}
2664-
else if (it->it_index >= PyTuple_GET_SIZE(seq)) {
2665-
Py_DECREF(seq);
2666-
it->it_seq = NULL;
2667-
exhausted = Py_True;
2668-
}
2669-
else {
2670-
exhausted = Py_False;
2671-
}
2652+
DEOPT_IF(seq == NULL);
2653+
DEOPT_IF(it->it_index >= PyTuple_GET_SIZE(seq));
26722654
}
26732655

26742656
op(_ITER_NEXT_TUPLE, (iter -- iter, next)) {
@@ -2691,7 +2673,7 @@ dummy_func(
26912673
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type);
26922674
}
26932675

2694-
op(_ITER_JUMP_RANGE, (iter -- iter)) {
2676+
replaced op(_ITER_JUMP_RANGE, (iter -- iter)) {
26952677
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
26962678
assert(Py_TYPE(r) == &PyRangeIter_Type);
26972679
STAT_INC(FOR_ITER, hit);
@@ -2705,10 +2687,10 @@ dummy_func(
27052687
}
27062688

27072689
// Only used by Tier 2
2708-
op(_IS_ITER_EXHAUSTED_RANGE, (iter -- iter, exhausted)) {
2690+
op(_GUARD_NOT_EXHAUSTED_RANGE, (iter -- iter)) {
27092691
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
27102692
assert(Py_TYPE(r) == &PyRangeIter_Type);
2711-
exhausted = r->len <= 0 ? Py_True : Py_False;
2693+
DEOPT_IF(r->len <= 0);
27122694
}
27132695

27142696
op(_ITER_NEXT_RANGE, (iter -- iter, next)) {

Python/executor_cases.c.h

+8-35
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)