Skip to content

Commit f038e7f

Browse files
committed
Allow LOAD_FAST to be optimized to LOAD_FAST_BORROW when the loaded
reference is unconsumed at the end of a basic block, as long as it's otherwise safe to borrow (not killed and not stored as a local).
1 parent 9546eee commit f038e7f

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

Lib/test/test_peepholer.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,14 +2430,14 @@ def test_optimized(self):
24302430
]
24312431
self.check(insts, expected)
24322432

2433-
def test_unoptimized_if_unconsumed(self):
2433+
def test_optimize_unconsumed_when_is_safe(self):
24342434
insts = [
24352435
("LOAD_FAST", 0, 1),
24362436
("LOAD_FAST", 1, 2),
24372437
("POP_TOP", None, 3),
24382438
]
24392439
expected = [
2440-
("LOAD_FAST", 0, 1),
2440+
("LOAD_FAST_BORROW", 0, 1),
24412441
("LOAD_FAST_BORROW", 1, 2),
24422442
("POP_TOP", None, 3),
24432443
]
@@ -2449,7 +2449,7 @@ def test_unoptimized_if_unconsumed(self):
24492449
("POP_TOP", None, 3),
24502450
]
24512451
expected = [
2452-
("LOAD_FAST", 0, 1),
2452+
("LOAD_FAST_BORROW", 0, 1),
24532453
("NOP", None, 2),
24542454
("NOP", None, 3),
24552455
]
@@ -2509,7 +2509,12 @@ def test_consume_some_inputs_no_outputs(self):
25092509
("GET_LEN", None, 2),
25102510
("LIST_APPEND", 0, 3),
25112511
]
2512-
self.check(insts, insts)
2512+
expected = [
2513+
("LOAD_FAST_BORROW", 0, 1),
2514+
("GET_LEN", None, 2),
2515+
("LIST_APPEND", 0, 3),
2516+
]
2517+
self.check(insts, expected)
25132518

25142519
def test_check_exc_match(self):
25152520
insts = [
@@ -2518,7 +2523,7 @@ def test_check_exc_match(self):
25182523
("CHECK_EXC_MATCH", None, 3)
25192524
]
25202525
expected = [
2521-
("LOAD_FAST", 0, 1),
2526+
("LOAD_FAST_BORROW", 0, 1),
25222527
("LOAD_FAST_BORROW", 1, 2),
25232528
("CHECK_EXC_MATCH", None, 3)
25242529
]
@@ -2537,7 +2542,19 @@ def test_for_iter(self):
25372542
("LOAD_CONST", 0, 7),
25382543
("RETURN_VALUE", None, 8),
25392544
]
2540-
self.cfg_optimization_test(insts, insts, consts=[None])
2545+
expected = [
2546+
("LOAD_FAST_BORROW", 0, 1),
2547+
top := self.Label(),
2548+
("FOR_ITER", end := self.Label(), 2),
2549+
("STORE_FAST", 2, 3),
2550+
("JUMP", top, 4),
2551+
end,
2552+
("END_FOR", None, 5),
2553+
("POP_TOP", None, 6),
2554+
("LOAD_CONST", 0, 7),
2555+
("RETURN_VALUE", None, 8),
2556+
]
2557+
self.cfg_optimization_test(insts, expected, consts=[None])
25412558

25422559
def test_load_attr(self):
25432560
insts = [
@@ -2556,7 +2573,7 @@ def test_load_attr(self):
25562573
("LOAD_ATTR", 1, 2),
25572574
]
25582575
expected = [
2559-
("LOAD_FAST", 0, 1),
2576+
("LOAD_FAST_BORROW", 0, 1),
25602577
("LOAD_ATTR", 1, 2),
25612578
]
25622579
self.check(insts, expected)
@@ -2586,7 +2603,7 @@ def test_super_attr(self):
25862603
expected = [
25872604
("LOAD_FAST_BORROW", 0, 1),
25882605
("LOAD_FAST_BORROW", 1, 2),
2589-
("LOAD_FAST", 2, 3),
2606+
("LOAD_FAST_BORROW", 2, 3),
25902607
("LOAD_SUPER_ATTR", 1, 4),
25912608
]
25922609
self.check(insts, expected)
@@ -2603,7 +2620,7 @@ def test_send(self):
26032620
("RETURN_VALUE", None, 7)
26042621
]
26052622
expected = [
2606-
("LOAD_FAST", 0, 1),
2623+
("LOAD_FAST_BORROW", 0, 1),
26072624
("LOAD_FAST_BORROW", 1, 2),
26082625
("SEND", end := self.Label(), 3),
26092626
("LOAD_CONST", 0, 4),

Python/flowgraph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2976,7 +2976,7 @@ optimize_load_fast(cfg_builder *g)
29762976

29772977
// Optimize instructions
29782978
for (int i = 0; i < block->b_iused; i++) {
2979-
if (!instr_flags[i]) {
2979+
if (!(instr_flags[i] & (SUPPORT_KILLED | STORED_AS_LOCAL))) {
29802980
cfg_instr *instr = &block->b_instr[i];
29812981
switch (instr->i_opcode) {
29822982
case LOAD_FAST:

0 commit comments

Comments
 (0)