mirror of
https://github.com/python/cpython.git
synced 2026-05-06 04:37:33 -04:00
gh-148871: extend and improve LOAD_COMMON_CONSTANT (GH-148971)
This commit is contained in:
@@ -75,7 +75,12 @@ extern "C" {
|
||||
#define CONSTANT_BUILTIN_ANY 4
|
||||
#define CONSTANT_BUILTIN_LIST 5
|
||||
#define CONSTANT_BUILTIN_SET 6
|
||||
#define NUM_COMMON_CONSTANTS 7
|
||||
#define CONSTANT_NONE 7
|
||||
#define CONSTANT_EMPTY_STR 8
|
||||
#define CONSTANT_TRUE 9
|
||||
#define CONSTANT_FALSE 10
|
||||
#define CONSTANT_MINUS_ONE 11
|
||||
#define NUM_COMMON_CONSTANTS 12
|
||||
|
||||
/* Values used in the oparg for RESUME */
|
||||
#define RESUME_AT_FUNC_START 0
|
||||
|
||||
+10
-3
@@ -643,6 +643,7 @@ class ArgResolver:
|
||||
argrepr = _intrinsic_2_descs[arg]
|
||||
elif deop == LOAD_COMMON_CONSTANT:
|
||||
obj = _common_constants[arg]
|
||||
argval = obj
|
||||
if isinstance(obj, type):
|
||||
argrepr = obj.__name__
|
||||
else:
|
||||
@@ -692,10 +693,15 @@ def _get_const_value(op, arg, co_consts):
|
||||
Otherwise (if it is a LOAD_CONST and co_consts is not
|
||||
provided) returns the dis.UNKNOWN sentinel.
|
||||
"""
|
||||
assert op in hasconst or op == LOAD_SMALL_INT
|
||||
assert op in hasconst or op == LOAD_SMALL_INT or op == LOAD_COMMON_CONSTANT
|
||||
|
||||
if op == LOAD_SMALL_INT:
|
||||
return arg
|
||||
if op == LOAD_COMMON_CONSTANT:
|
||||
# Opargs 0-6 are callables; 7-11 are literal values.
|
||||
if 7 <= arg <= 11:
|
||||
return _common_constants[arg]
|
||||
return UNKNOWN
|
||||
argval = UNKNOWN
|
||||
if co_consts is not None:
|
||||
argval = co_consts[arg]
|
||||
@@ -1015,8 +1021,9 @@ def _find_imports(co):
|
||||
if op == IMPORT_NAME and i >= 2:
|
||||
from_op = opargs[i-1]
|
||||
level_op = opargs[i-2]
|
||||
if (from_op[0] in hasconst and
|
||||
(level_op[0] in hasconst or level_op[0] == LOAD_SMALL_INT)):
|
||||
if ((from_op[0] in hasconst or from_op[0] == LOAD_COMMON_CONSTANT) and
|
||||
(level_op[0] in hasconst or level_op[0] == LOAD_SMALL_INT or
|
||||
level_op[0] == LOAD_COMMON_CONSTANT)):
|
||||
level = _get_const_value(level_op[0], level_op[1], consts)
|
||||
fromlist = _get_const_value(from_op[0], from_op[1], consts)
|
||||
# IMPORT_NAME encodes lazy/eager flags in bits 0-1,
|
||||
|
||||
+4
-1
@@ -41,7 +41,10 @@ _intrinsic_2_descs = _opcode.get_intrinsic2_descs()
|
||||
_special_method_names = _opcode.get_special_method_names()
|
||||
_common_constants = [builtins.AssertionError, builtins.NotImplementedError,
|
||||
builtins.tuple, builtins.all, builtins.any, builtins.list,
|
||||
builtins.set]
|
||||
builtins.set,
|
||||
# Append-only — must match CONSTANT_* in
|
||||
# Include/internal/pycore_opcode_utils.h.
|
||||
None, "", True, False, -1]
|
||||
_nb_ops = _opcode.get_nb_ops()
|
||||
|
||||
hascompare = [opmap["COMPARE_OP"]]
|
||||
|
||||
@@ -2685,11 +2685,12 @@ class ConstantTests(unittest.TestCase):
|
||||
|
||||
def get_load_const(self, tree):
|
||||
# Compile to bytecode, disassemble and get parameter of LOAD_CONST
|
||||
# instructions
|
||||
# and LOAD_COMMON_CONSTANT instructions
|
||||
co = compile(tree, '<string>', 'exec')
|
||||
consts = []
|
||||
for instr in dis.get_instructions(co):
|
||||
if instr.opcode in dis.hasconst:
|
||||
if instr.opcode in dis.hasconst or \
|
||||
instr.opname == 'LOAD_COMMON_CONSTANT':
|
||||
consts.append(instr.argval)
|
||||
return consts
|
||||
|
||||
|
||||
@@ -3446,6 +3446,27 @@ class TestUopsOptimization(unittest.TestCase):
|
||||
self.assertIn("_BUILD_LIST", uops)
|
||||
self.assertNotIn("_LOAD_COMMON_CONSTANT", uops)
|
||||
|
||||
def test_load_common_constant_new_literals(self):
|
||||
def testfunc(n):
|
||||
x = None
|
||||
s = ""
|
||||
t = True
|
||||
f = False
|
||||
m = -1
|
||||
for _ in range(n):
|
||||
x = None
|
||||
s = ""
|
||||
t = True
|
||||
f = False
|
||||
m = -1
|
||||
return x, s, t, f, m
|
||||
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
|
||||
self.assertEqual(res, (None, "", True, False, -1))
|
||||
self.assertIsNotNone(ex)
|
||||
uops = get_opnames(ex)
|
||||
self.assertNotIn("_LOAD_COMMON_CONSTANT", uops)
|
||||
self.assertIn("_LOAD_CONST_INLINE_BORROW", uops)
|
||||
|
||||
def test_load_small_int(self):
|
||||
def testfunc(n):
|
||||
x = 0
|
||||
|
||||
@@ -87,7 +87,7 @@ cellvars: ()
|
||||
freevars: ()
|
||||
nlocals: 0
|
||||
flags: 67108867
|
||||
consts: ("'doc string'", 'None')
|
||||
consts: ("'doc string'",)
|
||||
|
||||
>>> def keywordonly_args(a,b,*,k1):
|
||||
... return a,b,k1
|
||||
@@ -161,7 +161,7 @@ cellvars: ()
|
||||
freevars: ()
|
||||
nlocals: 3
|
||||
flags: 67108995
|
||||
consts: ("'This is a docstring from async function'", 'None')
|
||||
consts: ("'This is a docstring from async function'",)
|
||||
|
||||
>>> def no_docstring(x, y, z):
|
||||
... return x + "hello" + y + z + "world"
|
||||
@@ -532,7 +532,7 @@ class CodeTest(unittest.TestCase):
|
||||
],
|
||||
[
|
||||
("PUSH_EXC_INFO", None),
|
||||
("LOAD_CONST", None), # artificial 'None'
|
||||
("LOAD_COMMON_CONSTANT", None), # artificial 'None'
|
||||
("STORE_NAME", "e"), # XX: we know the location for this
|
||||
("DELETE_NAME", "e"),
|
||||
("RERAISE", 1),
|
||||
|
||||
@@ -2485,12 +2485,13 @@ class TestSourcePositions(unittest.TestCase):
|
||||
start_line, end_line, _, _ = instr.positions
|
||||
self.assertEqual(start_line, end_line)
|
||||
|
||||
# Expect four `LOAD_CONST None` instructions:
|
||||
# Expect four `None`-loading instructions:
|
||||
# three for the no-exception __exit__ call, and one for the return.
|
||||
# They should all have the locations of the context manager ('xyz').
|
||||
|
||||
load_none = [instr for instr in dis.get_instructions(f) if
|
||||
instr.opname == 'LOAD_CONST' and instr.argval is None]
|
||||
instr.opname in ('LOAD_CONST', 'LOAD_COMMON_CONSTANT')
|
||||
and instr.argval is None]
|
||||
return_value = [instr for instr in dis.get_instructions(f) if
|
||||
instr.opname == 'RETURN_VALUE']
|
||||
|
||||
|
||||
+53
-56
@@ -56,7 +56,7 @@ dis_c_instance_method = """\
|
||||
COMPARE_OP 72 (==)
|
||||
LOAD_FAST_BORROW 0 (self)
|
||||
STORE_ATTR 0 (x)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
""" % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,)
|
||||
|
||||
@@ -67,7 +67,7 @@ dis_c_instance_method_bytes = """\
|
||||
COMPARE_OP 72 (==)
|
||||
LOAD_FAST_BORROW 0
|
||||
STORE_ATTR 0
|
||||
LOAD_CONST 1
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -79,7 +79,7 @@ dis_c_class_method = """\
|
||||
COMPARE_OP 72 (==)
|
||||
LOAD_FAST_BORROW 0 (cls)
|
||||
STORE_ATTR 0 (x)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
""" % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,)
|
||||
|
||||
@@ -90,7 +90,7 @@ dis_c_static_method = """\
|
||||
LOAD_SMALL_INT 1
|
||||
COMPARE_OP 72 (==)
|
||||
STORE_FAST 0 (x)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
""" % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,)
|
||||
|
||||
@@ -182,7 +182,7 @@ dis_bug708901 = """\
|
||||
|
||||
%3d L2: END_FOR
|
||||
POP_ITER
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
""" % (bug708901.__code__.co_firstlineno,
|
||||
bug708901.__code__.co_firstlineno + 1,
|
||||
@@ -229,7 +229,7 @@ bug42562.__code__ = bug42562.__code__.replace(co_linetable=b'\xf8')
|
||||
|
||||
dis_bug42562 = """\
|
||||
RESUME 0
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -282,7 +282,7 @@ dis_kw_names = """\
|
||||
LOAD_CONST 1 (('c',))
|
||||
CALL_KW 3
|
||||
POP_TOP
|
||||
LOAD_CONST 2 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
""" % (wrap_func_w_kwargs.__code__.co_firstlineno,
|
||||
wrap_func_w_kwargs.__code__.co_firstlineno + 1)
|
||||
@@ -295,7 +295,7 @@ dis_intrinsic_1_2 = """\
|
||||
IMPORT_NAME 2 (math + eager)
|
||||
CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR)
|
||||
POP_TOP
|
||||
LOAD_CONST 2 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -322,7 +322,7 @@ _BIG_LINENO_FORMAT = """\
|
||||
|
||||
%3d LOAD_GLOBAL 0 (spam)
|
||||
POP_TOP
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -331,19 +331,19 @@ _BIG_LINENO_FORMAT2 = """\
|
||||
|
||||
%4d LOAD_GLOBAL 0 (spam)
|
||||
POP_TOP
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
dis_module_expected_results = """\
|
||||
Disassembly of f:
|
||||
4 RESUME 0
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
Disassembly of g:
|
||||
5 RESUME 0
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
"""
|
||||
@@ -368,7 +368,7 @@ dis_simple_stmt_str = """\
|
||||
LOAD_SMALL_INT 1
|
||||
BINARY_OP 0 (+)
|
||||
STORE_NAME 0 (x)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -409,7 +409,7 @@ dis_annot_stmt_str = """\
|
||||
LOAD_SMALL_INT 0
|
||||
CALL 1
|
||||
STORE_SUBSCR
|
||||
LOAD_CONST 2 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -427,7 +427,7 @@ dis_fn_with_annotate_str = """\
|
||||
MAKE_FUNCTION
|
||||
SET_FUNCTION_ATTRIBUTE 16 (annotate)
|
||||
STORE_NAME 0 (foo)
|
||||
LOAD_CONST 2 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""
|
||||
|
||||
@@ -477,14 +477,14 @@ dis_traceback = """\
|
||||
LOAD_ATTR 2 (__traceback__)
|
||||
STORE_FAST 1 (tb)
|
||||
L7: POP_EXCEPT
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
STORE_FAST 0 (e)
|
||||
DELETE_FAST 0 (e)
|
||||
|
||||
%4d LOAD_FAST 1 (tb)
|
||||
RETURN_VALUE
|
||||
|
||||
-- L8: LOAD_CONST 1 (None)
|
||||
-- L8: LOAD_COMMON_CONSTANT 7 (None)
|
||||
STORE_FAST 0 (e)
|
||||
DELETE_FAST 0 (e)
|
||||
RERAISE 1
|
||||
@@ -554,15 +554,15 @@ dis_with = """\
|
||||
%4d LOAD_SMALL_INT 1
|
||||
STORE_FAST 1 (x)
|
||||
|
||||
%4d L2: LOAD_CONST 1 (None)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_CONST 1 (None)
|
||||
%4d L2: LOAD_COMMON_CONSTANT 7 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
CALL 3
|
||||
POP_TOP
|
||||
|
||||
%4d LOAD_SMALL_INT 2
|
||||
STORE_FAST 2 (y)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
%4d L3: PUSH_EXC_INFO
|
||||
@@ -579,7 +579,7 @@ dis_with = """\
|
||||
|
||||
%4d LOAD_SMALL_INT 2
|
||||
STORE_FAST 2 (y)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
-- L8: COPY 3
|
||||
@@ -617,7 +617,7 @@ dis_asyncwith = """\
|
||||
CALL 0
|
||||
GET_AWAITABLE 1
|
||||
PUSH_NULL
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
L2: SEND 4 (to L5)
|
||||
L3: YIELD_VALUE 1
|
||||
L4: RESUME 3
|
||||
@@ -628,13 +628,13 @@ dis_asyncwith = """\
|
||||
%4d LOAD_SMALL_INT 1
|
||||
STORE_FAST 1 (x)
|
||||
|
||||
%4d L7: LOAD_CONST 0 (None)
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_CONST 0 (None)
|
||||
%4d L7: LOAD_COMMON_CONSTANT 7 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
CALL 3
|
||||
GET_AWAITABLE 2
|
||||
PUSH_NULL
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
L8: SEND 4 (to L11)
|
||||
L9: YIELD_VALUE 1
|
||||
L10: RESUME 3
|
||||
@@ -644,7 +644,7 @@ dis_asyncwith = """\
|
||||
|
||||
%4d LOAD_SMALL_INT 2
|
||||
STORE_FAST 2 (y)
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
%4d L12: CLEANUP_THROW
|
||||
@@ -655,7 +655,7 @@ dis_asyncwith = """\
|
||||
WITH_EXCEPT_START
|
||||
GET_AWAITABLE 2
|
||||
PUSH_NULL
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
L17: SEND 5 (to L21)
|
||||
L18: YIELD_VALUE 1
|
||||
L19: RESUME 3
|
||||
@@ -674,7 +674,7 @@ dis_asyncwith = """\
|
||||
|
||||
%4d LOAD_SMALL_INT 2
|
||||
STORE_FAST 2 (y)
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
-- L26: COPY 3
|
||||
@@ -895,7 +895,7 @@ Disassembly of <code object <genexpr> at 0x..., file "%s", line %d>:
|
||||
JUMP_BACKWARD 17 (to L2)
|
||||
L3: END_FOR
|
||||
POP_ITER
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
|
||||
-- L4: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR)
|
||||
@@ -933,7 +933,7 @@ dis_loop_test_quickened_code = """\
|
||||
%3d RESUME_CHECK{: <6} 0
|
||||
|
||||
%3d BUILD_LIST 0
|
||||
LOAD_CONST 2 ((1, 2, 3))
|
||||
LOAD_CONST 1 ((1, 2, 3))
|
||||
LIST_EXTEND 1
|
||||
LOAD_SMALL_INT 3
|
||||
BINARY_OP 5 (*)
|
||||
@@ -949,7 +949,7 @@ dis_loop_test_quickened_code = """\
|
||||
|
||||
%3d L2: END_FOR
|
||||
POP_ITER
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
""" % (loop_test.__code__.co_firstlineno,
|
||||
loop_test.__code__.co_firstlineno + 1,
|
||||
@@ -967,7 +967,7 @@ dis_extended_arg_quick_code = """\
|
||||
UNPACK_EX 256
|
||||
POP_TOP
|
||||
STORE_FAST 0 (_)
|
||||
LOAD_CONST 1 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
"""% (extended_arg_quick.__code__.co_firstlineno,
|
||||
extended_arg_quick.__code__.co_firstlineno + 1,)
|
||||
@@ -1084,7 +1084,7 @@ class DisTests(DisTestBase):
|
||||
'',
|
||||
'2:3-3:15 NOP',
|
||||
'',
|
||||
'3:11-3:15 LOAD_CONST 0 (None)',
|
||||
'3:11-3:15 LOAD_COMMON_CONSTANT 7 (None)',
|
||||
'3:11-3:15 RETURN_VALUE',
|
||||
'',
|
||||
' -- L1: PUSH_EXC_INFO',
|
||||
@@ -1115,7 +1115,7 @@ class DisTests(DisTestBase):
|
||||
'',
|
||||
'2:5-2:6 LOAD_SMALL_INT 1',
|
||||
'2:?-2:? STORE_FAST 0 (x)',
|
||||
'2:?-2:? LOAD_CONST 1 (None)',
|
||||
'2:?-2:? LOAD_COMMON_CONSTANT 7 (None)',
|
||||
'2:?-2:? RETURN_VALUE',
|
||||
'',
|
||||
])
|
||||
@@ -1128,7 +1128,7 @@ class DisTests(DisTestBase):
|
||||
f.__code__ = f.__code__.replace(co_linetable=b'')
|
||||
expect = '\n'.join([
|
||||
' RESUME 0',
|
||||
' LOAD_CONST 0 (None)',
|
||||
' LOAD_COMMON_CONSTANT 7 (None)',
|
||||
' RETURN_VALUE',
|
||||
'',
|
||||
])
|
||||
@@ -1533,7 +1533,6 @@ Stack size: \\d+
|
||||
Flags: OPTIMIZED, NEWLOCALS, VARARGS, VARKEYWORDS, GENERATOR
|
||||
Constants:
|
||||
0: <code object f at (.*), file "(.*)", line (.*)>
|
||||
1: None
|
||||
Variable names:
|
||||
0: a
|
||||
1: b
|
||||
@@ -1605,7 +1604,6 @@ Stack size: \\d+
|
||||
Flags: 0x0
|
||||
Constants:
|
||||
0: 1
|
||||
1: None
|
||||
Names:
|
||||
0: x"""
|
||||
|
||||
@@ -1640,7 +1638,6 @@ Stack size: \\d+
|
||||
Flags: OPTIMIZED, NEWLOCALS, COROUTINE
|
||||
Constants:
|
||||
0: 1
|
||||
1: None
|
||||
Names:
|
||||
0: b
|
||||
1: c
|
||||
@@ -1790,7 +1787,7 @@ expected_opinfo_outer = [
|
||||
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, cache_info=[('counter', 1, b'\x00\x00')]),
|
||||
make_inst(opname='LOAD_CONST', arg=4, argval=(3, 4), argrepr='(3, 4)', offset=8, start_offset=8, starts_line=True, line_number=2),
|
||||
make_inst(opname='LOAD_CONST', arg=3, argval=(3, 4), argrepr='(3, 4)', offset=8, start_offset=8, starts_line=True, line_number=2),
|
||||
make_inst(opname='LOAD_FAST_BORROW', arg=0, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=2),
|
||||
make_inst(opname='LOAD_FAST_BORROW', arg=1, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=2),
|
||||
make_inst(opname='BUILD_TUPLE', arg=2, argval=2, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=2),
|
||||
@@ -1802,11 +1799,11 @@ expected_opinfo_outer = [
|
||||
make_inst(opname='LOAD_GLOBAL', arg=1, argval='print', argrepr='print + NULL', offset=26, start_offset=26, 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=36, start_offset=36, starts_line=False, line_number=7),
|
||||
make_inst(opname='LOAD_DEREF', arg=1, argval='b', argrepr='b', offset=38, start_offset=38, starts_line=False, line_number=7),
|
||||
make_inst(opname='LOAD_CONST', arg=2, argval='', argrepr="''", offset=40, start_offset=40, starts_line=False, line_number=7),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=8, argval='', argrepr="''", offset=40, start_offset=40, starts_line=False, line_number=7),
|
||||
make_inst(opname='LOAD_SMALL_INT', arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7),
|
||||
make_inst(opname='BUILD_LIST', arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7),
|
||||
make_inst(opname='BUILD_MAP', arg=0, argval=0, argrepr='', 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=48, start_offset=48, starts_line=False, line_number=7),
|
||||
make_inst(opname='LOAD_CONST', arg=2, argval='Hello world!', argrepr="'Hello world!'", offset=48, start_offset=48, starts_line=False, line_number=7),
|
||||
make_inst(opname='CALL', arg=7, argval=7, argrepr='', offset=50, start_offset=50, 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=58, start_offset=58, starts_line=False, line_number=7),
|
||||
make_inst(opname='LOAD_FAST_BORROW', arg=2, argval='f', argrepr='f', offset=60, start_offset=60, starts_line=True, line_number=8),
|
||||
@@ -1851,7 +1848,7 @@ expected_opinfo_inner = [
|
||||
make_inst(opname='LOAD_FAST_BORROW_LOAD_FAST_BORROW', arg=1, argval=('e', 'f'), argrepr='e, f', offset=24, start_offset=24, starts_line=False, line_number=4),
|
||||
make_inst(opname='CALL', arg=6, argval=6, argrepr='', offset=26, start_offset=26, starts_line=False, line_number=4, 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=34, start_offset=34, starts_line=False, line_number=4),
|
||||
make_inst(opname='LOAD_CONST', arg=0, argval=None, argrepr='None', offset=36, start_offset=36, starts_line=False, line_number=4),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=7, argval=None, argrepr='None', offset=36, start_offset=36, starts_line=False, line_number=4),
|
||||
make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=38, start_offset=38, starts_line=False, line_number=4),
|
||||
]
|
||||
|
||||
@@ -1934,16 +1931,16 @@ expected_opinfo_jumpy = [
|
||||
make_inst(opname='LOAD_CONST', arg=3, argval='Never reach this', argrepr="'Never reach this'", offset=292, start_offset=292, starts_line=False, line_number=26),
|
||||
make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=294, start_offset=294, 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=302, start_offset=302, starts_line=False, line_number=26),
|
||||
make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=304, start_offset=304, starts_line=True, line_number=25),
|
||||
make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=25),
|
||||
make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=308, start_offset=308, starts_line=False, line_number=25),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=7, argval=None, argrepr='None', offset=304, start_offset=304, starts_line=True, line_number=25),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=7, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=25),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=7, argval=None, argrepr='None', offset=308, start_offset=308, starts_line=False, line_number=25),
|
||||
make_inst(opname='CALL', arg=3, argval=3, argrepr='', offset=310, start_offset=310, 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=318, start_offset=318, starts_line=False, line_number=25),
|
||||
make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=320, start_offset=320, 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=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=330, start_offset=330, starts_line=False, line_number=28),
|
||||
make_inst(opname='LOAD_CONST', arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=330, start_offset=330, starts_line=False, line_number=28),
|
||||
make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=332, start_offset=332, 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=340, start_offset=340, starts_line=False, line_number=28),
|
||||
make_inst(opname='LOAD_CONST', arg=4, argval=None, argrepr='None', offset=342, start_offset=342, starts_line=False, line_number=28),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=7, argval=None, argrepr='None', offset=342, start_offset=342, starts_line=False, line_number=28),
|
||||
make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=28),
|
||||
make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=True, line_number=25),
|
||||
make_inst(opname='WITH_EXCEPT_START', arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=25),
|
||||
@@ -1967,7 +1964,7 @@ expected_opinfo_jumpy = [
|
||||
make_inst(opname='NOT_TAKEN', arg=None, argval=None, argrepr='', offset=402, start_offset=402, starts_line=False, line_number=22),
|
||||
make_inst(opname='POP_TOP', arg=None, argval=None, argrepr='', offset=404, start_offset=404, starts_line=False, line_number=22),
|
||||
make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=406, start_offset=406, 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=5, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=416, start_offset=416, starts_line=False, line_number=23),
|
||||
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=416, start_offset=416, starts_line=False, line_number=23),
|
||||
make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=418, start_offset=418, 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=426, start_offset=426, starts_line=False, line_number=23),
|
||||
make_inst(opname='POP_EXCEPT', arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=23),
|
||||
@@ -1978,7 +1975,7 @@ expected_opinfo_jumpy = [
|
||||
make_inst(opname='RERAISE', arg=1, argval=1, argrepr='', offset=438, start_offset=438, starts_line=False, line_number=None),
|
||||
make_inst(opname='PUSH_EXC_INFO', arg=None, argval=None, argrepr='', offset=440, start_offset=440, starts_line=False, line_number=None),
|
||||
make_inst(opname='LOAD_GLOBAL', arg=3, argval='print', argrepr='print + NULL', offset=442, start_offset=442, 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=6, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=452, start_offset=452, starts_line=False, line_number=28),
|
||||
make_inst(opname='LOAD_CONST', arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=452, start_offset=452, starts_line=False, line_number=28),
|
||||
make_inst(opname='CALL', arg=1, argval=1, argrepr='', offset=454, start_offset=454, 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=462, start_offset=462, starts_line=False, line_number=28),
|
||||
make_inst(opname='RERAISE', arg=0, argval=0, argrepr='', offset=464, start_offset=464, starts_line=False, line_number=28),
|
||||
@@ -1991,7 +1988,7 @@ expected_opinfo_jumpy = [
|
||||
def simple(): pass
|
||||
expected_opinfo_simple = [
|
||||
make_inst(opname='RESUME', arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno),
|
||||
make_inst(opname='LOAD_CONST', arg=0, argval=None, argrepr='None', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno),
|
||||
make_inst(opname='LOAD_COMMON_CONSTANT', arg=7, argval=None, argrepr='None', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno),
|
||||
make_inst(opname='RETURN_VALUE', arg=None, argval=None, argrepr='', offset=6, start_offset=6, starts_line=False, line_number=simple.__code__.co_firstlineno),
|
||||
]
|
||||
|
||||
@@ -2600,7 +2597,7 @@ class TestDisCLI(unittest.TestCase):
|
||||
CACHE 0 (func_version: 0)
|
||||
CACHE 0
|
||||
POP_TOP
|
||||
LOAD_CONST 0 (None)
|
||||
LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
'''
|
||||
for flag in ['-C', '--show-caches']:
|
||||
@@ -2612,7 +2609,7 @@ class TestDisCLI(unittest.TestCase):
|
||||
expect = '''
|
||||
0 0 RESUME 0
|
||||
|
||||
1 4 LOAD_CONST 0 (None)
|
||||
1 4 LOAD_COMMON_CONSTANT 7 (None)
|
||||
6 RETURN_VALUE
|
||||
'''
|
||||
for flag in ['-O', '--show-offsets']:
|
||||
@@ -2624,7 +2621,7 @@ class TestDisCLI(unittest.TestCase):
|
||||
expect = '''
|
||||
0:0-1:0 RESUME 0
|
||||
|
||||
1:0-1:4 LOAD_CONST 0 (None)
|
||||
1:0-1:4 LOAD_COMMON_CONSTANT 7 (None)
|
||||
1:0-1:4 RETURN_VALUE
|
||||
'''
|
||||
for flag in ['-P', '--show-positions']:
|
||||
@@ -2636,7 +2633,7 @@ class TestDisCLI(unittest.TestCase):
|
||||
expect = '''
|
||||
0 RESUME 0
|
||||
|
||||
1 LOAD_CONST 0 (None)
|
||||
1 LOAD_COMMON_CONSTANT 7 (None)
|
||||
RETURN_VALUE
|
||||
'''
|
||||
for flag in ['-S', '--specialized']:
|
||||
|
||||
+114
-35
@@ -106,7 +106,7 @@ class TestTranforms(BytecodeTestCase):
|
||||
self.check_lnotab(code)
|
||||
|
||||
def test_global_as_constant(self):
|
||||
# LOAD_GLOBAL None/True/False --> LOAD_CONST None/True/False
|
||||
# LOAD_GLOBAL None/True/False --> LOAD_COMMON_CONSTANT None/True/False
|
||||
def f():
|
||||
x = None
|
||||
x = None
|
||||
@@ -121,7 +121,7 @@ class TestTranforms(BytecodeTestCase):
|
||||
for func, elem in ((f, None), (g, True), (h, False)):
|
||||
with self.subTest(func=func):
|
||||
self.assertNotInBytecode(func, 'LOAD_GLOBAL')
|
||||
self.assertInBytecode(func, 'LOAD_CONST', elem)
|
||||
self.assertInBytecode(func, 'LOAD_COMMON_CONSTANT', elem)
|
||||
self.check_lnotab(func)
|
||||
|
||||
def f():
|
||||
@@ -129,7 +129,7 @@ class TestTranforms(BytecodeTestCase):
|
||||
return None
|
||||
|
||||
self.assertNotInBytecode(f, 'LOAD_GLOBAL')
|
||||
self.assertInBytecode(f, 'LOAD_CONST', None)
|
||||
self.assertInBytecode(f, 'LOAD_COMMON_CONSTANT', None)
|
||||
self.check_lnotab(f)
|
||||
|
||||
def test_while_one(self):
|
||||
@@ -146,13 +146,14 @@ class TestTranforms(BytecodeTestCase):
|
||||
|
||||
def test_pack_unpack(self):
|
||||
for line, elem in (
|
||||
('a, = a,', 'LOAD_CONST',),
|
||||
('a, = a,', None),
|
||||
('a, b = a, b', 'SWAP',),
|
||||
('a, b, c = a, b, c', 'SWAP',),
|
||||
):
|
||||
with self.subTest(line=line):
|
||||
code = compile(line,'','single')
|
||||
self.assertInBytecode(code, elem)
|
||||
if elem is not None:
|
||||
self.assertInBytecode(code, elem)
|
||||
self.assertNotInBytecode(code, 'BUILD_TUPLE')
|
||||
self.assertNotInBytecode(code, 'UNPACK_SEQUENCE')
|
||||
self.check_lnotab(code)
|
||||
@@ -174,10 +175,10 @@ class TestTranforms(BytecodeTestCase):
|
||||
# Long tuples should be folded too.
|
||||
code = compile(repr(tuple(range(10000))),'','single')
|
||||
self.assertNotInBytecode(code, 'BUILD_TUPLE')
|
||||
# One LOAD_CONST for the tuple, one for the None return value
|
||||
# One LOAD_CONST for the tuple; None return value uses LOAD_COMMON_CONSTANT
|
||||
load_consts = [instr for instr in dis.get_instructions(code)
|
||||
if instr.opname == 'LOAD_CONST']
|
||||
self.assertEqual(len(load_consts), 2)
|
||||
self.assertEqual(len(load_consts), 1)
|
||||
self.check_lnotab(code)
|
||||
|
||||
# Bug 1053819: Tuple of constants misidentified when presented with:
|
||||
@@ -283,11 +284,11 @@ class TestTranforms(BytecodeTestCase):
|
||||
('-0.0', 'UNARY_NEGATIVE', None, True, 'LOAD_CONST', -0.0),
|
||||
('-(1.0-1.0)', 'UNARY_NEGATIVE', None, True, 'LOAD_CONST', -0.0),
|
||||
('-0.5', 'UNARY_NEGATIVE', None, True, 'LOAD_CONST', -0.5),
|
||||
('---1', 'UNARY_NEGATIVE', None, True, 'LOAD_CONST', -1),
|
||||
('---1', 'UNARY_NEGATIVE', None, True, 'LOAD_COMMON_CONSTANT', -1),
|
||||
('---""', 'UNARY_NEGATIVE', None, False, None, None),
|
||||
('~~~1', 'UNARY_INVERT', None, True, 'LOAD_CONST', -2),
|
||||
('~~~""', 'UNARY_INVERT', None, False, None, None),
|
||||
('not not True', 'UNARY_NOT', None, True, 'LOAD_CONST', True),
|
||||
('not not True', 'UNARY_NOT', None, True, 'LOAD_COMMON_CONSTANT', True),
|
||||
('not not x', 'UNARY_NOT', None, True, 'LOAD_NAME', 'x'), # this should be optimized regardless of constant or not
|
||||
('+++1', 'CALL_INTRINSIC_1', intrinsic_positive, True, 'LOAD_SMALL_INT', 1),
|
||||
('---x', 'UNARY_NEGATIVE', None, False, None, None),
|
||||
@@ -326,7 +327,7 @@ class TestTranforms(BytecodeTestCase):
|
||||
('1 + 2', 'NB_ADD', True, 'LOAD_SMALL_INT', 3),
|
||||
('1 + 2 + 3', 'NB_ADD', True, 'LOAD_SMALL_INT', 6),
|
||||
('1 + ""', 'NB_ADD', False, None, None),
|
||||
('1 - 2', 'NB_SUBTRACT', True, 'LOAD_CONST', -1),
|
||||
('1 - 2', 'NB_SUBTRACT', True, 'LOAD_COMMON_CONSTANT', -1),
|
||||
('1 - 2 - 3', 'NB_SUBTRACT', True, 'LOAD_CONST', -4),
|
||||
('1 - ""', 'NB_SUBTRACT', False, None, None),
|
||||
('2 * 2', 'NB_MULTIPLY', True, 'LOAD_SMALL_INT', 4),
|
||||
@@ -1539,7 +1540,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
end,
|
||||
('END_FOR', None, 0),
|
||||
('POP_ITER', None, 0),
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[None], expected_consts=[None, (1, 2)])
|
||||
@@ -1572,7 +1573,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
end,
|
||||
('END_FOR', None, 0),
|
||||
('POP_ITER', None, 0),
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[None], expected_consts=[None])
|
||||
@@ -1604,7 +1605,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
end,
|
||||
('END_FOR', None, 0),
|
||||
('POP_ITER', None, 0),
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[None], expected_consts=[None, frozenset({1, 2})])
|
||||
@@ -1626,7 +1627,22 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('LOAD_CONST', 0, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(same, same, consts=[None], expected_consts=[None])
|
||||
expected = [
|
||||
('LOAD_SMALL_INT', 1, 0),
|
||||
('LOAD_NAME', 0, 0),
|
||||
('BUILD_SET', 2, 0),
|
||||
('GET_ITER', 0, 0),
|
||||
start := self.Label(),
|
||||
('FOR_ITER', end := self.Label(), 0),
|
||||
('STORE_FAST', 0, 0),
|
||||
('JUMP', start, 0),
|
||||
end,
|
||||
('END_FOR', None, 0),
|
||||
('POP_ITER', None, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(same, expected, consts=[None], expected_consts=[None])
|
||||
|
||||
def test_optimize_literal_list_contains(self):
|
||||
# x in [1, 2] ==> x in (1, 2)
|
||||
@@ -1645,7 +1661,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('LOAD_CONST', 1, 0),
|
||||
('CONTAINS_OP', 0, 0),
|
||||
('POP_TOP', None, 0),
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[None], expected_consts=[None, (1, 2)])
|
||||
@@ -1668,7 +1684,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('BUILD_TUPLE', 2, 0),
|
||||
('CONTAINS_OP', 0, 0),
|
||||
('POP_TOP', None, 0),
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[None], expected_consts=[None])
|
||||
@@ -1690,7 +1706,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('LOAD_CONST', 1, 0),
|
||||
('CONTAINS_OP', 0, 0),
|
||||
('POP_TOP', None, 0),
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[None], expected_consts=[None, frozenset({1, 2})])
|
||||
@@ -1707,7 +1723,17 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('LOAD_CONST', 0, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(same, same, consts=[None], expected_consts=[None])
|
||||
expected = [
|
||||
('LOAD_NAME', 0, 0),
|
||||
('LOAD_SMALL_INT', 1, 0),
|
||||
('LOAD_NAME', 1, 0),
|
||||
('BUILD_SET', 2, 0),
|
||||
('CONTAINS_OP', 0, 0),
|
||||
('POP_TOP', None, 0),
|
||||
('LOAD_COMMON_CONSTANT', 7, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(same, expected, consts=[None], expected_consts=[None])
|
||||
|
||||
def test_optimize_unary_not(self):
|
||||
# test folding
|
||||
@@ -1718,10 +1744,10 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
after = [
|
||||
('LOAD_CONST', 1, 0),
|
||||
('LOAD_COMMON_CONSTANT', 10, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[], expected_consts=[True, False])
|
||||
self.cfg_optimization_test(before, after, consts=[], expected_consts=[True])
|
||||
|
||||
# test cancel out
|
||||
before = [
|
||||
@@ -1769,7 +1795,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
after = [
|
||||
('LOAD_CONST', 0, 0),
|
||||
('LOAD_COMMON_CONSTANT', 9, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[], expected_consts=[True])
|
||||
@@ -1785,10 +1811,10 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
after = [
|
||||
('LOAD_CONST', 1, 0),
|
||||
('LOAD_COMMON_CONSTANT', 10, 0),
|
||||
('RETURN_VALUE', None, 0),
|
||||
]
|
||||
self.cfg_optimization_test(before, after, consts=[], expected_consts=[True, False])
|
||||
self.cfg_optimization_test(before, after, consts=[], expected_consts=[True])
|
||||
|
||||
# test cancel out & eliminate to bool (to bool stays as we are not iterating to a fixed point)
|
||||
before = [
|
||||
@@ -2430,7 +2456,7 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase):
|
||||
end,
|
||||
("END_FOR", None, 11),
|
||||
("POP_TOP", None, 12),
|
||||
("LOAD_CONST", 0, 13),
|
||||
("LOAD_COMMON_CONSTANT", 7, 13),
|
||||
("RETURN_VALUE", None, 14),
|
||||
]
|
||||
self.cfg_optimization_test(insts, expected_insts, consts=[None])
|
||||
@@ -2454,7 +2480,7 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
maxconst = max(maxconst, arg)
|
||||
consts = [None for _ in range(maxconst + 1)]
|
||||
return insts + [
|
||||
("LOAD_CONST", 0, last_loc + 1),
|
||||
("LOAD_COMMON_CONSTANT", 7, last_loc + 1),
|
||||
("RETURN_VALUE", None, last_loc + 2),
|
||||
], consts
|
||||
|
||||
@@ -2485,7 +2511,7 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
]
|
||||
expected = [
|
||||
("LOAD_FAST_BORROW", 0, 1),
|
||||
("LOAD_CONST", 1, 2),
|
||||
("LOAD_COMMON_CONSTANT", 7, 2),
|
||||
("SWAP", 2, 3),
|
||||
("POP_TOP", None, 4),
|
||||
]
|
||||
@@ -2523,7 +2549,13 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("STORE_FAST", 0, 3),
|
||||
("POP_TOP", None, 4),
|
||||
]
|
||||
self.check(insts, insts)
|
||||
expected = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
("LOAD_COMMON_CONSTANT", 7, 2),
|
||||
("STORE_FAST", 0, 3),
|
||||
("POP_TOP", None, 4),
|
||||
]
|
||||
self.check(insts, expected)
|
||||
|
||||
insts = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
@@ -2532,7 +2564,14 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("STORE_FAST_STORE_FAST", ((0 << 4) | 1), 4),
|
||||
("POP_TOP", None, 5),
|
||||
]
|
||||
self.check(insts, insts)
|
||||
expected = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
("LOAD_COMMON_CONSTANT", 7, 2),
|
||||
("LOAD_COMMON_CONSTANT", 7, 3),
|
||||
("STORE_FAST_STORE_FAST", ((0 << 4) | 1), 4),
|
||||
("POP_TOP", None, 5),
|
||||
]
|
||||
self.check(insts, expected)
|
||||
|
||||
insts = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
@@ -2553,7 +2592,12 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("LOAD_CONST", 0, 3),
|
||||
("STORE_FAST_STORE_FAST", ((0 << 4) | 1), 4),
|
||||
]
|
||||
self.check(insts, insts)
|
||||
expected = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
("LOAD_COMMON_CONSTANT", 7, 3),
|
||||
("STORE_FAST_STORE_FAST", ((0 << 4) | 1), 4),
|
||||
]
|
||||
self.check(insts, expected)
|
||||
|
||||
def test_consume_no_inputs(self):
|
||||
insts = [
|
||||
@@ -2598,7 +2642,19 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("LOAD_CONST", 0, 7),
|
||||
("RETURN_VALUE", None, 8),
|
||||
]
|
||||
self.cfg_optimization_test(insts, insts, consts=[None])
|
||||
expected = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
top := self.Label(),
|
||||
("FOR_ITER", end := self.Label(), 2),
|
||||
("STORE_FAST", 2, 3),
|
||||
("JUMP", top, 4),
|
||||
end,
|
||||
("END_FOR", None, 5),
|
||||
("POP_TOP", None, 6),
|
||||
("LOAD_COMMON_CONSTANT", 7, 7),
|
||||
("RETURN_VALUE", None, 8),
|
||||
]
|
||||
self.cfg_optimization_test(insts, expected, consts=[None])
|
||||
|
||||
def test_load_attr(self):
|
||||
insts = [
|
||||
@@ -2667,10 +2723,10 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("LOAD_FAST", 0, 1),
|
||||
("LOAD_FAST_BORROW", 1, 2),
|
||||
("SEND", end := self.Label(), 3),
|
||||
("LOAD_CONST", 0, 4),
|
||||
("LOAD_COMMON_CONSTANT", 7, 4),
|
||||
("RETURN_VALUE", None, 5),
|
||||
end,
|
||||
("LOAD_CONST", 0, 6),
|
||||
("LOAD_COMMON_CONSTANT", 7, 6),
|
||||
("RETURN_VALUE", None, 7)
|
||||
]
|
||||
self.cfg_optimization_test(insts, expected, consts=[None])
|
||||
@@ -2708,7 +2764,15 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("LOAD_CONST", 0, 5),
|
||||
("RETURN_VALUE", None, 6)
|
||||
]
|
||||
self.cfg_optimization_test(insts, insts, consts=[None])
|
||||
expected = [
|
||||
("LOAD_COMMON_CONSTANT", 7, 1),
|
||||
("LOAD_FAST", 0, 2),
|
||||
("SET_FUNCTION_ATTRIBUTE", 2, 3),
|
||||
("STORE_FAST", 1, 4),
|
||||
("LOAD_COMMON_CONSTANT", 7, 5),
|
||||
("RETURN_VALUE", None, 6)
|
||||
]
|
||||
self.cfg_optimization_test(insts, expected, consts=[None])
|
||||
|
||||
insts = [
|
||||
("LOAD_CONST", 0, 1),
|
||||
@@ -2717,7 +2781,7 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("RETURN_VALUE", None, 4)
|
||||
]
|
||||
expected = [
|
||||
("LOAD_CONST", 0, 1),
|
||||
("LOAD_COMMON_CONSTANT", 7, 1),
|
||||
("LOAD_FAST_BORROW", 0, 2),
|
||||
("SET_FUNCTION_ATTRIBUTE", 2, 3),
|
||||
("RETURN_VALUE", None, 4)
|
||||
@@ -2740,7 +2804,22 @@ class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
|
||||
("LOAD_CONST", 0, 11),
|
||||
("RETURN_VALUE", None, 12),
|
||||
]
|
||||
self.cfg_optimization_test(insts, insts, consts=[None])
|
||||
expected = [
|
||||
("LOAD_FAST", 0, 1),
|
||||
("GET_ITER", 1, 2),
|
||||
("PUSH_NULL", None, 3),
|
||||
("LOAD_COMMON_CONSTANT", 7, 4),
|
||||
send := self.Label(),
|
||||
("SEND", end := self.Label(), 6),
|
||||
("YIELD_VALUE", 1, 7),
|
||||
("RESUME", 2, 8),
|
||||
("JUMP", send, 9),
|
||||
end,
|
||||
("END_SEND", None, 10),
|
||||
("LOAD_COMMON_CONSTANT", 7, 11),
|
||||
("RETURN_VALUE", None, 12),
|
||||
]
|
||||
self.cfg_optimization_test(insts, expected, consts=[None])
|
||||
|
||||
def test_push_exc_info(self):
|
||||
insts = [
|
||||
|
||||
+16
-40
@@ -2128,10 +2128,6 @@ code_returns_only_none(PyCodeObject *co)
|
||||
int len = (int)Py_SIZE(co);
|
||||
assert(len > 0);
|
||||
|
||||
// The last instruction either returns or raises. We can take advantage
|
||||
// of that for a quick exit.
|
||||
_Py_CODEUNIT final = _Py_GetBaseCodeUnit(co, len-1);
|
||||
|
||||
// Look up None in co_consts.
|
||||
Py_ssize_t nconsts = PyTuple_Size(co->co_consts);
|
||||
int none_index = 0;
|
||||
@@ -2140,45 +2136,25 @@ code_returns_only_none(PyCodeObject *co)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (none_index == nconsts) {
|
||||
// None wasn't there, which means there was no implicit return,
|
||||
// "return", or "return None".
|
||||
|
||||
// That means there must be
|
||||
// an explicit return (non-None), or it only raises.
|
||||
if (IS_RETURN_OPCODE(final.op.code)) {
|
||||
// It was an explicit return (non-None).
|
||||
return 0;
|
||||
/* We don't worry about EXTENDED_ARG for now. */
|
||||
for (int i = 0; i < len; i += _PyInstruction_GetLength(co, i)) {
|
||||
_Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
|
||||
if (!IS_RETURN_OPCODE(inst.op.code)) {
|
||||
continue;
|
||||
}
|
||||
// It must end with a raise then. We still have to walk the
|
||||
// bytecode to see if there's any explicit return (non-None).
|
||||
assert(IS_RAISE_OPCODE(final.op.code));
|
||||
for (int i = 0; i < len; i += _PyInstruction_GetLength(co, i)) {
|
||||
_Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
|
||||
if (IS_RETURN_OPCODE(inst.op.code)) {
|
||||
// We alraedy know it isn't returning None.
|
||||
return 0;
|
||||
}
|
||||
assert(i != 0);
|
||||
_Py_CODEUNIT prev = _Py_GetBaseCodeUnit(co, i-1);
|
||||
if (prev.op.code == LOAD_COMMON_CONSTANT &&
|
||||
prev.op.arg == CONSTANT_NONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// It must only raise.
|
||||
}
|
||||
else {
|
||||
// Walk the bytecode, looking for RETURN_VALUE.
|
||||
for (int i = 0; i < len; i += _PyInstruction_GetLength(co, i)) {
|
||||
_Py_CODEUNIT inst = _Py_GetBaseCodeUnit(co, i);
|
||||
if (IS_RETURN_OPCODE(inst.op.code)) {
|
||||
assert(i != 0);
|
||||
// Ignore it if it returns None.
|
||||
_Py_CODEUNIT prev = _Py_GetBaseCodeUnit(co, i-1);
|
||||
if (prev.op.code == LOAD_CONST) {
|
||||
// We don't worry about EXTENDED_ARG for now.
|
||||
if (prev.op.arg == none_index) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (none_index < nconsts && prev.op.code == LOAD_CONST
|
||||
&& prev.op.arg == none_index)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Generated
+29
-29
@@ -2,38 +2,38 @@
|
||||
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,188,0,0,0,128,0,0,0,93,0,
|
||||
81,1,72,0,115,0,93,0,81,1,72,4,115,1,92,2,
|
||||
31,0,81,2,50,1,0,0,0,0,0,0,29,0,92,2,
|
||||
31,0,81,3,92,0,79,6,0,0,0,0,0,0,0,0,
|
||||
80,7,72,0,115,0,93,0,80,7,72,4,115,1,92,2,
|
||||
31,0,81,1,50,1,0,0,0,0,0,0,29,0,92,2,
|
||||
31,0,81,2,92,0,79,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,29,0,92,1,79,8,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,31,0,50,0,0,0,
|
||||
0,0,0,0,81,4,42,26,0,0,0,0,0,0,0,0,
|
||||
0,0,115,5,81,7,70,0,0,0,68,24,0,0,115,6,
|
||||
92,2,31,0,81,5,92,6,12,0,81,6,92,5,92,6,
|
||||
0,0,0,0,81,3,42,26,0,0,0,0,0,0,0,0,
|
||||
0,0,115,5,81,6,70,0,0,0,68,24,0,0,115,6,
|
||||
92,2,31,0,81,4,92,6,12,0,81,5,92,5,92,6,
|
||||
42,26,0,0,0,0,0,0,0,0,0,0,12,0,48,4,
|
||||
50,1,0,0,0,0,0,0,29,0,74,26,0,0,9,0,
|
||||
28,0,81,1,33,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,122,7,99,111,110,102,105,103,32,122,2,58,
|
||||
32,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,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,241,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,244,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,
|
||||
28,0,80,7,33,0,41,7,233,0,0,0,0,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,122,7,99,111,110,102,105,103,32,122,2,58,32,
|
||||
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,
|
||||
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,241,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,244,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,
|
||||
};
|
||||
|
||||
+71
-3
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "pycore_opcode_utils.h"
|
||||
#include "pycore_opcode_metadata.h" // OPCODE_HAS_ARG, etc
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -1125,6 +1126,8 @@ remove_redundant_nops(cfg_builder *g) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
static int loads_const(int opcode);
|
||||
|
||||
static int
|
||||
remove_redundant_nops_and_pairs(basicblock *entryblock)
|
||||
{
|
||||
@@ -1148,7 +1151,7 @@ remove_redundant_nops_and_pairs(basicblock *entryblock)
|
||||
int opcode = instr->i_opcode;
|
||||
bool is_redundant_pair = false;
|
||||
if (opcode == POP_TOP) {
|
||||
if (prev_opcode == LOAD_CONST || prev_opcode == LOAD_SMALL_INT) {
|
||||
if (loads_const(prev_opcode)) {
|
||||
is_redundant_pair = true;
|
||||
}
|
||||
else if (prev_opcode == COPY && prev_oparg == 1) {
|
||||
@@ -1300,7 +1303,9 @@ jump_thread(basicblock *bb, cfg_instr *inst, cfg_instr *target, int opcode)
|
||||
static int
|
||||
loads_const(int opcode)
|
||||
{
|
||||
return OPCODE_HAS_CONST(opcode) || opcode == LOAD_SMALL_INT;
|
||||
return OPCODE_HAS_CONST(opcode)
|
||||
|| opcode == LOAD_SMALL_INT
|
||||
|| opcode == LOAD_COMMON_CONSTANT;
|
||||
}
|
||||
|
||||
/* Returns new reference */
|
||||
@@ -1323,6 +1328,10 @@ get_const_value(int opcode, int oparg, PyObject *co_consts)
|
||||
if (opcode == LOAD_SMALL_INT) {
|
||||
return PyLong_FromLong(oparg);
|
||||
}
|
||||
if (opcode == LOAD_COMMON_CONSTANT) {
|
||||
assert(oparg < NUM_COMMON_CONSTANTS);
|
||||
return Py_NewRef(_PyInterpreterState_GET()->common_consts[oparg]);
|
||||
}
|
||||
|
||||
if (constant == NULL) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
@@ -1437,6 +1446,46 @@ maybe_instr_make_load_smallint(cfg_instr *instr, PyObject *newconst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Does not steal reference to "newconst".
|
||||
Return 1 if changed instruction to LOAD_COMMON_CONSTANT.
|
||||
Return 0 if could not change instruction to LOAD_COMMON_CONSTANT.
|
||||
Return -1 on error.
|
||||
*/
|
||||
static int
|
||||
maybe_instr_make_load_common_const(cfg_instr *instr, PyObject *newconst)
|
||||
{
|
||||
int oparg;
|
||||
if (newconst == Py_None) {
|
||||
oparg = CONSTANT_NONE;
|
||||
}
|
||||
else if (newconst == Py_True) {
|
||||
oparg = CONSTANT_TRUE;
|
||||
}
|
||||
else if (newconst == Py_False) {
|
||||
oparg = CONSTANT_FALSE;
|
||||
}
|
||||
else if (PyUnicode_CheckExact(newconst)
|
||||
&& PyUnicode_GET_LENGTH(newconst) == 0) {
|
||||
oparg = CONSTANT_EMPTY_STR;
|
||||
}
|
||||
else if (PyLong_CheckExact(newconst)) {
|
||||
int overflow;
|
||||
long val = PyLong_AsLongAndOverflow(newconst, &overflow);
|
||||
if (val == -1 && PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
if (overflow || val != -1) {
|
||||
return 0;
|
||||
}
|
||||
oparg = CONSTANT_MINUS_ONE;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
assert(_Py_IsImmortal(newconst));
|
||||
INSTR_SET_OP1(instr, LOAD_COMMON_CONSTANT, oparg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Steals reference to "newconst" */
|
||||
static int
|
||||
@@ -1452,6 +1501,14 @@ instr_make_load_const(cfg_instr *instr, PyObject *newconst,
|
||||
if (res > 0) {
|
||||
return SUCCESS;
|
||||
}
|
||||
res = maybe_instr_make_load_common_const(instr, newconst);
|
||||
if (res < 0) {
|
||||
Py_DECREF(newconst);
|
||||
return ERROR;
|
||||
}
|
||||
if (res > 0) {
|
||||
return SUCCESS;
|
||||
}
|
||||
int oparg = add_const(newconst, consts, const_cache, consts_index);
|
||||
RETURN_IF_ERROR(oparg);
|
||||
INSTR_SET_OP1(instr, LOAD_CONST, oparg);
|
||||
@@ -2208,7 +2265,7 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb,
|
||||
oparg = inst->i_oparg;
|
||||
}
|
||||
assert(!IS_ASSEMBLER_OPCODE(opcode));
|
||||
if (opcode != LOAD_CONST && opcode != LOAD_SMALL_INT) {
|
||||
if (!loads_const(opcode)) {
|
||||
continue;
|
||||
}
|
||||
int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
|
||||
@@ -2308,6 +2365,17 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inst->i_opcode == LOAD_CONST) {
|
||||
PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts);
|
||||
if (constant == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
int res = maybe_instr_make_load_common_const(inst, constant);
|
||||
Py_DECREF(constant);
|
||||
if (res < 0) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "Python.h"
|
||||
#include "pycore_long.h"
|
||||
#include "pycore_opcode_utils.h"
|
||||
#include "pycore_optimizer.h"
|
||||
#include "pycore_uops.h"
|
||||
#include "pycore_uop_ids.h"
|
||||
@@ -875,8 +877,14 @@ dummy_func(void) {
|
||||
op(_LOAD_COMMON_CONSTANT, (-- value)) {
|
||||
assert(oparg < NUM_COMMON_CONSTANTS);
|
||||
PyObject *val = _PyInterpreterState_GET()->common_consts[oparg];
|
||||
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
|
||||
value = PyJitRef_Borrow(sym_new_const(ctx, val));
|
||||
if (_Py_IsImmortal(val)) {
|
||||
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
|
||||
value = PyJitRef_Borrow(sym_new_const(ctx, val));
|
||||
}
|
||||
else {
|
||||
ADD_OP(_LOAD_CONST_INLINE, 0, (uintptr_t)val);
|
||||
value = sym_new_const(ctx, val);
|
||||
}
|
||||
}
|
||||
|
||||
op(_LOAD_SMALL_INT, (-- value)) {
|
||||
|
||||
Generated
+8
-2
@@ -1911,8 +1911,14 @@
|
||||
JitOptRef value;
|
||||
assert(oparg < NUM_COMMON_CONSTANTS);
|
||||
PyObject *val = _PyInterpreterState_GET()->common_consts[oparg];
|
||||
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
|
||||
value = PyJitRef_Borrow(sym_new_const(ctx, val));
|
||||
if (_Py_IsImmortal(val)) {
|
||||
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
|
||||
value = PyJitRef_Borrow(sym_new_const(ctx, val));
|
||||
}
|
||||
else {
|
||||
ADD_OP(_LOAD_CONST_INLINE, 0, (uintptr_t)val);
|
||||
value = sym_new_const(ctx, val);
|
||||
}
|
||||
CHECK_STACK_BOUNDS(1);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer += 1;
|
||||
|
||||
+11
-5
@@ -879,13 +879,19 @@ pycore_init_builtins(PyThreadState *tstate)
|
||||
|
||||
interp->common_consts[CONSTANT_ASSERTIONERROR] = PyExc_AssertionError;
|
||||
interp->common_consts[CONSTANT_NOTIMPLEMENTEDERROR] = PyExc_NotImplementedError;
|
||||
interp->common_consts[CONSTANT_BUILTIN_TUPLE] = (PyObject*)&PyTuple_Type;
|
||||
interp->common_consts[CONSTANT_BUILTIN_TUPLE] = (PyObject *)&PyTuple_Type;
|
||||
interp->common_consts[CONSTANT_BUILTIN_ALL] = all;
|
||||
interp->common_consts[CONSTANT_BUILTIN_ANY] = any;
|
||||
interp->common_consts[CONSTANT_BUILTIN_LIST] = (PyObject*)&PyList_Type;
|
||||
interp->common_consts[CONSTANT_BUILTIN_SET] = (PyObject*)&PySet_Type;
|
||||
|
||||
for (int i=0; i < NUM_COMMON_CONSTANTS; i++) {
|
||||
interp->common_consts[CONSTANT_BUILTIN_LIST] = (PyObject *)&PyList_Type;
|
||||
interp->common_consts[CONSTANT_BUILTIN_SET] = (PyObject *)&PySet_Type;
|
||||
interp->common_consts[CONSTANT_NONE] = Py_None;
|
||||
interp->common_consts[CONSTANT_EMPTY_STR] =
|
||||
Py_GetConstantBorrowed(Py_CONSTANT_EMPTY_STR);
|
||||
interp->common_consts[CONSTANT_TRUE] = Py_True;
|
||||
interp->common_consts[CONSTANT_FALSE] = Py_False;
|
||||
interp->common_consts[CONSTANT_MINUS_ONE] =
|
||||
(PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS - 1];
|
||||
for (int i = 0; i < NUM_COMMON_CONSTANTS; i++) {
|
||||
assert(interp->common_consts[i] != NULL);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user