From c3cd21c861a8850c4f42f5e1fde8e634a3ce4a06 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Thu, 24 Apr 2025 22:56:29 +0200 Subject: [PATCH 1/4] Make _BINARY_OP_SUBSCR_TUPLE_INT smarter --- Lib/test/test_capi/test_opt.py | 17 +++++++++++++++++ Python/optimizer_bytecodes.c | 14 ++++++++++++++ Python/optimizer_cases.c.h | 16 +++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 0047306ae422db..7e0c60d5522402 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1923,6 +1923,23 @@ def testfunc(n): self.assertNotIn("_GUARD_TOS_INT", uops) self.assertIn("_CALL_LEN", uops) + def test_binary_op_subscr_tuple_int(self): + def testfunc(n): + x = 0 + for _ in range(n): + y = (1, 2) + if y[0] == 1: # _COMPARE_OP_INT + _GUARD_IS_TRUE_POP are removed + 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_TUPLE_INT", uops) + self.assertNotIn("_COMPARE_OP_INT", uops) + self.assertNotIn("_GUARD_IS_TRUE_POP", uops) + def global_identity(x): return x diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 040e54479b722a..7ef41c7aa811a6 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -370,6 +370,20 @@ dummy_func(void) { res = sym_new_type(ctx, &PyUnicode_Type); } + op(_BINARY_OP_SUBSCR_TUPLE_INT, (left, right -- res)) { + assert(sym_matches_type(left, &PyTuple_Type)); + if (sym_is_const(ctx, right)) { + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + long index = PyLong_AsLong(sym_get_const(ctx, right)); + assert(index >= 0); + assert(index < sym_tuple_length(left)); + res = sym_tuple_getitem(ctx, left, index); + } + else { + res = sym_new_not_null(ctx); + } + } + 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 9a5a362ec199a9..3ad68834032fd7 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -617,8 +617,22 @@ } case _BINARY_OP_SUBSCR_TUPLE_INT: { + JitOptSymbol *right; + JitOptSymbol *left; JitOptSymbol *res; - res = sym_new_not_null(ctx); + right = stack_pointer[-1]; + left = stack_pointer[-2]; + assert(sym_matches_type(left, &PyTuple_Type)); + if (sym_is_const(ctx, right)) { + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + long index = PyLong_AsLong(sym_get_const(ctx, right)); + assert(index >= 0); + assert(index < sym_tuple_length(left)); + res = sym_tuple_getitem(ctx, left, index); + } + else { + res = sym_new_not_null(ctx); + } stack_pointer[-2] = res; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); From c7b7b484ba31e0c9952ade35299183e72f2b2658 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Sat, 26 Apr 2025 13:59:30 +0200 Subject: [PATCH 2/4] Add news entry --- .../2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst new file mode 100644 index 00000000000000..f4049240f7d15c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-26-13-57-13.gh-issue-131798.Gt8CGE.rst @@ -0,0 +1,2 @@ +Propagate the return type of ``_BINARY_OP_SUBSCR_TUPLE_INT`` in JIT. Patch +by Tomas Roun From dddd56ff271e69215bea67516a88d3dfe99b5db7 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Sat, 26 Apr 2025 20:11:43 +0200 Subject: [PATCH 3/4] Fix a case when the tuple length is not known --- Python/optimizer_bytecodes.c | 11 +++++++++-- Python/optimizer_cases.c.h | 10 ++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 7ef41c7aa811a6..8ae1e4dd65445a 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -376,8 +376,15 @@ dummy_func(void) { assert(PyLong_CheckExact(sym_get_const(ctx, right))); long index = PyLong_AsLong(sym_get_const(ctx, right)); assert(index >= 0); - assert(index < sym_tuple_length(left)); - res = sym_tuple_getitem(ctx, left, index); + int tuple_length = sym_tuple_length(left); + if (tuple_length == -1) { + // Unknown length + res = sym_new_not_null(ctx); + } + else { + assert(index < tuple_length); + res = sym_tuple_getitem(ctx, left, index); + } } else { res = sym_new_not_null(ctx); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 3ad68834032fd7..5138fe2903e82a 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -627,8 +627,14 @@ assert(PyLong_CheckExact(sym_get_const(ctx, right))); long index = PyLong_AsLong(sym_get_const(ctx, right)); assert(index >= 0); - assert(index < sym_tuple_length(left)); - res = sym_tuple_getitem(ctx, left, index); + int tuple_length = sym_tuple_length(left); + if (tuple_length == -1) { + res = sym_new_not_null(ctx); + } + else { + assert(index < tuple_length); + res = sym_tuple_getitem(ctx, left, index); + } } else { res = sym_new_not_null(ctx); From 00b00cbfe82d95ec15ad0945c83a3553646538a0 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Sat, 26 Apr 2025 20:13:19 +0200 Subject: [PATCH 4/4] Keep the same names for stack variables --- Python/optimizer_bytecodes.c | 14 +++++++------- Python/optimizer_cases.c.h | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 8ae1e4dd65445a..f862c9c8c6a840 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -370,20 +370,20 @@ dummy_func(void) { res = sym_new_type(ctx, &PyUnicode_Type); } - op(_BINARY_OP_SUBSCR_TUPLE_INT, (left, right -- res)) { - assert(sym_matches_type(left, &PyTuple_Type)); - if (sym_is_const(ctx, right)) { - assert(PyLong_CheckExact(sym_get_const(ctx, right))); - long index = PyLong_AsLong(sym_get_const(ctx, right)); + op(_BINARY_OP_SUBSCR_TUPLE_INT, (tuple_st, sub_st -- res)) { + assert(sym_matches_type(tuple_st, &PyTuple_Type)); + if (sym_is_const(ctx, sub_st)) { + assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); + long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); assert(index >= 0); - int tuple_length = sym_tuple_length(left); + int tuple_length = sym_tuple_length(tuple_st); if (tuple_length == -1) { // Unknown length res = sym_new_not_null(ctx); } else { assert(index < tuple_length); - res = sym_tuple_getitem(ctx, left, index); + res = sym_tuple_getitem(ctx, tuple_st, index); } } else { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 5138fe2903e82a..c92b036eb56463 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -617,23 +617,23 @@ } case _BINARY_OP_SUBSCR_TUPLE_INT: { - JitOptSymbol *right; - JitOptSymbol *left; + JitOptSymbol *sub_st; + JitOptSymbol *tuple_st; JitOptSymbol *res; - right = stack_pointer[-1]; - left = stack_pointer[-2]; - assert(sym_matches_type(left, &PyTuple_Type)); - if (sym_is_const(ctx, right)) { - assert(PyLong_CheckExact(sym_get_const(ctx, right))); - long index = PyLong_AsLong(sym_get_const(ctx, right)); + sub_st = stack_pointer[-1]; + tuple_st = stack_pointer[-2]; + assert(sym_matches_type(tuple_st, &PyTuple_Type)); + if (sym_is_const(ctx, sub_st)) { + assert(PyLong_CheckExact(sym_get_const(ctx, sub_st))); + long index = PyLong_AsLong(sym_get_const(ctx, sub_st)); assert(index >= 0); - int tuple_length = sym_tuple_length(left); + int tuple_length = sym_tuple_length(tuple_st); if (tuple_length == -1) { res = sym_new_not_null(ctx); } else { assert(index < tuple_length); - res = sym_tuple_getitem(ctx, left, index); + res = sym_tuple_getitem(ctx, tuple_st, index); } } else { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy