https://github.com/python/cpython/commit/a059e85866adb8ccd98d216b78428eb37fa70509
commit: a059e85866adb8ccd98d216b78428eb37fa70509
branch: main
author: Wulian233 <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-04-11T23:02:46+08:00
summary:

gh-131798: Add `_IS_NONE` to the JIT optimizer (GH-148369)

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 6d8ad8798de5e2..f11413cc625422 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -4662,6 +4662,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 9b1a69649978c7..c7fe34bf785c0b 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -724,6 +724,16 @@ dummy_func(void) {
         r = right;
     }
 
+    op(_IS_NONE, (value -- b)) {
+        if (sym_is_const(ctx, value)) {
+            PyObject *value_o = sym_get_const(ctx, value);
+            b = sym_new_const(ctx, Py_IsNone(value_o) ? 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 e5c67b6cf0e333..98287e7f841761 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -3193,8 +3193,16 @@
         /* _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);
+                b = sym_new_const(ctx, Py_IsNone(value_o) ? Py_True : 
Py_False);
+            }
+            else {
+                b = sym_new_type(ctx, &PyBool_Type);
+            }
             stack_pointer[-1] = b;
             break;
         }

_______________________________________________
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]

Reply via email to