diff options
author | Savannah Ostrowski <savannahostrowski@gmail.com> | 2025-03-21 11:23:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-21 11:23:12 -0700 |
commit | b92ee14b80cc8898f799aa8120ec99dd0c882339 (patch) | |
tree | a32440d8906db0dc9393983205d43b3cfb4eef41 /Python | |
parent | 0de5e0c5442abddbe17481ef450e4abc992058f5 (diff) | |
download | cpython-b92ee14b80cc8898f799aa8120ec99dd0c882339.tar.gz cpython-b92ee14b80cc8898f799aa8120ec99dd0c882339.zip |
GH-130415: Optimize constant comparison in JIT builds (GH-131489)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 6 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 24 | ||||
-rw-r--r-- | Python/optimizer_bytecodes.c | 20 | ||||
-rw-r--r-- | Python/optimizer_cases.c.h | 44 |
4 files changed, 89 insertions, 5 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index cdd4d5bdd46..fe1465b36c7 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -5133,6 +5133,12 @@ dummy_func( value = PyStackRef_FromPyObjectImmortal(ptr); } + tier2 pure op(_POP_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, pop1, pop2 -- value)) { + PyStackRef_CLOSE(pop2); + PyStackRef_CLOSE(pop1); + value = PyStackRef_FromPyObjectImmortal(ptr); + } + tier2 op(_CHECK_FUNCTION, (func_version/2 -- )) { assert(PyStackRef_FunctionCheck(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 42a3d6d4be9..2bd009e3755 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -6925,6 +6925,30 @@ break; } + case _POP_TWO_LOAD_CONST_INLINE_BORROW: { + _PyStackRef pop2; + _PyStackRef pop1; + _PyStackRef value; + pop2 = stack_pointer[-1]; + pop1 = stack_pointer[-2]; + PyObject *ptr = (PyObject *)CURRENT_OPERAND0(); + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(pop2); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(pop1); + stack_pointer = _PyFrame_GetStackPointer(frame); + value = PyStackRef_FromPyObjectImmortal(ptr); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _CHECK_FUNCTION: { uint32_t func_version = (uint32_t)CURRENT_OPERAND0(); assert(PyStackRef_FunctionCheck(frame->f_funcobj)); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index cfa0a733cda..cba878748c2 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -446,7 +446,25 @@ dummy_func(void) { } op(_COMPARE_OP_INT, (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)); + assert(_Py_IsImmortal(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_FLOAT, (left, right -- res)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index fc70ee31a80..a1119171fa4 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1281,11 +1281,38 @@ } case _COMPARE_OP_INT: { + 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))); + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); + 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)); + assert(_Py_IsImmortal(tmp)); + REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp); + res = sym_new_const(ctx, tmp); + stack_pointer[0] = res; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + Py_DECREF(tmp); + } + else { + res = sym_new_type(ctx, &PyBool_Type); + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + } + stack_pointer[-1] = res; break; } @@ -2392,6 +2419,15 @@ break; } + case _POP_TWO_LOAD_CONST_INLINE_BORROW: { + JitOptSymbol *value; + value = sym_new_not_null(ctx); + stack_pointer[-2] = value; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _CHECK_FUNCTION: { break; } |