https://github.com/python/cpython/commit/004f9fd1f22643100aa8163cc9f7bcde7df54973
commit: 004f9fd1f22643100aa8163cc9f7bcde7df54973
branch: main
author: Brandt Bucher <[email protected]>
committer: brandtbucher <[email protected]>
date: 2025-01-08T09:00:11-08:00
summary:
Remove unnecessary LIST_TO_TUPLE conversions (GH-126558)
files:
M Lib/test/test_peepholer.py
M Python/flowgraph.c
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index c7da151dce3b37..b5b2b350e77a3b 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -1193,5 +1193,56 @@ def get_insts(lno1, lno2, op1, op2):
]
self.cfg_optimization_test(insts, expected_insts,
consts=list(range(5)))
+ def test_list_to_tuple_get_iter(self):
+ # for _ in (*foo, *bar) -> for _ in [*foo, *bar]
+ INTRINSIC_LIST_TO_TUPLE = 6
+ insts = [
+ ("BUILD_LIST", 0, 1),
+ ("LOAD_FAST", 0, 2),
+ ("LIST_EXTEND", 1, 3),
+ ("LOAD_FAST", 1, 4),
+ ("LIST_EXTEND", 1, 5),
+ ("CALL_INTRINSIC_1", INTRINSIC_LIST_TO_TUPLE, 6),
+ ("GET_ITER", None, 7),
+ top := self.Label(),
+ ("FOR_ITER", end := self.Label(), 8),
+ ("STORE_FAST", 2, 9),
+ ("JUMP", top, 10),
+ end,
+ ("END_FOR", None, 11),
+ ("POP_TOP", None, 12),
+ ("LOAD_CONST", 0, 13),
+ ("RETURN_VALUE", None, 14),
+ ]
+ expected_insts = [
+ ("BUILD_LIST", 0, 1),
+ ("LOAD_FAST", 0, 2),
+ ("LIST_EXTEND", 1, 3),
+ ("LOAD_FAST", 1, 4),
+ ("LIST_EXTEND", 1, 5),
+ ("NOP", None, 6), # ("CALL_INTRINSIC_1", INTRINSIC_LIST_TO_TUPLE,
6),
+ ("GET_ITER", None, 7),
+ top := self.Label(),
+ ("FOR_ITER", end := self.Label(), 8),
+ ("STORE_FAST", 2, 9),
+ ("JUMP", top, 10),
+ end,
+ ("END_FOR", None, 11),
+ ("POP_TOP", None, 12),
+ ("LOAD_CONST", 0, 13),
+ ("RETURN_VALUE", None, 14),
+ ]
+ self.cfg_optimization_test(insts, expected_insts, consts=[None])
+
+ def test_list_to_tuple_get_iter_is_safe(self):
+ a, b = [], []
+ for item in (*(items := [0, 1, 2, 3]),):
+ a.append(item)
+ b.append(items.pop())
+ self.assertEqual(a, [0, 1, 2, 3])
+ self.assertEqual(b, [3, 2, 1, 0])
+ self.assertEqual(items, [])
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 017216aadd1f01..24561c1ee04db9 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -4,6 +4,7 @@
#include "Python.h"
#include "pycore_flowgraph.h"
#include "pycore_compile.h"
+#include "pycore_intrinsics.h"
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_opcode_utils.h"
@@ -1874,6 +1875,12 @@ optimize_basic_block(PyObject *const_cache, basicblock
*bb, PyObject *consts)
continue;
}
break;
+ case CALL_INTRINSIC_1:
+ // for _ in (*foo, *bar) -> for _ in [*foo, *bar]
+ if (oparg == INTRINSIC_LIST_TO_TUPLE && nextop == GET_ITER) {
+ INSTR_SET_OP0(inst, NOP);
+ }
+ break;
}
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]