mirror of
https://github.com/python/cpython.git
synced 2025-12-15 21:44:50 +00:00
Remove unnecessary LIST_TO_TUPLE conversions (GH-126558)
This commit is contained in:
parent
845d924efb
commit
004f9fd1f2
2 changed files with 58 additions and 0 deletions
|
|
@ -1193,5 +1193,56 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
|||
]
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue