Skip to content

Commit 6b51678

Browse files
committed
pythongh-104635: Eliminate redundant STORE_FAST instructions in the compiler
1 parent eb0ce92 commit 6b51678

File tree

4 files changed

+66
-9
lines changed

4 files changed

+66
-9
lines changed

Lib/test/test_dis.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,9 @@ def extended_arg_quick():
808808
%3d 2 LOAD_CONST 1 (Ellipsis)
809809
4 EXTENDED_ARG 1
810810
6 UNPACK_EX 256
811-
8 STORE_FAST_STORE_FAST 0 (_, _)
812-
10 RETURN_CONST 0 (None)
811+
8 POP_TOP
812+
10 STORE_FAST 0 (_)
813+
12 RETURN_CONST 0 (None)
813814
"""% (extended_arg_quick.__code__.co_firstlineno,
814815
extended_arg_quick.__code__.co_firstlineno + 1,)
815816

Lib/test/test_peepholer.py

+43-2
Original file line numberDiff line numberDiff line change
@@ -1075,15 +1075,56 @@ def test_no_unsafe_static_swap(self):
10751075
('RETURN_VALUE', 5)
10761076
]
10771077
expected_insts = [
1078+
('LOAD_CONST', 0, 1),
1079+
('LOAD_CONST', 1, 2),
1080+
('NOP', 0, 3),
1081+
('STORE_FAST', 1, 4),
1082+
('POP_TOP', 0, 4),
1083+
('RETURN_VALUE', 5)
1084+
]
1085+
self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1)
1086+
1087+
def test_dead_store_elimination_in_same_lineno(self):
1088+
insts = [
10781089
('LOAD_CONST', 0, 1),
10791090
('LOAD_CONST', 1, 2),
10801091
('LOAD_CONST', 2, 3),
1081-
('SWAP', 3, 4),
1082-
('STORE_FAST_STORE_FAST', 17, 4),
1092+
('STORE_FAST', 1, 4),
1093+
('STORE_FAST', 1, 4),
1094+
('STORE_FAST', 1, 4),
1095+
('RETURN_VALUE', 5)
1096+
]
1097+
expected_insts = [
1098+
('LOAD_CONST', 0, 1),
1099+
('LOAD_CONST', 1, 2),
1100+
('NOP', 0, 3),
10831101
('POP_TOP', 0, 4),
1102+
('STORE_FAST', 1, 4),
1103+
('RETURN_VALUE', 5)
1104+
]
1105+
self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1)
1106+
1107+
def test_no_dead_store_elimination_in_different_lineno(self):
1108+
insts = [
1109+
('LOAD_CONST', 0, 1),
1110+
('LOAD_CONST', 1, 2),
1111+
('LOAD_CONST', 2, 3),
1112+
('STORE_FAST', 1, 4),
1113+
('STORE_FAST', 1, 5),
1114+
('STORE_FAST', 1, 6),
1115+
('RETURN_VALUE', 5)
1116+
]
1117+
expected_insts = [
1118+
('LOAD_CONST', 0, 1),
1119+
('LOAD_CONST', 1, 2),
1120+
('LOAD_CONST', 2, 3),
1121+
('STORE_FAST', 1, 4),
1122+
('STORE_FAST', 1, 5),
1123+
('STORE_FAST', 1, 6),
10841124
('RETURN_VALUE', 5)
10851125
]
10861126
self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1)
10871127

1128+
10881129
if __name__ == "__main__":
10891130
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Eliminate redundant :opcode:`STORE_FAST` instructions in the compiler. Patch
2+
by Dong-hee Na and Carl Meyer.

Python/flowgraph.c

+18-5
Original file line numberDiff line numberDiff line change
@@ -1515,15 +1515,18 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
15151515
*/
15161516
}
15171517
break;
1518+
case STORE_FAST:
1519+
if (opcode == nextop &&
1520+
oparg == bb->b_instr[i+1].i_oparg &&
1521+
bb->b_instr[i].i_loc.lineno == bb->b_instr[i+1].i_loc.lineno) {
1522+
bb->b_instr[i].i_opcode = POP_TOP;
1523+
bb->b_instr[i].i_oparg = 0;
1524+
}
1525+
break;
15181526
case SWAP:
15191527
if (oparg == 1) {
15201528
INSTR_SET_OP0(inst, NOP);
1521-
break;
1522-
}
1523-
if (swaptimize(bb, &i) < 0) {
1524-
goto error;
15251529
}
1526-
apply_static_swaps(bb, i);
15271530
break;
15281531
case KW_NAMES:
15291532
break;
@@ -1538,6 +1541,16 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
15381541
assert (!HAS_CONST(inst->i_opcode));
15391542
}
15401543
}
1544+
1545+
for (int i = 0; i < bb->b_iused; i++) {
1546+
cfg_instr *inst = &bb->b_instr[i];
1547+
if (inst->i_opcode == SWAP) {
1548+
if (swaptimize(bb, &i) < 0) {
1549+
goto error;
1550+
}
1551+
apply_static_swaps(bb, i);
1552+
}
1553+
}
15411554
return SUCCESS;
15421555
error:
15431556
return ERROR;

0 commit comments

Comments
 (0)