]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-131798: Add `_IS_NONE` to the JIT optimizer (GH-148369)
authorWulian233 <1055917385@qq.com>
Sat, 11 Apr 2026 15:02:46 +0000 (23:02 +0800)
committerGitHub <noreply@github.com>
Sat, 11 Apr 2026 15:02:46 +0000 (23:02 +0800)
Lib/test/test_capi/test_opt.py
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h

index 6d8ad8798de5e2964c47e3490663e9c09879443f..f11413cc6254225987eebb611d876977cb6b6d77 100644 (file)
@@ -4662,6 +4662,24 @@ class TestUopsOptimization(unittest.TestCase):
         # 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():
index 9b1a69649978c73e1f99c124a367ef6d9366f8a7..c7fe34bf785c0b8b8564bbc5fb33ede6f12e24cb 100644 (file)
@@ -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;
index e5c67b6cf0e333c7756b61a6eb3126000d44081b..98287e7f84176133d3ecf23b9ebaff1169440b1c 100644 (file)
         /* _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;
         }