From f7cddcc2376668ccb1d1da25f1d68bb008cd6955 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Sun, 6 Apr 2025 13:15:00 +0200 Subject: [PATCH 1/3] Narrow the return type of _BINARY_OP_SUBSCR_STR_INT --- Lib/test/test_capi/test_opt.py | 21 +++++++++++++++++++++ Python/optimizer_bytecodes.c | 4 ++++ Python/optimizer_cases.c.h | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 0e13799ad47381..f309a4501db1c6 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1646,6 +1646,27 @@ def f(n): self.assertIn("_TO_BOOL_STR", uops) self.assertNotIn("_GUARD_TOS_UNICODE", uops) + def test_binary_subcsr_str_int_narrows_to_str(self): + def testfunc(n): + x = 0 + s = "foo" + z = "" + for _ in range(n): + y = s[0] # _BINARY_OP_SUBSCR_STR_INT + z = "bar" + y # (_GUARD_TOS_UNICODE) + _BINARY_OP_ADD_UNICODE + x += 1 + return x + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertIn("_BINARY_OP_SUBSCR_STR_INT", uops) + # _BINARY_OP_SUBSCR_STR_INT narrows the result to 'str' so + # the unicode guard before _BINARY_OP_ADD_UNICODE is removed. + self.assertNotIn("_GUARD_TOS_UNICODE", uops) + self.assertIn("_BINARY_OP_ADD_UNICODE", uops) + def global_identity(x): return x diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index d7b3564db1b90a..72dc2bbd44e71c 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -366,6 +366,10 @@ dummy_func(void) { ctx->done = true; } + op(_BINARY_OP_SUBSCR_STR_INT, (left, right -- res)) { + res = sym_new_type(ctx, &PyUnicode_Type); + } + op(_TO_BOOL, (value -- res)) { int already_bool = optimize_to_bool(this_instr, ctx, value, &res); if (!already_bool) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 870c32d74ac913..160d09ca7c5580 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -569,7 +569,7 @@ case _BINARY_OP_SUBSCR_STR_INT: { JitOptSymbol *res; - res = sym_new_not_null(ctx); + res = sym_new_type(ctx, &PyUnicode_Type); stack_pointer[-2] = res; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); From b821b8b05a5c5fd26dea0b67ab4149740dbb0c4b Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Sun, 6 Apr 2025 13:17:16 +0200 Subject: [PATCH 2/3] Add news entry --- .../2025-04-06-13-17-10.gh-issue-131798.uMrfha.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-04-06-13-17-10.gh-issue-131798.uMrfha.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-06-13-17-10.gh-issue-131798.uMrfha.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-06-13-17-10.gh-issue-131798.uMrfha.rst new file mode 100644 index 00000000000000..5ea5fcecc33517 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-06-13-17-10.gh-issue-131798.uMrfha.rst @@ -0,0 +1,2 @@ +Allow the JIT to remove unicode guards after ``_BINARY_OP_SUBSCR_STR_INT`` +by setting the return type to string. From f6eb00ccc2fc1ce8051e8cb65bef10e76f6111dc Mon Sep 17 00:00:00 2001 From: "Tomas R." Date: Tue, 8 Apr 2025 08:39:15 +0200 Subject: [PATCH 3/3] Improve test Co-authored-by: Brandt Bucher --- Lib/test/test_capi/test_opt.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index f309a4501db1c6..3ade7cb7a2b6af 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1648,17 +1648,16 @@ def f(n): def test_binary_subcsr_str_int_narrows_to_str(self): def testfunc(n): - x = 0 + x = [] s = "foo" - z = "" for _ in range(n): y = s[0] # _BINARY_OP_SUBSCR_STR_INT z = "bar" + y # (_GUARD_TOS_UNICODE) + _BINARY_OP_ADD_UNICODE - x += 1 + x.append(z) return x res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) - self.assertEqual(res, TIER2_THRESHOLD) + self.assertEqual(res, ["barf"] * TIER2_THRESHOLD) self.assertIsNotNone(ex) uops = get_opnames(ex) self.assertIn("_BINARY_OP_SUBSCR_STR_INT", uops)