]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-130415: Narrow str to "" based on boolean tests (GH-130476)
authorAmit Lavon <amitlavon1.spam@gmail.com>
Tue, 4 Mar 2025 21:20:17 +0000 (13:20 -0800)
committerGitHub <noreply@github.com>
Tue, 4 Mar 2025 21:20:17 +0000 (13:20 -0800)
Lib/test/test_capi/test_opt.py
Misc/ACKS
Misc/NEWS.d/next/Core_and_Builtins/2025-02-22-22-49-00.gh-issue-130415.WyxBYS.rst [new file with mode: 0644]
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h
Python/optimizer_symbols.c

index a4faab2124b9c704bc829e086b6753ba3b6e0a80..c985009e1202031406dbc96bdb7cd1ebd27dfcf9 100644 (file)
@@ -1531,6 +1531,39 @@ class TestUopsOptimization(unittest.TestCase):
         # But all of the appends we care about are still there:
         self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))
 
+def test_narrow_type_to_constant_str_empty(self):
+        def f(n):
+            trace = []
+            for i in range(n):
+                # Hopefully the optimizer can't guess what the value is.
+                # empty is always "", but we can only prove that it's a string:
+                false = i == TIER2_THRESHOLD
+                empty = "X"[:false]
+                trace.append("A")
+                if not empty:  # Kept.
+                    trace.append("B")
+                    if not empty:  # Removed!
+                        trace.append("C")
+                    trace.append("D")
+                    if empty:  # Removed!
+                        trace.append("X")
+                    trace.append("E")
+                trace.append("F")
+                if empty:  # Removed!
+                    trace.append("X")
+                trace.append("G")
+            return trace
+
+        trace, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
+        self.assertEqual(trace, list("ABCDEFG") * TIER2_THRESHOLD)
+        self.assertIsNotNone(ex)
+        uops = get_opnames(ex)
+        # Only one guard remains:
+        self.assertEqual(uops.count("_GUARD_IS_FALSE_POP"), 1)
+        self.assertEqual(uops.count("_GUARD_IS_TRUE_POP"), 0)
+        # But all of the appends we care about are still there:
+        self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))
+
 def global_identity(x):
     return x
 
index 2526e78389dea213bec3724a79f6d4b38f99440a..d110002ffeb86ca8d010dbd540d6d0ef7d611d4d 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1065,6 +1065,7 @@ Keenan Lau
 Piers Lauder
 Ben Laurie
 Yoni Lavi
+Amit Lavon
 Simon Law
 Julia Lawall
 Chris Lawrence
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-22-22-49-00.gh-issue-130415.WyxBYS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-22-22-49-00.gh-issue-130415.WyxBYS.rst
new file mode 100644 (file)
index 0000000..2559aa8
--- /dev/null
@@ -0,0 +1 @@
+Improve JIT's ability to optimize strings in boolean contexts.
index 2aeed24a8c6c3249f542d257002bbc9f7e41010c..4bdef60dda9d53d7bc3d24b74c08260e5abdbfaa 100644 (file)
@@ -426,7 +426,7 @@ dummy_func(void) {
 
     op(_TO_BOOL_STR, (value -- res)) {
         if (!optimize_to_bool(this_instr, ctx, value, &res)) {
-            res = sym_new_type(ctx, &PyBool_Type);
+            res = sym_new_truthiness(ctx, value, true);
             sym_set_type(value, &PyUnicode_Type);
         }
     }
index 9555e141ed5c9febd42f499706f3de859b887265..306599bea778779ba8c13647bca7106a686a8e28 100644 (file)
             JitOptSymbol *res;
             value = stack_pointer[-1];
             if (!optimize_to_bool(this_instr, ctx, value, &res)) {
-                res = sym_new_type(ctx, &PyBool_Type);
+                res = sym_new_truthiness(ctx, value, true);
                 sym_set_type(value, &PyUnicode_Type);
             }
             stack_pointer[-1] = res;
index 28a2791f5e7de67d2d9f86045c14d851f9aa9279..5adc1c8a62ce8bc0bc3b5fd31bc1e786be40eb94 100644 (file)
@@ -302,6 +302,9 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val
             else if (type == &PyLong_Type) {
                 _Py_uop_sym_set_const(ctx, value, Py_GetConstant(Py_CONSTANT_ZERO));
             }
+            else if (type == &PyUnicode_Type) {
+                _Py_uop_sym_set_const(ctx, value, Py_GetConstant(Py_CONSTANT_EMPTY_STR));
+            }
             // TODO: More types (GH-130415)!
             make_const(sym, const_val);
             return;