From 9967aea6388025076b1ebb31a508d6a8216612fb Mon Sep 17 00:00:00 2001 From: fluhus Date: Wed, 7 May 2025 12:42:29 -0700 Subject: [PATCH 1/2] JIT: Assign type to sliced string --- Lib/test/test_capi/test_opt.py | 3 --- Python/optimizer_bytecodes.c | 12 ++++++++++++ Python/optimizer_cases.c.h | 9 ++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index ba7bcb4540a451..8f0f20020486b8 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -458,7 +458,6 @@ def _run_with_optimizer(self, testfunc, arg): ex = get_first_executor(testfunc) return res, ex - def test_int_type_propagation(self): def testfunc(loops): num = 0 @@ -1655,13 +1654,11 @@ def testfunc(n): self.assertIn("_CONTAINS_OP_DICT", uops) self.assertNotIn("_TO_BOOL_BOOL", uops) - def test_remove_guard_for_known_type_str(self): def f(n): for i in range(n): false = i == TIER2_THRESHOLD empty = "X"[:false] - empty += "" # Make JIT realize this is a string. if empty: return 1 return 0 diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index e99421a3aff4ba..882881a1f56ed6 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1096,6 +1096,18 @@ dummy_func(void) { sym_set_const(callable, len); } + op(_BINARY_SLICE, (container, start, stop -- res)) { + // Slicing a string always returns a string. + // TODO: We can apply this to lists and tuples as well. + // We'll start with string to simplify the process. + PyTypeObject *type = sym_get_type(container); + if (type == &PyUnicode_Type) { + res = sym_new_type(ctx, type); + } else { + res = sym_new_not_null(ctx); + } + } + // END BYTECODES // } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 56b4b9983fbaaa..f44d2515c6477f 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -568,8 +568,15 @@ } case _BINARY_SLICE: { + JitOptSymbol *container; JitOptSymbol *res; - res = sym_new_not_null(ctx); + container = stack_pointer[-3]; + PyTypeObject *type = sym_get_type(container); + if (type == &PyUnicode_Type) { + res = sym_new_type(ctx, type); + } else { + res = sym_new_not_null(ctx); + } stack_pointer[-3] = res; stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); From 7f64a64e6d2f3039dfd574c632400fba90cad585 Mon Sep 17 00:00:00 2001 From: fluhus Date: Wed, 7 May 2025 12:44:25 -0700 Subject: [PATCH 2/2] Revert accidental whitespace change --- Lib/test/test_capi/test_opt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 8f0f20020486b8..d5c03cde8fa7a3 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -458,6 +458,7 @@ def _run_with_optimizer(self, testfunc, arg): ex = get_first_executor(testfunc) return res, ex + def test_int_type_propagation(self): def testfunc(loops): num = 0