From cabe8f1bf01e092afe4bb3175bd4730f496e629f Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sat, 3 May 2025 22:31:14 +0800 Subject: [PATCH 01/22] gh-131798: JIT: Narrow the return type of _GET_LEN to int Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 13 +++++++++++++ Python/optimizer_bytecodes.c | 6 +++++- Python/optimizer_cases.c.h | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index ba7bcb4540a451..0cc788b3206ba9 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1925,6 +1925,19 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertNotIn("_GUARD_TOS_INT", uops) + def test_get_len(self): + def testfunc(n): + a = [1, 2, 3, 4] + for _ in range(n): + match a: + case [1,2]: + _ = len(a) - 1 + _, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertNotIn("_GUARD_NOS_INT", uops) + self.assertNotIn("_GUARD_TOS_INT", uops) + self.assertIn("_GET_LEN", uops) + def test_binary_op_subscr_tuple_int(self): def testfunc(n): x = 0 diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index e99421a3aff4ba..d7c5cc85eb8684 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -480,7 +480,7 @@ dummy_func(void) { res = sym_new_const(ctx, tmp); Py_DECREF(tmp); } - else { + else { res = sym_new_type(ctx, &PyBool_Type); } } @@ -1088,6 +1088,10 @@ dummy_func(void) { res = sym_new_type(ctx, &PyLong_Type); } + op(_GET_LEN, (-- len)) { + len = sym_new_type(ctx, &PyLong_Type); + } + op(_GUARD_CALLABLE_LEN, (callable, unused, unused -- callable, unused, unused)) { PyObject *len = _PyInterpreterState_GET()->callable_cache.len; if (sym_get_const(ctx, callable) == len) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 56b4b9983fbaaa..112b8530f13871 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1470,7 +1470,7 @@ case _GET_LEN: { JitOptSymbol *len; - len = sym_new_not_null(ctx); + len = sym_new_type(ctx, &PyLong_Type); stack_pointer[0] = len; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); From 1f8a6076dd953b8b2895a353a2302392728cce22 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sat, 3 May 2025 22:32:13 +0800 Subject: [PATCH 02/22] Add news Signed-off-by: Manjusaka --- .../2025-05-03-22-31-53.gh-issue-131798.fQ0ato.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-05-03-22-31-53.gh-issue-131798.fQ0ato.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-05-03-22-31-53.gh-issue-131798.fQ0ato.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-03-22-31-53.gh-issue-131798.fQ0ato.rst new file mode 100644 index 00000000000000..f322d43b30a9f3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-03-22-31-53.gh-issue-131798.fQ0ato.rst @@ -0,0 +1,2 @@ +Allow the JIT to remove int guards after ``_GET_LEN`` by setting the return +type to int. From f2f71d921c677fc649946849abe73096460da9a6 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sat, 3 May 2025 22:33:39 +0800 Subject: [PATCH 03/22] Fix typo Signed-off-by: Manjusaka --- Python/optimizer_bytecodes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index d7c5cc85eb8684..06905cfbe6e262 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -480,7 +480,7 @@ dummy_func(void) { res = sym_new_const(ctx, tmp); Py_DECREF(tmp); } - else { + else { res = sym_new_type(ctx, &PyBool_Type); } } From 1662b47718e64b2599e23891309e614d735b0616 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Thu, 8 May 2025 15:02:40 +0800 Subject: [PATCH 04/22] Fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 0cc788b3206ba9..a240b75887486c 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1927,14 +1927,16 @@ def testfunc(n): def test_get_len(self): def testfunc(n): + x = 0 a = [1, 2, 3, 4] for _ in range(n): match a: - case [1,2]: - _ = len(a) - 1 - _, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + case [_, _, _, _]: + x += 1 + return x + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) uops = get_opnames(ex) - self.assertNotIn("_GUARD_NOS_INT", uops) self.assertNotIn("_GUARD_TOS_INT", uops) self.assertIn("_GET_LEN", uops) From 52ce69827de5d584abf0097c6f672858e5eaf7e9 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Thu, 8 May 2025 15:07:44 +0800 Subject: [PATCH 05/22] Fix review idea Signed-off-by: Manjusaka --- Python/optimizer_bytecodes.c | 12 ++++++++++-- Python/optimizer_cases.c.h | 11 ++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 06905cfbe6e262..35b9f4519114d8 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1088,8 +1088,16 @@ dummy_func(void) { res = sym_new_type(ctx, &PyLong_Type); } - op(_GET_LEN, (-- len)) { - len = sym_new_type(ctx, &PyLong_Type); + op(_GET_LEN, (obj -- obj, len)) { + int tuple_length = sym_tuple_length(obj); + if (tuple_length == -1) { + // Unknown length + len = sym_new_type(ctx, &PyLong_Type); + } + else { + assert(tuple_length >= 0); + len = sym_new_const(ctx, PyLong_FromLong(tuple_length)); + } } op(_GUARD_CALLABLE_LEN, (callable, unused, unused -- callable, unused, unused)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 112b8530f13871..1cccfa1e9df2ea 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1469,8 +1469,17 @@ } case _GET_LEN: { + JitOptSymbol *obj; JitOptSymbol *len; - len = sym_new_type(ctx, &PyLong_Type); + obj = stack_pointer[-1]; + int tuple_length = sym_tuple_length(obj); + if (tuple_length == -1) { + len = sym_new_type(ctx, &PyLong_Type); + } + else { + assert(tuple_length >= 0); + len = sym_new_const(ctx, PyLong_FromLong(tuple_length)); + } stack_pointer[0] = len; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); From b1640ed6b3ccbc983baa228ffc788b35f5251b7d Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Thu, 8 May 2025 15:12:47 +0800 Subject: [PATCH 06/22] Fix review idea Signed-off-by: Manjusaka --- Python/optimizer_bytecodes.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 35b9f4519114d8..e63c0be0cc9cda 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1091,7 +1091,6 @@ dummy_func(void) { op(_GET_LEN, (obj -- obj, len)) { int tuple_length = sym_tuple_length(obj); if (tuple_length == -1) { - // Unknown length len = sym_new_type(ctx, &PyLong_Type); } else { From cf17d92c012232dee27e786c1b07b5e8e31e6736 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Fri, 9 May 2025 06:34:24 +0800 Subject: [PATCH 07/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 21 +++++++++++++++++---- Python/optimizer_bytecodes.c | 8 +++++++- Python/optimizer_cases.c.h | 11 ++++++++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index a240b75887486c..d43d6a5b2f9129 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1926,19 +1926,32 @@ def testfunc(n): self.assertNotIn("_GUARD_TOS_INT", uops) def test_get_len(self): - def testfunc(n): + def testfunc1(n): x = 0 - a = [1, 2, 3, 4] for _ in range(n): - match a: + match (1, 2, 3, 4): case [_, _, _, _]: x += 1 return x - res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + res, ex = self._run_with_optimizer(testfunc1, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertNotIn("_GUARD_TOS_INT", uops) + self.assertIn("_GET_LEN", uops) + self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) + def testfunc1(n): + x = 0 + for _ in range(n): + match [1, 2, 3, 4]: + case [_, _, _, _]: + x += 1 + return x + res, ex = self._run_with_optimizer(testfunc1, TIER2_THRESHOLD) self.assertEqual(res, TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_TOS_INT", uops) self.assertIn("_GET_LEN", uops) + self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) def test_binary_op_subscr_tuple_int(self): def testfunc(n): diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index e63c0be0cc9cda..536d443b9194f9 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -3,6 +3,7 @@ #include "pycore_uops.h" #include "pycore_uop_ids.h" #include "internal/pycore_moduleobject.h" +#include "tupleobject.h" #define op(name, ...) /* NAME is ignored */ @@ -1095,7 +1096,12 @@ dummy_func(void) { } else { assert(tuple_length >= 0); - len = sym_new_const(ctx, PyLong_FromLong(tuple_length)); + PyObject *temp = PyLong_FromLong(tuple_length); + if (temp == NULL) { + goto error; + } + len = sym_new_const(ctx, temp); + Py_DECREF(temp); } } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 1cccfa1e9df2ea..ef66f1437fa845 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1478,7 +1478,16 @@ } else { assert(tuple_length >= 0); - len = sym_new_const(ctx, PyLong_FromLong(tuple_length)); + PyObject *temp = PyLong_FromLong(tuple_length); + if (temp == NULL) { + goto error; + } + len = sym_new_const(ctx, temp); + stack_pointer[0] = len; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + Py_DECREF(temp); + stack_pointer += -1; } stack_pointer[0] = len; stack_pointer += 1; From c401539572d542c9485a8b6b256edcdc778cecbd Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sat, 10 May 2025 11:32:27 +0800 Subject: [PATCH 08/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 24 ++++++++++++------------ Python/optimizer_bytecodes.c | 1 - 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index d43d6a5b2f9129..f4c14863a45730 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1926,30 +1926,30 @@ def testfunc(n): self.assertNotIn("_GUARD_TOS_INT", uops) def test_get_len(self): - def testfunc1(n): - x = 0 + def testfunc(n): + x = "" for _ in range(n): match (1, 2, 3, 4): case [_, _, _, _]: - x += 1 + x += "1" return x - res, ex = self._run_with_optimizer(testfunc1, TIER2_THRESHOLD) - self.assertEqual(res, TIER2_THRESHOLD) + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(len(res), TIER2_THRESHOLD) uops = get_opnames(ex) - self.assertNotIn("_GUARD_TOS_INT", uops) + self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) - def testfunc1(n): - x = 0 + def testfunc(n): + x = "" for _ in range(n): match [1, 2, 3, 4]: case [_, _, _, _]: - x += 1 + x += "1" return x - res, ex = self._run_with_optimizer(testfunc1, TIER2_THRESHOLD) - self.assertEqual(res, TIER2_THRESHOLD) + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(len(res), TIER2_THRESHOLD) uops = get_opnames(ex) - self.assertNotIn("_GUARD_TOS_INT", uops) + self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 536d443b9194f9..b9efb031311c02 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -3,7 +3,6 @@ #include "pycore_uops.h" #include "pycore_uop_ids.h" #include "internal/pycore_moduleobject.h" -#include "tupleobject.h" #define op(name, ...) /* NAME is ignored */ From 619a846b0811385b82a6d29d3cd7bf90d6111780 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sat, 10 May 2025 22:24:41 +0800 Subject: [PATCH 09/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index f4c14863a45730..43e0f1daa7efd3 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1925,7 +1925,7 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertNotIn("_GUARD_TOS_INT", uops) - def test_get_len(self): + def test_get_len_with_tuple(self): def testfunc(n): x = "" for _ in range(n): @@ -1939,6 +1939,9 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) + + + def test_get_len_with_non_tuple(self): def testfunc(n): x = "" for _ in range(n): From 9adefc3fb4a675e9b6bc27dea360d9998950079f Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sat, 10 May 2025 22:25:17 +0800 Subject: [PATCH 10/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 43e0f1daa7efd3..6329da18ebb3dc 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1940,7 +1940,6 @@ def testfunc(n): self.assertIn("_GET_LEN", uops) self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) - def test_get_len_with_non_tuple(self): def testfunc(n): x = "" From 9c6efcbfef9c61328f224694a225429c18b0bb7a Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Sun, 11 May 2025 02:12:02 +0800 Subject: [PATCH 11/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 6329da18ebb3dc..674a05b1c6c9db 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1925,7 +1925,7 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertNotIn("_GUARD_TOS_INT", uops) - def test_get_len_with_tuple(self): + def test_get_len_with_const_tuple(self): def testfunc(n): x = "" for _ in range(n): @@ -1940,6 +1940,21 @@ def testfunc(n): self.assertIn("_GET_LEN", uops) self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) + def test_get_len_with_non_const_tuple(self): + def testfunc(n): + x = "" + for _ in range(n): + match (object(), object()): + case [_, _]: + x += "1" + return x + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(len(res), TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertNotIn("_GUARD_NOS_INT", uops) + self.assertIn("_GET_LEN", uops) + self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) + def test_get_len_with_non_tuple(self): def testfunc(n): x = "" From d1e3a2be92950ae536ccfab45f7eef4984b4b325 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:12:41 +0800 Subject: [PATCH 12/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 30 +++++++++++++++++++++++------- Python/optimizer_bytecodes.c | 4 ++++ Python/optimizer_cases.c.h | 3 +++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 6f029d642579a8..4b408b2204b4b8 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1942,14 +1942,14 @@ def testfunc(n): def test_get_len_with_non_const_tuple(self): def testfunc(n): - x = "" + x = 0.0 for _ in range(n): match (object(), object()): case [_, _]: - x += "1" + x += 1.0 return x res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) - self.assertEqual(len(res), TIER2_THRESHOLD) + self.assertEqual(int(res), TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) @@ -1957,18 +1957,34 @@ def testfunc(n): def test_get_len_with_non_tuple(self): def testfunc(n): - x = "" + x = 0.0 for _ in range(n): match [1, 2, 3, 4]: case [_, _, _, _]: - x += "1" + x += 1.0 return x res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) - self.assertEqual(len(res), TIER2_THRESHOLD) + self.assertEqual(int(res), TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) - self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) + + def test_get_len_with_immortal_tuple(self): + def testfunc(n): + class TestObject(tuple): + pass + x = 0.0 + for _ in range(n): + match TestObject.__mro__: + case (_, _, _,): + x += 1.0 + return x + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(int(res), TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertIn("_GET_LEN", uops) + self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) + def test_binary_op_subscr_tuple_int(self): def testfunc(n): diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 553072f927ddf6..573ac2ee5da688 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -3,6 +3,7 @@ #include "pycore_uops.h" #include "pycore_uop_ids.h" #include "internal/pycore_moduleobject.h" +#include "refcount.h" #define op(name, ...) /* NAME is ignored */ @@ -1128,6 +1129,9 @@ dummy_func(void) { goto error; } len = sym_new_const(ctx, temp); + if (_Py_IsImmortal(temp)) { + REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); + } Py_DECREF(temp); } } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index aa2a6d50773187..459dccf5f366b9 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1477,6 +1477,9 @@ goto error; } len = sym_new_const(ctx, temp); + if (_Py_IsImmortal(temp)) { + REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); + } stack_pointer[0] = len; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); From e0e37457410778ca42a4cdb3e284ed94429c2d76 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:13:49 +0800 Subject: [PATCH 13/22] fix review idea Signed-off-by: Manjusaka --- Python/optimizer_bytecodes.c | 2 +- Python/optimizer_cases.c.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 573ac2ee5da688..4a5b264eb53ba3 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1128,10 +1128,10 @@ dummy_func(void) { if (temp == NULL) { goto error; } - len = sym_new_const(ctx, temp); if (_Py_IsImmortal(temp)) { REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); } + len = sym_new_const(ctx, temp); Py_DECREF(temp); } } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 459dccf5f366b9..0a539b2829e3ba 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1476,10 +1476,10 @@ if (temp == NULL) { goto error; } - len = sym_new_const(ctx, temp); if (_Py_IsImmortal(temp)) { REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); } + len = sym_new_const(ctx, temp); stack_pointer[0] = len; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); From 81c49964dd33b161c8019ed611535168652e84c4 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:16:32 +0800 Subject: [PATCH 14/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 4b408b2204b4b8..22f1e4a3509a08 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1971,12 +1971,12 @@ def testfunc(n): def test_get_len_with_immortal_tuple(self): def testfunc(n): - class TestObject(tuple): + class TestObject: pass x = 0.0 for _ in range(n): match TestObject.__mro__: - case (_, _, _,): + case (_, _,): x += 1.0 return x res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) From 93e1e86360768fc5122fdfa21cb8e1792b53c56e Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:18:51 +0800 Subject: [PATCH 15/22] fix review idea Signed-off-by: Manjusaka --- Python/optimizer_bytecodes.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 4a5b264eb53ba3..639b4b7af1632c 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -3,7 +3,6 @@ #include "pycore_uops.h" #include "pycore_uop_ids.h" #include "internal/pycore_moduleobject.h" -#include "refcount.h" #define op(name, ...) /* NAME is ignored */ From 6b5282fbaee0d1c2fa9ef53f3b99b271531a7486 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:39:57 +0800 Subject: [PATCH 16/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 22f1e4a3509a08..f281a821f1b4a9 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1937,23 +1937,8 @@ def testfunc(n): self.assertEqual(len(res), TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_NOS_INT", uops) - self.assertIn("_GET_LEN", uops) - self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) + self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) - def test_get_len_with_non_const_tuple(self): - def testfunc(n): - x = 0.0 - for _ in range(n): - match (object(), object()): - case [_, _]: - x += 1.0 - return x - res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) - self.assertEqual(int(res), TIER2_THRESHOLD) - uops = get_opnames(ex) - self.assertNotIn("_GUARD_NOS_INT", uops) - self.assertIn("_GET_LEN", uops) - self.assertIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops) def test_get_len_with_non_tuple(self): def testfunc(n): @@ -1969,22 +1954,6 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) - def test_get_len_with_immortal_tuple(self): - def testfunc(n): - class TestObject: - pass - x = 0.0 - for _ in range(n): - match TestObject.__mro__: - case (_, _,): - x += 1.0 - return x - res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) - self.assertEqual(int(res), TIER2_THRESHOLD) - uops = get_opnames(ex) - self.assertIn("_GET_LEN", uops) - self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) - def test_binary_op_subscr_tuple_int(self): def testfunc(n): From 2eefeb329a5cee1894ffb2a8cb96f06a56584f28 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:59:00 +0800 Subject: [PATCH 17/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index f281a821f1b4a9..e425ef0c5960ad 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1927,11 +1927,11 @@ def testfunc(n): def test_get_len_with_const_tuple(self): def testfunc(n): - x = "" + x = 0.0 for _ in range(n): match (1, 2, 3, 4): case [_, _, _, _]: - x += "1" + x += 1.0 return x res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) self.assertEqual(len(res), TIER2_THRESHOLD) From 9c58f2ccd219d1f16e284c24a6f3e05215ced591 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 04:59:39 +0800 Subject: [PATCH 18/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index e425ef0c5960ad..27cd80cdae3772 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1934,7 +1934,7 @@ def testfunc(n): x += 1.0 return x res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) - self.assertEqual(len(res), TIER2_THRESHOLD) + self.assertEqual(int(res), TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) From f9822e96160413b3b4d23110fc3b7fe38bc735dd Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 05:13:21 +0800 Subject: [PATCH 19/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 27cd80cdae3772..a31e523e274477 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1939,6 +1939,19 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) + def test_get_len_with_non_const_tuple(self): + def testfunc(n): + x = 0.0 + for _ in range(n): + match (object(), object()): + case [_, _]: + x += 1.0 + return x + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(int(res), TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertNotIn("_GUARD_NOS_INT", uops) + self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) def test_get_len_with_non_tuple(self): def testfunc(n): From 6a06affd2e2df39db2f454ccc07fada4b6192b10 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 05:13:37 +0800 Subject: [PATCH 20/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index a31e523e274477..896a035ba362fc 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1943,7 +1943,7 @@ def test_get_len_with_non_const_tuple(self): def testfunc(n): x = 0.0 for _ in range(n): - match (object(), object()): + match object(), object(): case [_, _]: x += 1.0 return x From 6d92614b4e235a6d8e2c1be343207981f402ef53 Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 05:13:56 +0800 Subject: [PATCH 21/22] fix review idea Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 896a035ba362fc..0fdd16fe1b217a 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1937,6 +1937,7 @@ def testfunc(n): self.assertEqual(int(res), TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_NOS_INT", uops) + self.assertNotIn("_GET_LEN", uops) self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) def test_get_len_with_non_const_tuple(self): @@ -1951,6 +1952,7 @@ def testfunc(n): self.assertEqual(int(res), TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_GUARD_NOS_INT", uops) + self.assertNotIn("_GET_LEN", uops) self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) def test_get_len_with_non_tuple(self): From 5cfbad4ec2e020545ac39736fa6b8316b1356f9d Mon Sep 17 00:00:00 2001 From: Manjusaka Date: Wed, 21 May 2025 05:17:05 +0800 Subject: [PATCH 22/22] format code Signed-off-by: Manjusaka --- Lib/test/test_capi/test_opt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 0fdd16fe1b217a..50c4f19a1ab55f 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1969,7 +1969,6 @@ def testfunc(n): self.assertNotIn("_GUARD_NOS_INT", uops) self.assertIn("_GET_LEN", uops) - def test_binary_op_subscr_tuple_int(self): def testfunc(n): x = 0