From 6614ae69e934344ca2253ba4b48f9157ef91ca38 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 19 May 2025 11:22:27 -0400 Subject: [PATCH 1/4] Use POP_TWO_LOAD_CONST_INLINE_BORROW --- Python/optimizer_bytecodes.c | 52 ++++++++++++++++++++++-- Python/optimizer_cases.c.h | 77 ++++++++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 11 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 7c160cdcb0c149..837c16b32d208f 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -207,6 +207,20 @@ dummy_func(void) { else { res = sym_new_type(ctx, &PyFloat_Type); } + + if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + PyObject *temp = PyObject_RichCompare(sym_get_const(ctx, left), + sym_get_const(ctx, right), + oparg >> 5); + if (temp == NULL) { + goto error; + } + assert(PyBool_Check(temp)); + assert(_Py_IsImmortal(temp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); + res = sym_new_const(ctx, temp); + Py_DECREF(temp); + } } op(_BINARY_OP_ADD_INT, (left, right -- res)) { @@ -486,11 +500,43 @@ dummy_func(void) { } op(_COMPARE_OP_FLOAT, (left, right -- res)) { - res = sym_new_type(ctx, &PyBool_Type); + if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *tmp = PyObject_RichCompare(sym_get_const(ctx, left), + sym_get_const(ctx, right), + oparg >> 5); + if (tmp == NULL) { + goto error; + } + assert(PyBool_Check(tmp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp); + res = sym_new_const(ctx, tmp); + Py_DECREF(tmp); + } + else { + res = sym_new_type(ctx, &PyBool_Type); + } } op(_COMPARE_OP_STR, (left, right -- res)) { - res = sym_new_type(ctx, &PyBool_Type); + if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *tmp = PyObject_RichCompare(sym_get_const(ctx, left), + sym_get_const(ctx, right), + oparg >> 5); + if (tmp == NULL) { + goto error; + } + assert(PyBool_Check(tmp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp); + res = sym_new_const(ctx, tmp); + Py_DECREF(tmp); + } + else { + res = sym_new_type(ctx, &PyBool_Type); + } } op(_IS_OP, (left, right -- b)) { @@ -1117,4 +1163,4 @@ dummy_func(void) { // END BYTECODES // -} +} \ No newline at end of file diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index deb912662e4b0b..35e2e08e6610d0 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1334,11 +1334,33 @@ } case _COMPARE_OP_FLOAT: { + JitOptSymbol *right; + JitOptSymbol *left; JitOptSymbol *res; - res = sym_new_type(ctx, &PyBool_Type); - stack_pointer[-2] = res; - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); + right = stack_pointer[-1]; + left = stack_pointer[-2]; + if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *tmp = PyObject_RichCompare(sym_get_const(ctx, left), + sym_get_const(ctx, right), + oparg >> 5); + if (tmp == NULL) { + goto error; + } + assert(PyBool_Check(tmp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp); + res = sym_new_const(ctx, tmp); + stack_pointer[-2] = res; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + Py_DECREF(tmp); + } + else { + res = sym_new_type(ctx, &PyBool_Type); + stack_pointer += -1; + } + stack_pointer[-1] = res; break; } @@ -1375,11 +1397,33 @@ } case _COMPARE_OP_STR: { + JitOptSymbol *right; + JitOptSymbol *left; JitOptSymbol *res; - res = sym_new_type(ctx, &PyBool_Type); - stack_pointer[-2] = res; - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); + right = stack_pointer[-1]; + left = stack_pointer[-2]; + if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *tmp = PyObject_RichCompare(sym_get_const(ctx, left), + sym_get_const(ctx, right), + oparg >> 5); + if (tmp == NULL) { + goto error; + } + assert(PyBool_Check(tmp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp); + res = sym_new_const(ctx, tmp); + stack_pointer[-2] = res; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + Py_DECREF(tmp); + } + else { + res = sym_new_type(ctx, &PyBool_Type); + stack_pointer += -1; + } + stack_pointer[-1] = res; break; } @@ -2344,6 +2388,23 @@ else { res = sym_new_type(ctx, &PyFloat_Type); } + if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + stack_pointer[-2] = res; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + PyObject *temp = PyObject_RichCompare(sym_get_const(ctx, left), + sym_get_const(ctx, right), + oparg >> 5); + if (temp == NULL) { + goto error; + } + assert(PyBool_Check(temp)); + assert(_Py_IsImmortal(temp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); + res = sym_new_const(ctx, temp); + Py_DECREF(temp); + stack_pointer += 1; + } stack_pointer[-2] = res; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); From 37ccb18c9a18eefcc49fc8fae522cd4a41385212 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 19 May 2025 11:23:24 -0400 Subject: [PATCH 2/4] Add newline back --- 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 837c16b32d208f..dc1b280a289a01 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1163,4 +1163,4 @@ dummy_func(void) { // END BYTECODES // -} \ No newline at end of file +} From 3c19e433c28c2a13c6926a6beb4e0f99d59de1b9 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 15:26:29 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-05-19-15-26-26.gh-issue-130415.BFmc1o.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-05-19-15-26-26.gh-issue-130415.BFmc1o.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-05-19-15-26-26.gh-issue-130415.BFmc1o.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-19-15-26-26.gh-issue-130415.BFmc1o.rst new file mode 100644 index 00000000000000..b0ad2640150ffb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-19-15-26-26.gh-issue-130415.BFmc1o.rst @@ -0,0 +1 @@ +Optimize constant comparison for _COMPARE_OP_FLOAT, _COMPARE_OP_STR, _BINARY_OP in JIT builds From 6c7861cb760be0811a0864e7cf1fa2a727517428 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 19 May 2025 11:33:36 -0400 Subject: [PATCH 4/4] Fix rhs and lhs --- Python/optimizer_bytecodes.c | 6 +++--- Python/optimizer_cases.c.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index dc1b280a289a01..26b8dc611b7a4e 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -208,9 +208,9 @@ dummy_func(void) { res = sym_new_type(ctx, &PyFloat_Type); } - if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { - PyObject *temp = PyObject_RichCompare(sym_get_const(ctx, left), - sym_get_const(ctx, right), + if (sym_is_const(ctx, lhs) && sym_is_const(ctx, rhs)) { + PyObject *temp = PyObject_RichCompare(sym_get_const(ctx, lhs), + sym_get_const(ctx, rhs), oparg >> 5); if (temp == NULL) { goto error; diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 35e2e08e6610d0..28f70b96af7079 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2388,12 +2388,12 @@ else { res = sym_new_type(ctx, &PyFloat_Type); } - if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) { + if (sym_is_const(ctx, lhs) && sym_is_const(ctx, rhs)) { stack_pointer[-2] = res; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - PyObject *temp = PyObject_RichCompare(sym_get_const(ctx, left), - sym_get_const(ctx, right), + PyObject *temp = PyObject_RichCompare(sym_get_const(ctx, lhs), + sym_get_const(ctx, rhs), oparg >> 5); if (temp == NULL) { goto error;