From 15da3e6b6aecfc2f885d0b5026602ad933318b19 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Fri, 6 Jun 2025 19:15:15 +0300 Subject: [PATCH 1/7] optimize `_UNARY_NEGATIVE` --- Python/optimizer_bytecodes.c | 9 +++++++++ Python/optimizer_cases.c.h | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 34250fd4385d34..76e0d03b88033f 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -467,6 +467,15 @@ dummy_func(void) { res = sym_new_truthiness(ctx, value, false); } + op(_UNARY_NEGATIVE, (value -- res)) { + if (sym_matches_type(value, &PyLong_Type) || sym_matches_type(value, &PyFloat_Type)) { + res = sym_new_type(ctx, sym_get_type(value)); + } + else { + res = sym_new_not_null(ctx); + } + } + op(_COMPARE_OP, (left, right -- res)) { if (oparg & 16) { res = sym_new_type(ctx, &PyBool_Type); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index bbd45067103679..d1a1b0356d552f 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -142,8 +142,15 @@ } case _UNARY_NEGATIVE: { + JitOptSymbol *value; JitOptSymbol *res; - res = sym_new_not_null(ctx); + value = stack_pointer[-1]; + if (sym_matches_type(value, &PyLong_Type) || sym_matches_type(value, &PyFloat_Type)) { + res = sym_new_type(ctx, sym_get_type(value)); + } + else { + res = sym_new_not_null(ctx); + } stack_pointer[-1] = res; break; } From e7dc06ad3627ee5bd632fec96b4e4a7bc700c9a0 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Fri, 6 Jun 2025 19:17:31 +0300 Subject: [PATCH 2/7] add news entry --- .../2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst new file mode 100644 index 00000000000000..67e947e1a7857c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst @@ -0,0 +1 @@ +Optimize ``_UNARY_NEGATIVE`` From 4135c716d40d2746881d7890c8794399f2ec1076 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Fri, 6 Jun 2025 19:19:55 +0300 Subject: [PATCH 3/7] add test case --- Lib/test/test_capi/test_opt.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index cb6eae484149ee..c2bc83407235dd 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -2219,6 +2219,24 @@ def f(n): self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops) self.assertNotIn("_LOAD_ATTR_METHOD_LAZY_DICT", uops) + def test_unary_negative_long_float_type(self): + def testfunc(n): + for _ in range(n): + a = 9397 + f = 9397.0 + x = -a + -a + y = -f + -f + + testfunc(TIER2_THRESHOLD) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + + self.assertNotIn("_GUARD_TOS_INT", uops) + self.assertNotIn("_GUARD_NOS_INT", uops) + self.assertNotIn("_GUARD_TOS_FLOAT", uops) + self.assertNotIn("_GUARD_NOS_FLOAT", uops) def global_identity(x): return x From 161bad9b6375022a1134413447f91813f0382ad1 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Sat, 7 Jun 2025 09:58:21 +0300 Subject: [PATCH 4/7] fix news entry --- .../2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst index 67e947e1a7857c..6a9d9c683f9a8c 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-06-19-17-22.gh-issue-131798.XoV8Eb.rst @@ -1 +1 @@ -Optimize ``_UNARY_NEGATIVE`` +Optimize ``_UNARY_NEGATIVE`` in JIT-compiled code. From 68eed5ee2609074e4207358d2c0326c4b33fda83 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Sat, 7 Jun 2025 09:59:03 +0300 Subject: [PATCH 5/7] better type lookups --- Python/optimizer_bytecodes.c | 5 +++-- Python/optimizer_cases.c.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 76e0d03b88033f..200f60a9abdf01 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -468,8 +468,9 @@ dummy_func(void) { } op(_UNARY_NEGATIVE, (value -- res)) { - if (sym_matches_type(value, &PyLong_Type) || sym_matches_type(value, &PyFloat_Type)) { - res = sym_new_type(ctx, sym_get_type(value)); + PyTypeObject *type = sym_get_type(value); + if (type == &PyLong_Type || type == &PyFloat_Type) { + res = sym_new_type(ctx, type); } else { res = sym_new_not_null(ctx); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index d1a1b0356d552f..4de23a9a77fa44 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -145,8 +145,9 @@ JitOptSymbol *value; JitOptSymbol *res; value = stack_pointer[-1]; - if (sym_matches_type(value, &PyLong_Type) || sym_matches_type(value, &PyFloat_Type)) { - res = sym_new_type(ctx, sym_get_type(value)); + PyTypeObject *type = sym_get_type(value); + if (type == &PyLong_Type || type == &PyFloat_Type) { + res = sym_new_type(ctx, type); } else { res = sym_new_not_null(ctx); From 1890739113702801e0867bb3dda1f7eccda16095 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Mon, 23 Jun 2025 22:05:32 +0300 Subject: [PATCH 6/7] support compact ints --- Python/optimizer_bytecodes.c | 16 ++++++++++------ Python/optimizer_cases.c.h | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 1ad52a4eba254e..e44edef2fd57ec 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -448,12 +448,16 @@ dummy_func(void) { } op(_UNARY_NEGATIVE, (value -- res)) { - PyTypeObject *type = sym_get_type(value); - if (type == &PyLong_Type || type == &PyFloat_Type) { - res = sym_new_type(ctx, type); - } - else { - res = sym_new_not_null(ctx); + if (sym_is_compact_int(value)) { + res = sym_new_compact_int(ctx); + } else { + PyTypeObject *type = sym_get_type(value); + if (type == &PyLong_Type || type == &PyFloat_Type) { + res = sym_new_type(ctx, type); + } + else { + res = sym_new_not_null(ctx); + } } } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 1a5bfe2c5ed8ff..c7a5e19bc3c7f7 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -186,12 +186,16 @@ JitOptRef value; JitOptRef res; value = stack_pointer[-1]; - PyTypeObject *type = sym_get_type(value); - if (type == &PyLong_Type || type == &PyFloat_Type) { - res = sym_new_type(ctx, type); - } - else { - res = sym_new_not_null(ctx); + if (sym_is_compact_int(value)) { + res = sym_new_compact_int(ctx); + } else { + PyTypeObject *type = sym_get_type(value); + if (type == &PyLong_Type || type == &PyFloat_Type) { + res = sym_new_type(ctx, type); + } + else { + res = sym_new_not_null(ctx); + } } stack_pointer[-1] = res; break; From 3fa5d86a1f051033be3974df7dec11279c592e43 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Mon, 23 Jun 2025 22:08:30 +0300 Subject: [PATCH 7/7] keep old styling --- Python/optimizer_bytecodes.c | 3 ++- Python/optimizer_cases.c.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index e44edef2fd57ec..f8a0484bdc2b04 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -450,7 +450,8 @@ dummy_func(void) { op(_UNARY_NEGATIVE, (value -- res)) { if (sym_is_compact_int(value)) { res = sym_new_compact_int(ctx); - } else { + } + else { PyTypeObject *type = sym_get_type(value); if (type == &PyLong_Type || type == &PyFloat_Type) { res = sym_new_type(ctx, type); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index c7a5e19bc3c7f7..10767ccdbd57f5 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -188,7 +188,8 @@ value = stack_pointer[-1]; if (sym_is_compact_int(value)) { res = sym_new_compact_int(ctx); - } else { + } + else { PyTypeObject *type = sym_get_type(value); if (type == &PyLong_Type || type == &PyFloat_Type) { res = sym_new_type(ctx, type);