From 1fc22e48fba4330e66b568331f12846bc3dbfaac Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 11 Apr 2026 16:02:13 +0800 Subject: [PATCH 1/3] gh-131798: Add _IS_NONE to the JIT optimizer --- Lib/test/test_capi/test_opt.py | 18 ++++++++++++++++++ Python/optimizer_bytecodes.c | 14 ++++++++++++++ Python/optimizer_cases.c.h | 14 +++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 2a1abe178e5d84..eadda8271bfb6c 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -4554,6 +4554,24 @@ def return_true(): # v + 1 should be constant folded self.assertNotIn("_BINARY_OP", uops) + def test_is_none_narrows_to_constant(self): + def testfunc(n): + value = None + hits = 0 + for _ in range(n): + if value is None: + hits += 1 + return hits + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + + self.assertNotIn("_IS_NONE", uops) + self.assertIn("_GUARD_IS_NONE_POP", uops) + self.assertIn("_POP_TOP_NOP", uops) + def test_is_false_narrows_to_constant(self): def f(n): def return_false(): diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 0708fed6c5c803..5860e850c7a603 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -710,6 +710,20 @@ dummy_func(void) { r = right; } + op(_IS_NONE, (value -- b)) { + if (sym_is_const(ctx, value)) { + PyObject *value_o = sym_get_const(ctx, value); + assert(value_o != NULL); + b = sym_new_const(ctx, Py_IsNone(value_o) ? Py_True : Py_False); + } + else if (sym_has_type(value)) { + b = sym_new_const(ctx, sym_matches_type(value, &_PyNone_Type) ? Py_True : Py_False); + } + else { + b = sym_new_type(ctx, &PyBool_Type); + } + } + op(_CONTAINS_OP, (left, right -- b, l, r)) { b = sym_new_type(ctx, &PyBool_Type); l = left; diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 93b60f64e14ae1..1d0bf71849e039 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -3167,8 +3167,20 @@ /* _POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */ case _IS_NONE: { + JitOptRef value; JitOptRef b; - b = sym_new_not_null(ctx); + value = stack_pointer[-1]; + if (sym_is_const(ctx, value)) { + PyObject *value_o = sym_get_const(ctx, value); + assert(value_o != NULL); + b = sym_new_const(ctx, Py_IsNone(value_o) ? Py_True : Py_False); + } + else if (sym_has_type(value)) { + b = sym_new_const(ctx, sym_matches_type(value, &_PyNone_Type) ? Py_True : Py_False); + } + else { + b = sym_new_type(ctx, &PyBool_Type); + } stack_pointer[-1] = b; break; } From 321e5294e929ae4d4959a97a08021734e98ca3d5 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 11 Apr 2026 16:12:38 +0800 Subject: [PATCH 2/3] news --- .../2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst new file mode 100644 index 00000000000000..f038567e6d2a20 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst @@ -0,0 +1 @@ +Optimize ``_IS_NONE`` in JIT-compiled code. From 3d0058311d35f4de53cc08225b2a4412ab3269e9 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 11 Apr 2026 20:04:49 +0800 Subject: [PATCH 3/3] update --- .../2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst | 1 - Python/optimizer_bytecodes.c | 4 ---- Python/optimizer_cases.c.h | 4 ---- 3 files changed, 9 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst deleted file mode 100644 index f038567e6d2a20..00000000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-04-11-16-12-17.gh-issue-131798.be8mTq.rst +++ /dev/null @@ -1 +0,0 @@ -Optimize ``_IS_NONE`` in JIT-compiled code. diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 5860e850c7a603..b08b64f47c88d9 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -713,12 +713,8 @@ dummy_func(void) { op(_IS_NONE, (value -- b)) { if (sym_is_const(ctx, value)) { PyObject *value_o = sym_get_const(ctx, value); - assert(value_o != NULL); b = sym_new_const(ctx, Py_IsNone(value_o) ? Py_True : Py_False); } - else if (sym_has_type(value)) { - b = sym_new_const(ctx, sym_matches_type(value, &_PyNone_Type) ? Py_True : Py_False); - } else { b = sym_new_type(ctx, &PyBool_Type); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 1d0bf71849e039..4c6613e4e9fe5c 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -3172,12 +3172,8 @@ value = stack_pointer[-1]; if (sym_is_const(ctx, value)) { PyObject *value_o = sym_get_const(ctx, value); - assert(value_o != NULL); b = sym_new_const(ctx, Py_IsNone(value_o) ? Py_True : Py_False); } - else if (sym_has_type(value)) { - b = sym_new_const(ctx, sym_matches_type(value, &_PyNone_Type) ? Py_True : Py_False); - } else { b = sym_new_type(ctx, &PyBool_Type); }