From 222c9f56f78967954ddde6a5062841c3477104f9 Mon Sep 17 00:00:00 2001 From: Yan Yanchii Date: Mon, 17 Feb 2025 18:01:51 +0100 Subject: [PATCH 1/5] move LOAD_SMALL_INT optimization from codegen to cfg --- Lib/test/test_compiler_codegen.py | 18 +++--- Lib/test/test_dis.py | 92 ++++++++++++++++--------------- Lib/test/test_peepholer.py | 34 ++++++------ Python/codegen.c | 8 --- Python/flowgraph.c | 31 +++++++++-- 5 files changed, 100 insertions(+), 83 deletions(-) diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py index cf5e2d901db4de..cc9ecc7e38917b 100644 --- a/Lib/test/test_compiler_codegen.py +++ b/Lib/test/test_compiler_codegen.py @@ -29,10 +29,10 @@ def test_if_expression(self): ('LOAD_CONST', 0, 1), ('TO_BOOL', 0, 1), ('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1), - ('LOAD_SMALL_INT', 42, 1), + ('LOAD_CONST', 1, 1), # 42 ('JUMP_NO_INTERRUPT', exit_lbl := self.Label()), false_lbl, - ('LOAD_SMALL_INT', 24, 1), + ('LOAD_CONST', 2, 1), # 24 exit_lbl, ('POP_TOP', None), ('LOAD_CONST', 1), @@ -82,7 +82,7 @@ def f(x): # Function body ('RESUME', 0), ('LOAD_FAST', 0), - ('LOAD_SMALL_INT', 42), + ('LOAD_CONST', 42), ('BINARY_OP', 0), ('RETURN_VALUE', None), ('LOAD_CONST', 0), @@ -125,23 +125,23 @@ def g(): [ ('RESUME', 0), ('NOP', None), - ('LOAD_SMALL_INT', 12), + ('LOAD_CONST', 12), ('RETURN_VALUE', None), ('LOAD_CONST', 1), ('RETURN_VALUE', None), ], [ ('RESUME', 0), - ('LOAD_SMALL_INT', 1), + ('LOAD_CONST', 1), ('STORE_FAST', 0), - ('LOAD_SMALL_INT', 2), + ('LOAD_CONST', 2), ('STORE_FAST', 1), - ('LOAD_SMALL_INT', 3), + ('LOAD_CONST', 3), ('STORE_FAST', 2), - ('LOAD_SMALL_INT', 4), + ('LOAD_CONST', 4), ('STORE_FAST', 3), ('NOP', None), - ('LOAD_SMALL_INT', 42), + ('LOAD_CONST', 42), ('RETURN_VALUE', None), ('LOAD_CONST', 0), ('RETURN_VALUE', None), diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 6e1d94bd535663..726af931a38ecd 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -56,7 +56,7 @@ def cm(cls, x): COMPARE_OP 72 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) @@ -67,7 +67,7 @@ def cm(cls, x): COMPARE_OP 72 (==) LOAD_FAST 0 STORE_ATTR 0 - LOAD_CONST 0 + LOAD_CONST 1 RETURN_VALUE """ @@ -79,7 +79,7 @@ def cm(cls, x): COMPARE_OP 72 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) @@ -90,7 +90,7 @@ def cm(cls, x): LOAD_SMALL_INT 1 COMPARE_OP 72 (==) STORE_FAST 0 (x) - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) @@ -182,7 +182,7 @@ def bug708901(): %3d L2: END_FOR POP_ITER - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, @@ -201,7 +201,7 @@ def bug1333982(x=[]): %3d RESUME 0 %3d LOAD_COMMON_CONSTANT 0 (AssertionError) - LOAD_CONST 0 ( at 0x..., file "%s", line %d>) + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) MAKE_FUNCTION LOAD_FAST 0 (x) GET_ITER @@ -280,10 +280,10 @@ def wrap_func_w_kwargs(): LOAD_SMALL_INT 1 LOAD_SMALL_INT 2 LOAD_SMALL_INT 5 - LOAD_CONST 0 (('c',)) + LOAD_CONST 1 (('c',)) CALL_KW 3 POP_TOP - LOAD_CONST 1 (None) + LOAD_CONST 2 (None) RETURN_VALUE """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) @@ -292,11 +292,11 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_SMALL_INT 0 - LOAD_CONST 0 (('*',)) + LOAD_CONST 1 (('*',)) IMPORT_NAME 0 (math) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) POP_TOP - LOAD_CONST 1 (None) + LOAD_CONST 2 (None) RETURN_VALUE """ @@ -369,7 +369,7 @@ def wrap_func_w_kwargs(): LOAD_SMALL_INT 1 BINARY_OP 0 (+) STORE_NAME 0 (x) - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ @@ -395,10 +395,10 @@ def wrap_func_w_kwargs(): CALL 1 STORE_SUBSCR - 2 LOAD_CONST 0 (", line 2>) + 2 LOAD_CONST 1 (", line 2>) MAKE_FUNCTION STORE_NAME 3 (__annotate__) - LOAD_CONST 1 (None) + LOAD_CONST 2 (None) RETURN_VALUE """ @@ -466,14 +466,14 @@ def foo(a: int, b: str) -> str: LOAD_ATTR 2 (__traceback__) STORE_FAST 1 (tb) L5: POP_EXCEPT - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) %4d LOAD_FAST 1 (tb) RETURN_VALUE - -- L6: LOAD_CONST 0 (None) + -- L6: LOAD_CONST 1 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) RERAISE 1 @@ -542,15 +542,15 @@ def _with(c): %4d LOAD_SMALL_INT 1 STORE_FAST 1 (x) -%4d L2: LOAD_CONST 0 (None) - LOAD_CONST 0 (None) - LOAD_CONST 0 (None) +%4d L2: LOAD_CONST 1 (None) + LOAD_CONST 1 (None) + LOAD_CONST 1 (None) CALL 3 POP_TOP %4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE %4d L3: PUSH_EXC_INFO @@ -567,7 +567,7 @@ def _with(c): %4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) - LOAD_CONST 0 (None) + LOAD_CONST 1 (None) RETURN_VALUE -- L6: COPY 3 @@ -892,7 +892,7 @@ def loop_test(): %3d RESUME_CHECK 0 %3d BUILD_LIST 0 - LOAD_CONST_MORTAL 1 ((1, 2, 3)) + LOAD_CONST_MORTAL 2 ((1, 2, 3)) LIST_EXTEND 1 LOAD_SMALL_INT 3 BINARY_OP 5 (*) @@ -908,7 +908,7 @@ def loop_test(): %3d L2: END_FOR POP_ITER - LOAD_CONST_IMMORTAL 0 (None) + LOAD_CONST_IMMORTAL 1 (None) RETURN_VALUE """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, @@ -1071,7 +1071,7 @@ def test_dis_with_linenos_but_no_columns(self): '', '2:5-2:6 LOAD_SMALL_INT 1', '2:?-2:? STORE_FAST 0 (x)', - '2:?-2:? LOAD_CONST 0 (None)', + '2:?-2:? LOAD_CONST 1 (None)', '2:?-2:? RETURN_VALUE', '', ]) @@ -1537,6 +1537,8 @@ def f(c=c): Number of locals: 0 Stack size: \\d+ Flags: 0x0 +Constants: + 0: 1 Names: 0: x""" @@ -1550,7 +1552,8 @@ def f(c=c): Stack size: \\d+ Flags: 0x0 Constants: - 0: None + 0: 1 + 1: None Names: 0: x""" @@ -1564,7 +1567,7 @@ def f(c=c): Stack size: \\d+ Flags: 0x0 Constants: - 0: None + 0: 0 Names: 0: x""" @@ -1584,7 +1587,8 @@ async def async_def(): Stack size: \\d+ Flags: OPTIMIZED, NEWLOCALS, COROUTINE Constants: - 0: None + 0: 1 + 1: None Names: 0: b 1: c @@ -1668,9 +1672,9 @@ def jumpy(): # End fodder for opinfo generation tests expected_outer_line = 1 _line_offset = outer.__code__.co_firstlineno - 1 -code_object_f = outer.__code__.co_consts[0] +code_object_f = outer.__code__.co_consts[1] expected_f_line = code_object_f.co_firstlineno - _line_offset -code_object_inner = code_object_f.co_consts[0] +code_object_inner = code_object_f.co_consts[1] expected_inner_line = code_object_inner.co_firstlineno - _line_offset expected_jumpy_line = 1 @@ -1734,11 +1738,11 @@ def _prepare_test_cases(): make_inst(opname='MAKE_CELL', arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None), make_inst(opname='MAKE_CELL', arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None), make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1), - make_inst(opname='LOAD_CONST', arg=3, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2), + make_inst(opname='LOAD_CONST', arg=4, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2), make_inst(opname='LOAD_FAST', arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2), make_inst(opname='LOAD_FAST', arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2), make_inst(opname='BUILD_TUPLE', arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2), - make_inst(opname='LOAD_CONST', arg=0, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2), + make_inst(opname='LOAD_CONST', arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2), make_inst(opname='MAKE_FUNCTION', arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2), make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2), make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2), @@ -1746,11 +1750,11 @@ def _prepare_test_cases(): make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), make_inst(opname='LOAD_DEREF', arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7), make_inst(opname='LOAD_DEREF', arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7), - make_inst(opname='LOAD_CONST', arg=1, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7), + make_inst(opname='LOAD_CONST', arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7), make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7), make_inst(opname='BUILD_LIST', arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7), make_inst(opname='BUILD_MAP', arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7), - make_inst(opname='LOAD_CONST', arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7), + make_inst(opname='LOAD_CONST', arg=3, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7), make_inst(opname='CALL', arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7), make_inst(opname='LOAD_FAST', arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8), @@ -1762,13 +1766,13 @@ def _prepare_test_cases(): make_inst(opname='MAKE_CELL', arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None), make_inst(opname='MAKE_CELL', arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None), make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2), - make_inst(opname='LOAD_CONST', arg=1, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3), + make_inst(opname='LOAD_CONST', arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3), make_inst(opname='LOAD_FAST', arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3), make_inst(opname='LOAD_FAST', arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3), make_inst(opname='LOAD_FAST', arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3), make_inst(opname='LOAD_FAST', arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3), make_inst(opname='BUILD_TUPLE', arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3), - make_inst(opname='LOAD_CONST', arg=0, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3), + make_inst(opname='LOAD_CONST', arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3), make_inst(opname='MAKE_FUNCTION', arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3), make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3), make_inst(opname='SET_FUNCTION_ATTRIBUTE', arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3), @@ -1828,7 +1832,7 @@ def _prepare_test_cases(): make_inst(opname='END_FOR', arg=None, argval=None, argrepr='', offset=92, start_offset=92, starts_line=True, line_number=3, label=4), make_inst(opname='POP_ITER', arg=None, argval=None, argrepr='', offset=94, start_offset=94, starts_line=False, line_number=3), make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=96, start_offset=96, starts_line=True, line_number=10, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=0, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=106, start_offset=106, starts_line=False, line_number=10), + make_inst(opname='LOAD_CONST', arg=1, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=106, start_offset=106, starts_line=False, line_number=10), make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=108, start_offset=108, starts_line=False, line_number=10, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=116, start_offset=116, starts_line=False, line_number=10), make_inst(opname='LOAD_FAST_CHECK', arg=0, argval='i', argrepr='i', offset=118, start_offset=118, starts_line=True, line_number=11, label=5), @@ -1857,7 +1861,7 @@ def _prepare_test_cases(): make_inst(opname='JUMP_BACKWARD', arg=46, argval=118, argrepr='to L5', offset=206, start_offset=206, starts_line=False, line_number=16, cache_info=[('counter', 1, b'\x00\x00')]), make_inst(opname='JUMP_FORWARD', arg=11, argval=234, argrepr='to L9', offset=210, start_offset=210, starts_line=True, line_number=17, label=7), make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=212, start_offset=212, starts_line=True, line_number=19, label=8, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=1, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=222, start_offset=222, starts_line=False, line_number=19), + make_inst(opname='LOAD_CONST', arg=2, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=222, start_offset=222, starts_line=False, line_number=19), make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=224, start_offset=224, starts_line=False, line_number=19, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=232, start_offset=232, starts_line=False, line_number=19), make_inst(opname='NOP', arg=None, argval=None, argrepr='', offset=234, start_offset=234, starts_line=True, line_number=20, label=9), @@ -1874,19 +1878,19 @@ def _prepare_test_cases(): make_inst(opname='CALL', arg=0, argval=0, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='STORE_FAST', arg=1, argval='dodgy', argrepr='dodgy', offset=274, start_offset=274, starts_line=False, line_number=25), make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=276, start_offset=276, starts_line=True, line_number=26, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=2, argval='Never reach this', argrepr="'Never reach this'", offset=286, start_offset=286, starts_line=False, line_number=26), + make_inst(opname='LOAD_CONST', arg=3, argval='Never reach this', argrepr="'Never reach this'", offset=286, start_offset=286, starts_line=False, line_number=26), make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=288, start_offset=288, starts_line=False, line_number=26, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=26), - make_inst(opname='LOAD_CONST', arg=3, argval=None, argrepr='None', offset=298, start_offset=298, starts_line=True, line_number=25), - make_inst(opname='LOAD_CONST', arg=3, argval=None, argrepr='None', offset=300, start_offset=300, starts_line=False, line_number=25), - make_inst(opname='LOAD_CONST', arg=3, argval=None, argrepr='None', offset=302, start_offset=302, starts_line=False, line_number=25), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=298, start_offset=298, starts_line=True, line_number=25), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=300, start_offset=300, starts_line=False, line_number=25), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=302, start_offset=302, starts_line=False, line_number=25), make_inst(opname='CALL', arg=3, argval=3, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=25, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25), make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=314, start_offset=314, starts_line=True, line_number=28, label=10, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=324, start_offset=324, starts_line=False, line_number=28), + make_inst(opname='LOAD_CONST', arg=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=324, start_offset=324, starts_line=False, line_number=28), make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=28), - make_inst(opname='LOAD_CONST', arg=3, argval=None, argrepr='None', offset=336, start_offset=336, starts_line=False, line_number=28), + make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=336, start_offset=336, starts_line=False, line_number=28), make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=338, start_offset=338, starts_line=False, line_number=28), make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=True, line_number=25), make_inst(opname='WITH_EXCEPT_START', arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=25), @@ -1910,7 +1914,7 @@ def _prepare_test_cases(): make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=22), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=22), make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=400, start_offset=400, starts_line=True, line_number=23, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=410, start_offset=410, starts_line=False, line_number=23), + make_inst(opname='LOAD_CONST', arg=5, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=410, start_offset=410, starts_line=False, line_number=23), make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=23, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=420, start_offset=420, starts_line=False, line_number=23), make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=23), @@ -1921,7 +1925,7 @@ def _prepare_test_cases(): make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None), make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None), make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=436, start_offset=436, starts_line=True, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - make_inst(opname='LOAD_CONST', arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=446, start_offset=446, starts_line=False, line_number=28), + make_inst(opname='LOAD_CONST', arg=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=446, start_offset=446, starts_line=False, line_number=28), make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=448, start_offset=448, starts_line=False, line_number=28, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=456, start_offset=456, starts_line=False, line_number=28), make_inst(opname='RERAISE', arg=0, argval=0, argrepr='', offset=458, start_offset=458, starts_line=False, line_number=28), diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 98f6b29dc7fc5e..4644641144bee5 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -1207,16 +1207,16 @@ def test_conditional_jump_forward_non_const_condition(self): expected_insts = [ ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), - ('LOAD_CONST', 1, 13), + ('LOAD_SMALL_INT', 2, 13), ('RETURN_VALUE', None, 13), lbl, - ('LOAD_CONST', 2, 14), + ('LOAD_SMALL_INT', 3, 14), ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, consts=[0, 1, 2, 3, 4], - expected_consts=[0, 2, 3]) + expected_consts=[0]) def test_list_exceeding_stack_use_guideline(self): def f(): @@ -2157,13 +2157,13 @@ def test_conditional_jump_forward_const_condition(self): expected_insts = [ ('NOP', None, 11), ('NOP', None, 12), - ('LOAD_CONST', 1, 14), + ('LOAD_SMALL_INT', 3, 14), ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, consts=[0, 1, 2, 3, 4], - expected_consts=[0, 3]) + expected_consts=[0]) def test_conditional_jump_backward_non_const_condition(self): insts = [ @@ -2210,10 +2210,10 @@ def test_except_handler_label(self): ] expected_insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), - ('LOAD_CONST', 1, 11), + ('LOAD_SMALL_INT', 1, 11), ('RETURN_VALUE', None, 11), handler, - ('LOAD_CONST', 2, 12), + ('LOAD_SMALL_INT', 2, 12), ('RETURN_VALUE', None, 12), ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(5))) @@ -2232,12 +2232,12 @@ def test_no_unsafe_static_swap(self): ('RETURN_VALUE', None, 5) ] expected_insts = [ - ('LOAD_CONST', 0, 1), - ('LOAD_CONST', 1, 2), + ('LOAD_SMALL_INT', 0, 1), + ('LOAD_SMALL_INT', 1, 2), ('NOP', None, 3), ('STORE_FAST', 1, 4), ('POP_TOP', None, 4), - ('LOAD_CONST', 0, 5), + ('LOAD_SMALL_INT', 0, 5), ('RETURN_VALUE', None, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) @@ -2254,12 +2254,12 @@ def test_dead_store_elimination_in_same_lineno(self): ('RETURN_VALUE', None, 5) ] expected_insts = [ - ('LOAD_CONST', 0, 1), - ('LOAD_CONST', 1, 2), + ('LOAD_SMALL_INT', 0, 1), + ('LOAD_SMALL_INT', 1, 2), ('NOP', None, 3), ('POP_TOP', None, 4), ('STORE_FAST', 1, 4), - ('LOAD_CONST', 0, 5), + ('LOAD_SMALL_INT', 0, 5), ('RETURN_VALUE', None, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) @@ -2276,13 +2276,13 @@ def test_no_dead_store_elimination_in_different_lineno(self): ('RETURN_VALUE', None, 5) ] expected_insts = [ - ('LOAD_CONST', 0, 1), - ('LOAD_CONST', 1, 2), - ('LOAD_CONST', 2, 3), + ('LOAD_SMALL_INT', 0, 1), + ('LOAD_SMALL_INT', 1, 2), + ('LOAD_SMALL_INT', 2, 3), ('STORE_FAST', 1, 4), ('STORE_FAST', 1, 5), ('STORE_FAST', 1, 6), - ('LOAD_CONST', 0, 5), + ('LOAD_SMALL_INT', 0, 5), ('RETURN_VALUE', None, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) diff --git a/Python/codegen.c b/Python/codegen.c index 6ef3c63b33530e..627471cc386e04 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -272,14 +272,6 @@ codegen_addop_noarg(instr_sequence *seq, int opcode, location loc) static int codegen_addop_load_const(compiler *c, location loc, PyObject *o) { - if (PyLong_CheckExact(o)) { - int overflow; - long val = PyLong_AsLongAndOverflow(o, &overflow); - if (!overflow && _PY_IS_SMALL_INT(val)) { - ADDOP_I(c, loc, LOAD_SMALL_INT, val); - return SUCCESS; - } - } Py_ssize_t arg = _PyCompile_AddConst(c, o); if (arg < 0) { return ERROR; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index fdafafd76617a8..e222b722e40931 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1293,6 +1293,7 @@ loads_const(int opcode) return OPCODE_HAS_CONST(opcode) || opcode == LOAD_SMALL_INT; } +/* Returns new reference */ static PyObject* get_const_value(int opcode, int oparg, PyObject *co_consts) { @@ -1386,10 +1387,10 @@ nop_out(cfg_instr **instrs, int size) } } -/* Steals reference to "newconst" */ -static int -instr_make_load_const(cfg_instr *instr, PyObject *newconst, - PyObject *consts, PyObject *const_cache) +/* Does not steal reference to "newconst" */ +static bool +maybe_instr_make_load_smallint(cfg_instr *instr, PyObject *newconst, + PyObject *consts, PyObject *const_cache) { if (PyLong_CheckExact(newconst)) { int overflow; @@ -1397,9 +1398,22 @@ instr_make_load_const(cfg_instr *instr, PyObject *newconst, if (!overflow && _PY_IS_SMALL_INT(val)) { assert(_Py_IsImmortal(newconst)); INSTR_SET_OP1(instr, LOAD_SMALL_INT, (int)val); - return SUCCESS; + return true; } } + return false; +} + + +/* Steals reference to "newconst" */ +static int +instr_make_load_const(cfg_instr *instr, PyObject *newconst, + PyObject *consts, PyObject *const_cache) +{ + if (maybe_instr_make_load_smallint(instr, newconst, consts, const_cache)) { + assert(instr->i_opcode == LOAD_SMALL_INT); + return SUCCESS; + } int oparg = add_const(newconst, consts, const_cache); RETURN_IF_ERROR(oparg); INSTR_SET_OP1(instr, LOAD_CONST, oparg); @@ -2038,6 +2052,13 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * int oparg = 0; for (int i = 0; i < bb->b_iused; i++) { cfg_instr *inst = &bb->b_instr[i]; + if (inst->i_opcode == LOAD_CONST) { + PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts); + if (maybe_instr_make_load_smallint(inst, constant, consts, const_cache)) { + assert(inst->i_opcode == LOAD_SMALL_INT); + } + Py_DECREF(constant); + } bool is_copy_of_load_const = (opcode == LOAD_CONST && inst->i_opcode == COPY && inst->i_oparg == 1); From f878d788f867d0d200c94d1f44bbcdaaf81693c6 Mon Sep 17 00:00:00 2001 From: Yan Yanchii Date: Thu, 13 Mar 2025 18:30:50 +0100 Subject: [PATCH 2/5] fix conflicts --- Programs/test_frozenmain.h | 61 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 55bf4fe26e967a..1c7f74cc8039f2 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,38 +1,39 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0, - 0,0,0,0,0,243,184,0,0,0,128,0,90,0,80,0, - 71,0,112,0,90,0,80,0,71,1,112,1,89,2,32,0, - 80,1,50,1,0,0,0,0,0,0,30,0,89,2,32,0, - 80,2,89,0,78,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,243,184,0,0,0,128,0,90,0,80,1, + 71,0,112,0,90,0,80,1,71,1,112,1,89,2,32,0, + 80,2,50,1,0,0,0,0,0,0,30,0,89,2,32,0, + 80,3,89,0,78,6,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,50,2,0,0,0,0,0,0, 30,0,89,1,78,8,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,32,0,50,0,0,0,0,0, - 0,0,80,3,43,26,0,0,0,0,0,0,0,0,0,0, - 112,5,80,4,15,0,68,24,0,0,112,6,89,2,32,0, - 80,5,89,6,11,0,80,6,89,5,89,6,43,26,0,0, + 0,0,80,4,43,26,0,0,0,0,0,0,0,0,0,0, + 112,5,80,5,15,0,68,24,0,0,112,6,89,2,32,0, + 80,6,89,6,11,0,80,7,89,5,89,6,43,26,0,0, 0,0,0,0,0,0,0,0,11,0,48,4,50,1,0,0, - 0,0,0,0,30,0,73,26,0,0,8,0,29,0,80,0, - 34,0,41,7,78,122,18,70,114,111,122,101,110,32,72,101, - 108,108,111,32,87,111,114,108,100,122,8,115,121,115,46,97, - 114,103,118,218,6,99,111,110,102,105,103,41,5,218,12,112, - 114,111,103,114,97,109,95,110,97,109,101,218,10,101,120,101, - 99,117,116,97,98,108,101,218,15,117,115,101,95,101,110,118, - 105,114,111,110,109,101,110,116,218,17,99,111,110,102,105,103, - 117,114,101,95,99,95,115,116,100,105,111,218,14,98,117,102, - 102,101,114,101,100,95,115,116,100,105,111,122,7,99,111,110, - 102,105,103,32,122,2,58,32,41,7,218,3,115,121,115,218, - 17,95,116,101,115,116,105,110,116,101,114,110,97,108,99,97, - 112,105,218,5,112,114,105,110,116,218,4,97,114,103,118,218, - 11,103,101,116,95,99,111,110,102,105,103,115,114,2,0,0, - 0,218,3,107,101,121,169,0,243,0,0,0,0,218,18,116, - 101,115,116,95,102,114,111,122,101,110,109,97,105,110,46,112, - 121,218,8,60,109,111,100,117,108,101,62,114,17,0,0,0, - 1,0,0,0,115,94,0,0,0,240,3,1,1,1,243,8, - 0,1,11,219,0,24,225,0,5,208,6,26,212,0,27,217, - 0,5,128,106,144,35,151,40,145,40,212,0,27,216,9,26, - 215,9,38,210,9,38,211,9,40,168,24,213,9,50,128,6, - 243,2,6,12,2,128,67,241,14,0,5,10,136,71,144,67, - 144,53,152,2,152,54,160,35,157,59,152,45,208,10,40,214, - 4,41,243,15,6,12,2,114,15,0,0,0, + 0,0,0,0,30,0,73,26,0,0,8,0,29,0,80,1, + 34,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, + 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, + 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, + 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, + 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, + 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, + 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, + 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, + 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, + 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, + 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, + 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, + 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, + 0,0,218,18,116,101,115,116,95,102,114,111,122,101,110,109, + 97,105,110,46,112,121,218,8,60,109,111,100,117,108,101,62, + 114,18,0,0,0,1,0,0,0,115,94,0,0,0,240,3, + 1,1,1,243,8,0,1,11,219,0,24,225,0,5,208,6, + 26,212,0,27,217,0,5,128,106,144,35,151,40,145,40,212, + 0,27,216,9,26,215,9,38,210,9,38,211,9,40,168,24, + 213,9,50,128,6,243,2,6,12,2,128,67,241,14,0,5, + 10,136,71,144,67,144,53,152,2,152,54,160,35,157,59,152, + 45,208,10,40,214,4,41,243,15,6,12,2,114,16,0,0, + 0, }; From e3f4f8b7e1a5e4363b79edcaa3287dcfa5520e45 Mon Sep 17 00:00:00 2001 From: Yan Yanchii Date: Fri, 14 Mar 2025 11:56:39 +0100 Subject: [PATCH 3/5] address review --- Python/flowgraph.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index e222b722e40931..c888b39d3e0bdb 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -2054,9 +2054,7 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * cfg_instr *inst = &bb->b_instr[i]; if (inst->i_opcode == LOAD_CONST) { PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts); - if (maybe_instr_make_load_smallint(inst, constant, consts, const_cache)) { - assert(inst->i_opcode == LOAD_SMALL_INT); - } + (void)maybe_instr_make_load_smallint(inst, constant, consts, const_cache); Py_DECREF(constant); } bool is_copy_of_load_const = (opcode == LOAD_CONST && From fa005f39b37bf6aa12d0156805a509b8635c5ab2 Mon Sep 17 00:00:00 2001 From: Yan Yanchii Date: Fri, 14 Mar 2025 13:27:01 +0100 Subject: [PATCH 4/5] check PyLong_AsLongAndOverflow result for error --- Python/flowgraph.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index c888b39d3e0bdb..134541e29c2c53 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1387,21 +1387,28 @@ nop_out(cfg_instr **instrs, int size) } } -/* Does not steal reference to "newconst" */ -static bool +/* Does not steal reference to "newconst". + Return 1 if changed instruction to LOAD_SMALL_INT. + Return 0 if could not change instruction to LOAD_SMALL_INT. + Return -1 on error. +*/ +static int maybe_instr_make_load_smallint(cfg_instr *instr, PyObject *newconst, PyObject *consts, PyObject *const_cache) { if (PyLong_CheckExact(newconst)) { int overflow; long val = PyLong_AsLongAndOverflow(newconst, &overflow); + if (val == -1 && PyErr_Occurred()) { + return -1; + } if (!overflow && _PY_IS_SMALL_INT(val)) { assert(_Py_IsImmortal(newconst)); INSTR_SET_OP1(instr, LOAD_SMALL_INT, (int)val); - return true; + return 1; } } - return false; + return 0; } @@ -1410,9 +1417,9 @@ static int instr_make_load_const(cfg_instr *instr, PyObject *newconst, PyObject *consts, PyObject *const_cache) { - if (maybe_instr_make_load_smallint(instr, newconst, consts, const_cache)) { - assert(instr->i_opcode == LOAD_SMALL_INT); - return SUCCESS; + int res = maybe_instr_make_load_smallint(instr, newconst, consts, const_cache); + if (res) { + return res == -1 ? ERROR : SUCCESS; } int oparg = add_const(newconst, consts, const_cache); RETURN_IF_ERROR(oparg); @@ -2054,8 +2061,11 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * cfg_instr *inst = &bb->b_instr[i]; if (inst->i_opcode == LOAD_CONST) { PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts); - (void)maybe_instr_make_load_smallint(inst, constant, consts, const_cache); + int res = maybe_instr_make_load_smallint(inst, constant, consts, const_cache); Py_DECREF(constant); + if (res < 0) { + return ERROR; + } } bool is_copy_of_load_const = (opcode == LOAD_CONST && inst->i_opcode == COPY && From 83ccea7d3bc4826488bcdb4f0fd6ed42196d7c31 Mon Sep 17 00:00:00 2001 From: Yan Yanchii Date: Fri, 14 Mar 2025 13:37:27 +0100 Subject: [PATCH 5/5] decref newconst on error --- Python/flowgraph.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 134541e29c2c53..17ef7e1bf7ad4e 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1418,8 +1418,12 @@ instr_make_load_const(cfg_instr *instr, PyObject *newconst, PyObject *consts, PyObject *const_cache) { int res = maybe_instr_make_load_smallint(instr, newconst, consts, const_cache); - if (res) { - return res == -1 ? ERROR : SUCCESS; + if (res < 0) { + Py_DECREF(newconst); + return ERROR; + } + if (res > 0) { + return SUCCESS; } int oparg = add_const(newconst, consts, const_cache); RETURN_IF_ERROR(oparg); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy