gh-134584: JIT: Remove redundant refcounting for UNARY_{INVERT|NEGATIVE} (GH-143704)

This commit is contained in:
Ken Jin 2026-01-12 04:42:55 +08:00 committed by GitHub
parent 9d13ca97c1
commit 548526bbbe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 976 additions and 899 deletions

View file

@ -434,14 +434,19 @@ dummy_func(
PyStackRef_CLOSE(receiver);
}
inst(UNARY_NEGATIVE, (value -- res)) {
macro(UNARY_NEGATIVE) = _UNARY_NEGATIVE + POP_TOP;
op(_UNARY_NEGATIVE, (value -- res, v)) {
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
ERROR_IF(res_o == NULL);
if (res_o == NULL) {
ERROR_NO_POP();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
DEAD(value);
}
pure inst(UNARY_NOT, (value -- res)) {
inst(UNARY_NOT, (value -- res)) {
assert(PyStackRef_BoolCheck(value));
res = PyStackRef_IsFalse(value)
? PyStackRef_True : PyStackRef_False;
@ -570,11 +575,16 @@ dummy_func(
_REPLACE_WITH_TRUE +
POP_TOP;
inst(UNARY_INVERT, (value -- res)) {
macro(UNARY_INVERT) = _UNARY_INVERT + POP_TOP;
op(_UNARY_INVERT, (value -- res, v)) {
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
ERROR_IF(res_o == NULL);
if (res_o == NULL) {
ERROR_NO_POP();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
DEAD(value);
}
family(BINARY_OP, INLINE_CACHE_ENTRIES_BINARY_OP) = {

View file

@ -2631,11 +2631,12 @@
break;
}
case _UNARY_NEGATIVE_r11: {
case _UNARY_NEGATIVE_r12: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef value;
_PyStackRef res;
_PyStackRef v;
_PyStackRef _stack_item_0 = _tos_cache0;
value = _stack_item_0;
stack_pointer[0] = value;
@ -2644,20 +2645,18 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
_tos_cache1 = v;
_tos_cache0 = res;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
@ -3667,11 +3666,12 @@
break;
}
case _UNARY_INVERT_r11: {
case _UNARY_INVERT_r12: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef value;
_PyStackRef res;
_PyStackRef v;
_PyStackRef _stack_item_0 = _tos_cache0;
value = _stack_item_0;
stack_pointer[0] = value;
@ -3680,20 +3680,18 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
_tos_cache1 = v;
_tos_cache0 = res;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}

View file

@ -11860,22 +11860,27 @@
INSTRUCTION_STATS(UNARY_INVERT);
_PyStackRef value;
_PyStackRef res;
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
_PyStackRef v;
// _UNARY_INVERT
{
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
}
// _POP_TOP
{
value = v;
stack_pointer[-1] = res;
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}
@ -11889,22 +11894,27 @@
INSTRUCTION_STATS(UNARY_NEGATIVE);
_PyStackRef value;
_PyStackRef res;
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
_PyStackRef v;
// _UNARY_NEGATIVE
{
value = stack_pointer[-1];
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
stack_pointer = _PyFrame_GetStackPointer(frame);
if (res_o == NULL) {
JUMP_TO_LABEL(error);
}
res = PyStackRef_FromPyObjectSteal(res_o);
v = value;
}
// _POP_TOP
{
value = v;
stack_pointer[-1] = res;
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
}
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[0] = res;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
DISPATCH();
}

View file

@ -449,7 +449,8 @@ dummy_func(void) {
res = sym_new_truthiness(ctx, value, false);
}
op(_UNARY_NEGATIVE, (value -- res)) {
op(_UNARY_NEGATIVE, (value -- res, v)) {
v = value;
REPLACE_OPCODE_IF_EVALUATES_PURE(value, res);
if (sym_is_compact_int(value)) {
res = sym_new_compact_int(ctx);
@ -465,7 +466,8 @@ dummy_func(void) {
}
}
op(_UNARY_INVERT, (value -- res)) {
op(_UNARY_INVERT, (value -- res, v)) {
v = value;
// Required to avoid a warning due to the deprecation of bitwise inversion of bools
if (!sym_matches_type(value, &PyBool_Type)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(value, res);

View file

@ -221,30 +221,38 @@
case _UNARY_NEGATIVE: {
JitOptRef value;
JitOptRef res;
JitOptRef v;
value = stack_pointer[-1];
v = value;
if (
sym_is_safe_const(ctx, value)
) {
JitOptRef value_sym = value;
_PyStackRef value = sym_get_const_as_stackref(ctx, value_sym);
_PyStackRef res_stackref;
_PyStackRef v_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
if (res_o == NULL) {
goto error;
JUMP_TO_LABEL(error);
}
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
v_stackref = value;
/* End of uop copied from bytecodes for constant evaluation */
(void)v_stackref;
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TOP_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
// Replace with _INSERT_1_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _INSERT_1_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
if (sym_is_compact_int(value)) {
@ -259,7 +267,11 @@
res = sym_new_not_null(ctx);
}
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -444,7 +456,9 @@
case _UNARY_INVERT: {
JitOptRef value;
JitOptRef res;
JitOptRef v;
value = stack_pointer[-1];
v = value;
if (!sym_matches_type(value, &PyBool_Type)) {
if (
sym_is_safe_const(ctx, value)
@ -452,23 +466,29 @@
JitOptRef value_sym = value;
_PyStackRef value = sym_get_const_as_stackref(ctx, value_sym);
_PyStackRef res_stackref;
_PyStackRef v_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value));
PyStackRef_CLOSE(value);
if (res_o == NULL) {
goto error;
JUMP_TO_LABEL(error);
}
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
v_stackref = value;
/* End of uop copied from bytecodes for constant evaluation */
(void)v_stackref;
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TOP_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
// Replace with _INSERT_1_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
REPLACE_OP(this_instr, _INSERT_1_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
}
@ -478,7 +498,11 @@
else {
res = sym_new_not_null(ctx);
}
CHECK_STACK_BOUNDS(1);
stack_pointer[-1] = res;
stack_pointer[0] = v;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}