gh-148817: Fold long lists/sets of constant elements into constant tu… · python/cpython@084230e

GitHub

@@ -2470,6 +2470,168 @@ def test_list_to_tuple_get_iter_is_safe(self):

24702470self.assertEqual(b, [3, 2, 1, 0])

24712471self.assertEqual(items, [])

247224722473+deftest_fold_constant_big_list_for_iter(self):

2474+# for x in [c1, c2, ..., cN] (N > 30) should fold to LOAD_CONST tuple

2475+consts=35

2476+before= (

2477+ [("BUILD_LIST", 0, 1)] +

2478+ [("LOAD_CONST", 0, 2), ("LIST_APPEND", 1, 3)] *consts+

2479+ [("GET_ITER", 0, 4),

2480+top:=self.Label(),

2481+ ("FOR_ITER", end:=self.Label(), 5),

2482+ ("STORE_FAST", 0, 6),

2483+ ("JUMP", top, 7),

2484+end,

2485+ ("END_FOR", None, 8),

2486+ ("POP_ITER", None, 9),

2487+ ("LOAD_CONST", 0, 10),

2488+ ("RETURN_VALUE", None, 11)]

2489+ )

2490+after= [

2491+ ("LOAD_CONST", 1, 3),

2492+ ("GET_ITER", 0, 4),

2493+top:=self.Label(),

2494+ ("FOR_ITER", end:=self.Label(), 5),

2495+ ("STORE_FAST", 0, 6),

2496+ ("JUMP", top, 7),

2497+end,

2498+ ("END_FOR", None, 8),

2499+ ("POP_ITER", None, 9),

2500+ ("LOAD_CONST", 0, 10),

2501+ ("RETURN_VALUE", None, 11),

2502+ ]

2503+result_const=tuple(["test"] *consts)

2504+self.cfg_optimization_test(before, after, consts=["test"],

2505+expected_consts=["test", result_const])

2506+2507+deftest_fold_constant_big_set_for_iter(self):

2508+# for x in {c1, c2, ..., cN} (N > 30) should fold to LOAD_CONST frozenset

2509+before= [

2510+ ("BUILD_SET", 0, 1),

2511+ ("LOAD_SMALL_INT", 1, 2), ("SET_ADD", 1, 3),

2512+ ("LOAD_SMALL_INT", 2, 4), ("SET_ADD", 1, 5),

2513+ ("LOAD_SMALL_INT", 3, 6), ("SET_ADD", 1, 7),

2514+ ("GET_ITER", 0, 8),

2515+top:=self.Label(),

2516+ ("FOR_ITER", end:=self.Label(), 9),

2517+ ("STORE_FAST", 0, 10),

2518+ ("JUMP", top, 11),

2519+end,

2520+ ("END_FOR", None, 12),

2521+ ("POP_ITER", None, 13),

2522+ ("LOAD_CONST", 0, 14),

2523+ ("RETURN_VALUE", None, 15),

2524+ ]

2525+after= [

2526+ ("LOAD_CONST", 1, 7),

2527+ ("GET_ITER", 0, 8),

2528+top:=self.Label(),

2529+ ("FOR_ITER", end:=self.Label(), 9),

2530+ ("STORE_FAST", 0, 10),

2531+ ("JUMP", top, 11),

2532+end,

2533+ ("END_FOR", None, 12),

2534+ ("POP_ITER", None, 13),

2535+ ("LOAD_CONST", 0, 14),

2536+ ("RETURN_VALUE", None, 15),

2537+ ]

2538+self.cfg_optimization_test(before, after, consts=["test"],

2539+expected_consts=["test", frozenset({1, 2, 3})])

2540+2541+deftest_fold_constant_list_to_tuple_for_iter(self):

2542+INTRINSIC_LIST_TO_TUPLE=6

2543+before= [

2544+ ("BUILD_LIST", 0, 1),

2545+ ("LOAD_SMALL_INT", 1, 2), ("LIST_APPEND", 1, 3),

2546+ ("LOAD_SMALL_INT", 2, 4), ("LIST_APPEND", 1, 5),

2547+ ("LOAD_SMALL_INT", 3, 6), ("LIST_APPEND", 1, 7),

2548+ ("CALL_INTRINSIC_1", INTRINSIC_LIST_TO_TUPLE, 8),

2549+ ("GET_ITER", 0, 9),

2550+top:=self.Label(),

2551+ ("FOR_ITER", end:=self.Label(), 10),

2552+ ("STORE_FAST", 0, 11),

2553+ ("JUMP", top, 12),

2554+end,

2555+ ("END_FOR", None, 13),

2556+ ("POP_ITER", None, 14),

2557+ ("LOAD_CONST", 0, 15),

2558+ ("RETURN_VALUE", None, 16),

2559+ ]

2560+after= [

2561+ ("LOAD_CONST", 1, 8),

2562+ ("GET_ITER", 0, 9),

2563+top:=self.Label(),

2564+ ("FOR_ITER", end:=self.Label(), 10),

2565+ ("STORE_FAST", 0, 11),

2566+ ("JUMP", top, 12),

2567+end,

2568+ ("END_FOR", None, 13),

2569+ ("POP_ITER", None, 14),

2570+ ("LOAD_CONST", 0, 15),

2571+ ("RETURN_VALUE", None, 16),

2572+ ]

2573+self.cfg_optimization_test(before, after, consts=["test"],

2574+expected_consts=["test", (1, 2, 3)])

2575+2576+deftest_fold_constant_big_list_contains_op(self):

2577+# x in [c1, c2, ..., cN] (N > 30) should fold to LOAD_CONST tuple

2578+before= [

2579+ ("LOAD_FAST", 0, 1),

2580+ ("BUILD_LIST", 0, 2),

2581+ ("LOAD_SMALL_INT", 1, 3), ("LIST_APPEND", 1, 4),

2582+ ("LOAD_SMALL_INT", 2, 5), ("LIST_APPEND", 1, 6),

2583+ ("LOAD_SMALL_INT", 3, 7), ("LIST_APPEND", 1, 8),

2584+ ("CONTAINS_OP", 0, 9),

2585+ ("RETURN_VALUE", None, 10),

2586+ ]

2587+after= [

2588+ ("LOAD_FAST_BORROW", 0, 1),

2589+ ("LOAD_CONST", 1, 8),

2590+ ("CONTAINS_OP", 0, 9),

2591+ ("RETURN_VALUE", None, 10),

2592+ ]

2593+self.cfg_optimization_test(before, after, consts=[None],

2594+expected_consts=[None, (1, 2, 3)])

2595+2596+deftest_fold_constant_big_set_contains_op(self):

2597+# x in {c1, c2, ..., cN} (N > 30) should fold to LOAD_CONST frozenset

2598+before= [

2599+ ("LOAD_FAST", 0, 1),

2600+ ("BUILD_SET", 0, 2),

2601+ ("LOAD_SMALL_INT", 1, 3), ("SET_ADD", 1, 4),

2602+ ("LOAD_SMALL_INT", 2, 5), ("SET_ADD", 1, 6),

2603+ ("LOAD_SMALL_INT", 3, 7), ("SET_ADD", 1, 8),

2604+ ("CONTAINS_OP", 0, 9),

2605+ ("RETURN_VALUE", None, 10),

2606+ ]

2607+after= [

2608+ ("LOAD_FAST_BORROW", 0, 1),

2609+ ("LOAD_CONST", 1, 8),

2610+ ("CONTAINS_OP", 0, 9),

2611+ ("RETURN_VALUE", None, 10),

2612+ ]

2613+self.cfg_optimization_test(before, after, consts=[None],

2614+expected_consts=[None, frozenset({1, 2, 3})])

2615+2616+deftest_no_fold_big_list_for_iter_with_non_const(self):

2617+same= [

2618+ ("BUILD_LIST", 0, 1),

2619+ ("LOAD_SMALL_INT", 1, 2), ("LIST_APPEND", 1, 3),

2620+ ("LOAD_FAST_BORROW", 0, 4), ("LIST_APPEND", 1, 5),

2621+ ("LOAD_SMALL_INT", 3, 6), ("LIST_APPEND", 1, 7),

2622+ ("GET_ITER", 0, 8),

2623+top:=self.Label(),

2624+ ("FOR_ITER", end:=self.Label(), 9),

2625+ ("STORE_FAST", 1, 10),

2626+ ("JUMP", top, 11),

2627+end,

2628+ ("END_FOR", None, 12),

2629+ ("POP_ITER", None, 13),

2630+ ("LOAD_CONST", 0, 14),

2631+ ("RETURN_VALUE", None, 15),

2632+ ]

2633+self.cfg_optimization_test(same, same, consts=["test"])

2634+2473263524742636classOptimizeLoadFastTestCase(DirectCfgOptimizerTests):

24752637defmake_bb(self, insts):