https://github.com/python/cpython/commit/e998eb9a83b402f29bae06553424d1e42591cf4a
commit: e998eb9a83b402f29bae06553424d1e42591cf4a
branch: main
author: Neko Asakura <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-04-16T01:08:29+08:00
summary:
gh-148604: change `ADD_OP(_POP_TOP, ...)` to `optimize_pop_top` in
`optimizer_bytecodes.c` (GH-148619)
files:
M Lib/test/test_capi/test_opt.py
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index eb3c6458f834e8..efd00296896770 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -2642,6 +2642,9 @@ def testfunc(n):
uops = get_opnames(ex)
# When the result of type(...) is known, _CALL_TYPE_1 is decomposed.
self.assertNotIn("_CALL_TYPE_1", uops)
+ # _CALL_TYPE_1 produces 2 _POP_TOP_NOP (callable and null)
+ # type(42) is int produces 4 _POP_TOP_NOP
+ self.assertGreaterEqual(count_ops(ex, "_POP_TOP_NOP"), 6)
def test_call_type_1_result_is_const(self):
def testfunc(n):
@@ -3453,6 +3456,10 @@ def f(n):
self.assertEqual(res, TIER2_THRESHOLD)
uops = get_opnames(ex)
self.assertNotIn("_LOAD_SPECIAL", uops)
+ # __enter__/__exit__ produce 2 _POP_TOP_NOP
+ # x += 1 produces 2 _POP_TOP_NOP
+ # __exit__()'s None return produces 1 _POP_TOP_NOP
+ self.assertGreaterEqual(count_ops(ex, "_POP_TOP_NOP"), 5)
def test_store_fast_refcount_elimination(self):
def foo(x):
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index 7ffd835ad120c9..d0870a87aa1386 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -1480,13 +1480,13 @@ dummy_func(void) {
next = sym_new_type(ctx, &PyLong_Type);
}
- op(_CALL_TYPE_1, (unused, unused, arg -- res, a)) {
+ op(_CALL_TYPE_1, (callable, null, arg -- res, a)) {
PyObject* type = (PyObject *)sym_get_type(arg);
if (type) {
res = sym_new_const(ctx, type);
ADD_OP(_SWAP, 3, 0);
- ADD_OP(_POP_TOP, 0, 0);
- ADD_OP(_POP_TOP, 0, 0);
+ optimize_pop_top(ctx, this_instr, callable);
+ optimize_pop_top(ctx, this_instr, null);
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)type);
ADD_OP(_SWAP, 2, 0);
}
@@ -1509,7 +1509,7 @@ dummy_func(void) {
a = arg;
}
- op(_CALL_ISINSTANCE, (unused, unused, instance, cls -- res)) {
+ op(_CALL_ISINSTANCE, (callable, null, instance, cls -- res)) {
// the result is always a bool, but sometimes we can
// narrow it down to True or False
res = sym_new_type(ctx, &PyBool_Type);
@@ -1525,10 +1525,10 @@ dummy_func(void) {
out = Py_True;
}
sym_set_const(res, out);
- ADD_OP(_POP_TOP, 0, 0);
- ADD_OP(_POP_TOP, 0, 0);
- ADD_OP(_POP_TOP_NOP, 0, 0);
- ADD_OP(_POP_TOP, 0, 0);
+ optimize_pop_top(ctx, this_instr, cls);
+ optimize_pop_top(ctx, this_instr, instance);
+ optimize_pop_top(ctx, this_instr, null);
+ optimize_pop_top(ctx, this_instr, callable);
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)out);
}
}
@@ -1902,7 +1902,7 @@ dummy_func(void) {
ADD_OP(immortal ? _LOAD_CONST_INLINE_BORROW :
_LOAD_CONST_INLINE,
0, (uintptr_t)descr);
ADD_OP(_SWAP, 3, 0);
- ADD_OP(_POP_TOP, 0, 0);
+ optimize_pop_top(ctx, this_instr, method_and_self[0]);
if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
_Py_BloomFilter_Add(dependencies, type);
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index d2caa6fc7a7882..0cce6444c4e18b 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -3614,7 +3614,7 @@
ADD_OP(immortal ? _LOAD_CONST_INLINE_BORROW :
_LOAD_CONST_INLINE,
0, (uintptr_t)descr);
ADD_OP(_SWAP, 3, 0);
- ADD_OP(_POP_TOP, 0, 0);
+ optimize_pop_top(ctx, this_instr, method_and_self[0]);
if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) {
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
_Py_BloomFilter_Add(dependencies, type);
@@ -4035,15 +4035,19 @@
case _CALL_TYPE_1: {
JitOptRef arg;
+ JitOptRef null;
+ JitOptRef callable;
JitOptRef res;
JitOptRef a;
arg = stack_pointer[-1];
+ null = stack_pointer[-2];
+ callable = stack_pointer[-3];
PyObject* type = (PyObject *)sym_get_type(arg);
if (type) {
res = sym_new_const(ctx, type);
ADD_OP(_SWAP, 3, 0);
- ADD_OP(_POP_TOP, 0, 0);
- ADD_OP(_POP_TOP, 0, 0);
+ optimize_pop_top(ctx, this_instr, callable);
+ optimize_pop_top(ctx, this_instr, null);
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)type);
ADD_OP(_SWAP, 2, 0);
}
@@ -4404,9 +4408,13 @@
case _CALL_ISINSTANCE: {
JitOptRef cls;
JitOptRef instance;
+ JitOptRef null;
+ JitOptRef callable;
JitOptRef res;
cls = stack_pointer[-1];
instance = stack_pointer[-2];
+ null = stack_pointer[-3];
+ callable = stack_pointer[-4];
res = sym_new_type(ctx, &PyBool_Type);
PyTypeObject *inst_type = sym_get_type(instance);
PyTypeObject *cls_o = (PyTypeObject *)sym_get_const(ctx, cls);
@@ -4416,10 +4424,10 @@
out = Py_True;
}
sym_set_const(res, out);
- ADD_OP(_POP_TOP, 0, 0);
- ADD_OP(_POP_TOP, 0, 0);
- ADD_OP(_POP_TOP_NOP, 0, 0);
- ADD_OP(_POP_TOP, 0, 0);
+ optimize_pop_top(ctx, this_instr, cls);
+ optimize_pop_top(ctx, this_instr, instance);
+ optimize_pop_top(ctx, this_instr, null);
+ optimize_pop_top(ctx, this_instr, callable);
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)out);
}
CHECK_STACK_BOUNDS(-3);
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]