From 1c6517fd606d4d88a7b3d0c186c03183f6a498f3 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 20 Feb 2024 03:32:10 +0800 Subject: [PATCH 01/13] Type/values propagate for TO_BOOL in tier 2 --- Python/optimizer_analysis.c | 7 ++ .../tier2_redundancy_eliminator_bytecodes.c | 96 +++++++++++++---- Python/tier2_redundancy_eliminator_cases.c.h | 100 ++++++++++++------ 3 files changed, 151 insertions(+), 52 deletions(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index b104d2fa7baec9..fdd1d0c5c5593f 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -595,6 +595,13 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, } \ } while (0); +#define ERROR_IF(COND, LABEL) \ + do { \ + if (COND) { \ + goto LABEL; \ + } \ + } while (0); + #define _LOAD_ATTR_NOT_NULL \ do { \ OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); \ diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index 3f6e8ce1bbfbad..7d203440dd349b 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -84,9 +84,7 @@ dummy_func(void) { assert(PyLong_CheckExact(get_const(right))); PyObject *temp = _PyLong_Add((PyLongObject *)get_const(left), (PyLongObject *)get_const(right)); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -102,9 +100,7 @@ dummy_func(void) { assert(PyLong_CheckExact(get_const(right))); PyObject *temp = _PyLong_Subtract((PyLongObject *)get_const(left), (PyLongObject *)get_const(right)); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -120,9 +116,7 @@ dummy_func(void) { assert(PyLong_CheckExact(get_const(right))); PyObject *temp = _PyLong_Multiply((PyLongObject *)get_const(left), (PyLongObject *)get_const(right)); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -139,9 +133,7 @@ dummy_func(void) { PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(get_const(left)) + PyFloat_AS_DOUBLE(get_const(right))); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); res = sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -158,9 +150,7 @@ dummy_func(void) { PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(get_const(left)) - PyFloat_AS_DOUBLE(get_const(right))); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); res = sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -177,9 +167,7 @@ dummy_func(void) { PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(get_const(left)) * PyFloat_AS_DOUBLE(get_const(right))); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); res = sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -189,6 +177,74 @@ dummy_func(void) { } } + op(_TO_BOOL, (value -- res)) { + sym_set_type(value, &PyBool_Type); + if (is_const(value)) { + int err = PyObject_IsTrue(get_const(value)); + ERROR_IF(err < 0, error); + res = sym_new_const(ctx, err ? Py_True : Py_False); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } + } + + op(_TO_BOOL_BOOL, (value -- value)) { + sym_set_type(value, &PyBool_Type); + } + + op(_TO_BOOL_INT, (value -- res)) { + sym_set_type(value, &PyLong_Type); + if (is_const(value)) { + PyObject *temp = NULL; + if (_PyLong_IsZero((PyLongObject *)get_const(value))) { + assert(_Py_IsImmortal(get_const(value))); + temp = Py_False; + } + else { + temp = Py_True; + } + res = sym_new_const(ctx, temp); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } + } + + op(_TO_BOOL_LIST, (value -- res)) { + sym_set_type(value, &PyList_Type); + if (is_const(value)) { + res = sym_new_const(ctx, Py_SIZE(get_const(value)) ? Py_True : Py_False); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } + } + + op(_TO_BOOL_NONE, (value -- res)) { + sym_set_type(value, &_PyNone_Type); + res = sym_new_const(ctx, Py_False); + } + + op(_TO_BOOL_STR, (value -- res)) { + sym_set_type(value, &PyUnicode_Type); + if (is_const(value)) { + PyObject *temp = NULL; + if (get_const(value) == &_Py_STR(empty)) { + assert(_Py_IsImmortal(get_const(value))); + temp = Py_False; + } + else { + assert(Py_SIZE(get_const(value))); + temp = Py_True; + } + res = sym_new_const(ctx, temp); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } + } + op(_LOAD_CONST, (-- value)) { // There should be no LOAD_CONST. It should be all // replaced by peephole_opt. @@ -270,9 +326,7 @@ dummy_func(void) { (void)callable; PyFunctionObject *func = (PyFunctionObject *)(this_instr + 2)->operand; - if (func == NULL) { - goto error; - } + ERROR_IF(func == NULL, error); PyCodeObject *co = (PyCodeObject *)func->func_code; assert(self_or_null != NULL); diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index be2fbb9106fffc..000b37b2527748 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -104,45 +104,97 @@ } case _TO_BOOL: { + _Py_UOpsSymType *value; _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); - if (res == NULL) goto out_of_space; + value = stack_pointer[-1]; + sym_set_type(value, &PyBool_Type); + if (is_const(value)) { + int err = PyObject_IsTrue(get_const(value)); + ERROR_IF(err < 0, error); + res = sym_new_const(ctx, err ? Py_True : Py_False); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } stack_pointer[-1] = res; break; } case _TO_BOOL_BOOL: { + _Py_UOpsSymType *value; + value = stack_pointer[-1]; + sym_set_type(value, &PyBool_Type); break; } case _TO_BOOL_INT: { + _Py_UOpsSymType *value; _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); - if (res == NULL) goto out_of_space; + value = stack_pointer[-1]; + sym_set_type(value, &PyLong_Type); + if (is_const(value)) { + PyObject *temp = NULL; + if (_PyLong_IsZero((PyLongObject *)get_const(value))) { + assert(_Py_IsImmortal(get_const(value))); + temp = Py_False; + } + else { + temp = Py_True; + } + res = sym_new_const(ctx, temp); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } stack_pointer[-1] = res; break; } case _TO_BOOL_LIST: { + _Py_UOpsSymType *value; _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); - if (res == NULL) goto out_of_space; + value = stack_pointer[-1]; + sym_set_type(value, &PyList_Type); + if (is_const(value)) { + res = sym_new_const(ctx, Py_SIZE(get_const(value)) ? Py_True : Py_False); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } stack_pointer[-1] = res; break; } case _TO_BOOL_NONE: { + _Py_UOpsSymType *value; _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); - if (res == NULL) goto out_of_space; + value = stack_pointer[-1]; + sym_set_type(value, &_PyNone_Type); + res = sym_new_const(ctx, Py_False); stack_pointer[-1] = res; break; } case _TO_BOOL_STR: { + _Py_UOpsSymType *value; _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); - if (res == NULL) goto out_of_space; + value = stack_pointer[-1]; + sym_set_type(value, &PyUnicode_Type); + if (is_const(value)) { + PyObject *temp = NULL; + if (get_const(value) == &_Py_STR(empty)) { + assert(_Py_IsImmortal(get_const(value))); + temp = Py_False; + } + else { + assert(Py_SIZE(get_const(value))); + temp = Py_True; + } + res = sym_new_const(ctx, temp); + } + else { + res = sym_new_known_type(ctx, &PyBool_Type); + } stack_pointer[-1] = res; break; } @@ -188,9 +240,7 @@ assert(PyLong_CheckExact(get_const(right))); PyObject *temp = _PyLong_Multiply((PyLongObject *)get_const(left), (PyLongObject *)get_const(right)); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -214,9 +264,7 @@ assert(PyLong_CheckExact(get_const(right))); PyObject *temp = _PyLong_Add((PyLongObject *)get_const(left), (PyLongObject *)get_const(right)); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -240,9 +288,7 @@ assert(PyLong_CheckExact(get_const(right))); PyObject *temp = _PyLong_Subtract((PyLongObject *)get_const(left), (PyLongObject *)get_const(right)); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -281,9 +327,7 @@ PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(get_const(left)) * PyFloat_AS_DOUBLE(get_const(right))); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); res = sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -308,9 +352,7 @@ PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(get_const(left)) + PyFloat_AS_DOUBLE(get_const(right))); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); res = sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -335,9 +377,7 @@ PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(get_const(left)) - PyFloat_AS_DOUBLE(get_const(right))); - if (temp == NULL) { - goto error; - } + ERROR_IF(temp == NULL, error); res = sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -1376,9 +1416,7 @@ int argcount = oparg; (void)callable; PyFunctionObject *func = (PyFunctionObject *)(this_instr + 2)->operand; - if (func == NULL) { - goto error; - } + ERROR_IF(func == NULL, error); PyCodeObject *co = (PyCodeObject *)func->func_code; assert(self_or_null != NULL); assert(args != NULL); From 7dba4540625c954e53e24938b4e0e0e14ef0beb9 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 20 Feb 2024 20:57:58 +0800 Subject: [PATCH 02/13] Apply suggestions --- .../tier2_redundancy_eliminator_bytecodes.c | 19 +++---------------- Python/tier2_redundancy_eliminator_cases.c.h | 19 +++---------------- 2 files changed, 6 insertions(+), 32 deletions(-) diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index 7d203440dd349b..35cdbcafcea965 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -178,7 +178,6 @@ dummy_func(void) { } op(_TO_BOOL, (value -- res)) { - sym_set_type(value, &PyBool_Type); if (is_const(value)) { int err = PyObject_IsTrue(get_const(value)); ERROR_IF(err < 0, error); @@ -196,15 +195,8 @@ dummy_func(void) { op(_TO_BOOL_INT, (value -- res)) { sym_set_type(value, &PyLong_Type); if (is_const(value)) { - PyObject *temp = NULL; - if (_PyLong_IsZero((PyLongObject *)get_const(value))) { - assert(_Py_IsImmortal(get_const(value))); - temp = Py_False; - } - else { - temp = Py_True; - } - res = sym_new_const(ctx, temp); + res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) + ? Py_False : Py_True); } else { res = sym_new_known_type(ctx, &PyBool_Type); @@ -213,12 +205,7 @@ dummy_func(void) { op(_TO_BOOL_LIST, (value -- res)) { sym_set_type(value, &PyList_Type); - if (is_const(value)) { - res = sym_new_const(ctx, Py_SIZE(get_const(value)) ? Py_True : Py_False); - } - else { - res = sym_new_known_type(ctx, &PyBool_Type); - } + res = sym_new_known_type(ctx, &PyBool_Type); } op(_TO_BOOL_NONE, (value -- res)) { diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 000b37b2527748..8816718233c437 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -107,7 +107,6 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *res; value = stack_pointer[-1]; - sym_set_type(value, &PyBool_Type); if (is_const(value)) { int err = PyObject_IsTrue(get_const(value)); ERROR_IF(err < 0, error); @@ -133,15 +132,8 @@ value = stack_pointer[-1]; sym_set_type(value, &PyLong_Type); if (is_const(value)) { - PyObject *temp = NULL; - if (_PyLong_IsZero((PyLongObject *)get_const(value))) { - assert(_Py_IsImmortal(get_const(value))); - temp = Py_False; - } - else { - temp = Py_True; - } - res = sym_new_const(ctx, temp); + res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) + ? Py_False : Py_True); } else { res = sym_new_known_type(ctx, &PyBool_Type); @@ -155,12 +147,7 @@ _Py_UOpsSymType *res; value = stack_pointer[-1]; sym_set_type(value, &PyList_Type); - if (is_const(value)) { - res = sym_new_const(ctx, Py_SIZE(get_const(value)) ? Py_True : Py_False); - } - else { - res = sym_new_known_type(ctx, &PyBool_Type); - } + res = sym_new_known_type(ctx, &PyBool_Type); stack_pointer[-1] = res; break; } From 8c4d253a680352ef816e541db49e02ee985f30ed Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 21 Feb 2024 00:14:32 +0800 Subject: [PATCH 03/13] use OUT_OF_SPACE_IF_NULL --- .../tier2_redundancy_eliminator_bytecodes.c | 28 +++++++------------ Python/tier2_redundancy_eliminator_cases.c.h | 28 +++++++------------ 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index 35cdbcafcea965..e652c368c4a90a 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -181,10 +181,10 @@ dummy_func(void) { if (is_const(value)) { int err = PyObject_IsTrue(get_const(value)); ERROR_IF(err < 0, error); - res = sym_new_const(ctx, err ? Py_True : Py_False); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, err ? Py_True : Py_False)); } else { - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } } @@ -195,40 +195,32 @@ dummy_func(void) { op(_TO_BOOL_INT, (value -- res)) { sym_set_type(value, &PyLong_Type); if (is_const(value)) { - res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) - ? Py_False : Py_True); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) + ? Py_False : Py_True)); } else { - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } } op(_TO_BOOL_LIST, (value -- res)) { sym_set_type(value, &PyList_Type); - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } op(_TO_BOOL_NONE, (value -- res)) { sym_set_type(value, &_PyNone_Type); - res = sym_new_const(ctx, Py_False); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); } op(_TO_BOOL_STR, (value -- res)) { sym_set_type(value, &PyUnicode_Type); if (is_const(value)) { - PyObject *temp = NULL; - if (get_const(value) == &_Py_STR(empty)) { - assert(_Py_IsImmortal(get_const(value))); - temp = Py_False; - } - else { - assert(Py_SIZE(get_const(value))); - temp = Py_True; - } - res = sym_new_const(ctx, temp); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, + get_const(value) == &_Py_STR(empty) ? Py_False : Py_True)); } else { - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } } diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 8816718233c437..6216e5c67b9d00 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -110,10 +110,10 @@ if (is_const(value)) { int err = PyObject_IsTrue(get_const(value)); ERROR_IF(err < 0, error); - res = sym_new_const(ctx, err ? Py_True : Py_False); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, err ? Py_True : Py_False)); } else { - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } stack_pointer[-1] = res; break; @@ -132,11 +132,11 @@ value = stack_pointer[-1]; sym_set_type(value, &PyLong_Type); if (is_const(value)) { - res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) - ? Py_False : Py_True); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) + ? Py_False : Py_True)); } else { - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } stack_pointer[-1] = res; break; @@ -147,7 +147,7 @@ _Py_UOpsSymType *res; value = stack_pointer[-1]; sym_set_type(value, &PyList_Type); - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); stack_pointer[-1] = res; break; } @@ -157,7 +157,7 @@ _Py_UOpsSymType *res; value = stack_pointer[-1]; sym_set_type(value, &_PyNone_Type); - res = sym_new_const(ctx, Py_False); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); stack_pointer[-1] = res; break; } @@ -168,19 +168,11 @@ value = stack_pointer[-1]; sym_set_type(value, &PyUnicode_Type); if (is_const(value)) { - PyObject *temp = NULL; - if (get_const(value) == &_Py_STR(empty)) { - assert(_Py_IsImmortal(get_const(value))); - temp = Py_False; - } - else { - assert(Py_SIZE(get_const(value))); - temp = Py_True; - } - res = sym_new_const(ctx, temp); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, + get_const(value) == &_Py_STR(empty) ? Py_False : Py_True)); } else { - res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } stack_pointer[-1] = res; break; From 6d35c169c4180ba5b7be9c58914bb59ceefc5aa3 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:08:12 +0800 Subject: [PATCH 04/13] Address review --- .../tier2_redundancy_eliminator_bytecodes.c | 22 +++++++++++-------- Python/tier2_redundancy_eliminator_cases.c.h | 22 +++++++++++-------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index e652c368c4a90a..68c7fe6c658072 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -178,23 +178,23 @@ dummy_func(void) { } op(_TO_BOOL, (value -- res)) { - if (is_const(value)) { - int err = PyObject_IsTrue(get_const(value)); - ERROR_IF(err < 0, error); - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, err ? Py_True : Py_False)); - } - else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); - } + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } op(_TO_BOOL_BOOL, (value -- value)) { - sym_set_type(value, &PyBool_Type); + if (sym_matches_type(value, &PyBool_Type)) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + else { + sym_set_type(value, &PyBool_Type); + } } op(_TO_BOOL_INT, (value -- res)) { sym_set_type(value, &PyLong_Type); if (is_const(value)) { + // TODO gh-115759: + // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) ? Py_False : Py_True)); } @@ -209,6 +209,8 @@ dummy_func(void) { } op(_TO_BOOL_NONE, (value -- res)) { + // TODO gh-115759: + // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW sym_set_type(value, &_PyNone_Type); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); } @@ -216,6 +218,8 @@ dummy_func(void) { op(_TO_BOOL_STR, (value -- res)) { sym_set_type(value, &PyUnicode_Type); if (is_const(value)) { + // TODO gh-115759: + // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, get_const(value) == &_Py_STR(empty) ? Py_False : Py_True)); } diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 6216e5c67b9d00..b161b74a0b3a58 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -107,14 +107,7 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *res; value = stack_pointer[-1]; - if (is_const(value)) { - int err = PyObject_IsTrue(get_const(value)); - ERROR_IF(err < 0, error); - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, err ? Py_True : Py_False)); - } - else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); - } + OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); stack_pointer[-1] = res; break; } @@ -122,7 +115,12 @@ case _TO_BOOL_BOOL: { _Py_UOpsSymType *value; value = stack_pointer[-1]; - sym_set_type(value, &PyBool_Type); + if (sym_matches_type(value, &PyBool_Type)) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + else { + sym_set_type(value, &PyBool_Type); + } break; } @@ -132,6 +130,8 @@ value = stack_pointer[-1]; sym_set_type(value, &PyLong_Type); if (is_const(value)) { + // TODO gh-115759: + // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) ? Py_False : Py_True)); } @@ -156,6 +156,8 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *res; value = stack_pointer[-1]; + // TODO gh-115759: + // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW sym_set_type(value, &_PyNone_Type); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); stack_pointer[-1] = res; @@ -168,6 +170,8 @@ value = stack_pointer[-1]; sym_set_type(value, &PyUnicode_Type); if (is_const(value)) { + // TODO gh-115759: + // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, get_const(value) == &_Py_STR(empty) ? Py_False : Py_True)); } From e909451b907b913e3de8d79ea98c9b77f1a2ab27 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:39:02 +0800 Subject: [PATCH 05/13] Address Mark's review --- Include/internal/pycore_uop_ids.h | 15 +++++----- Include/internal/pycore_uop_metadata.h | 2 ++ Python/bytecodes.c | 5 ++++ Python/executor_cases.c.h | 12 ++++++++ .../tier2_redundancy_eliminator_bytecodes.c | 21 +++++++------- Python/tier2_redundancy_eliminator_cases.c.h | 29 ++++++++++++------- 6 files changed, 57 insertions(+), 27 deletions(-) diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 9bb537d355055d..14dc9818354cfd 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -232,13 +232,14 @@ extern "C" { #define _CHECK_VALIDITY 379 #define _LOAD_CONST_INLINE 380 #define _LOAD_CONST_INLINE_BORROW 381 -#define _LOAD_CONST_INLINE_WITH_NULL 382 -#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 383 -#define _CHECK_GLOBALS 384 -#define _CHECK_BUILTINS 385 -#define _INTERNAL_INCREMENT_OPT_COUNTER 386 -#define _CHECK_VALIDITY_AND_SET_IP 387 -#define MAX_UOP_ID 387 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 382 +#define _LOAD_CONST_INLINE_WITH_NULL 383 +#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 384 +#define _CHECK_GLOBALS 385 +#define _CHECK_BUILTINS 386 +#define _INTERNAL_INCREMENT_OPT_COUNTER 387 +#define _CHECK_VALIDITY_AND_SET_IP 388 +#define MAX_UOP_ID 388 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 163a0320aa2298..247c499f740a9e 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -204,6 +204,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_CHECK_VALIDITY] = HAS_DEOPT_FLAG, [_LOAD_CONST_INLINE] = HAS_PURE_FLAG, [_LOAD_CONST_INLINE_BORROW] = HAS_PURE_FLAG, + [_POP_TOP_LOAD_CONST_INLINE_BORROW] = HAS_PURE_FLAG, [_LOAD_CONST_INLINE_WITH_NULL] = HAS_PURE_FLAG, [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = HAS_PURE_FLAG, [_CHECK_GLOBALS] = HAS_DEOPT_FLAG, @@ -367,6 +368,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_POP_EXCEPT] = "_POP_EXCEPT", [_POP_FRAME] = "_POP_FRAME", [_POP_TOP] = "_POP_TOP", + [_POP_TOP_LOAD_CONST_INLINE_BORROW] = "_POP_TOP_LOAD_CONST_INLINE_BORROW", [_PUSH_EXC_INFO] = "_PUSH_EXC_INFO", [_PUSH_FRAME] = "_PUSH_FRAME", [_PUSH_NULL] = "_PUSH_NULL", diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 6822e772e913e8..30c77eb5be235b 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4072,6 +4072,11 @@ dummy_func( TIER_TWO_ONLY value = ptr; } + pure op (_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) { + TIER_TWO_ONLY; + DECREF_INPUTS(); + value = ptr; + } pure op(_LOAD_CONST_INLINE_WITH_NULL, (ptr/4 -- value, null)) { TIER_TWO_ONLY diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 11e2a1fe85d51d..ccc1093d025c1e 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3408,6 +3408,18 @@ break; } + case _POP_TOP_LOAD_CONST_INLINE_BORROW: { + PyObject *pop; + PyObject *value; + pop = stack_pointer[-1]; + PyObject *ptr = (PyObject *)CURRENT_OPERAND(); + TIER_TWO_ONLY; + Py_DECREF(pop); + value = ptr; + stack_pointer[-1] = value; + break; + } + case _LOAD_CONST_INLINE_WITH_NULL: { PyObject *value; PyObject *null; diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index 68c7fe6c658072..e916c37ab76302 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -178,6 +178,7 @@ dummy_func(void) { } op(_TO_BOOL, (value -- res)) { + (void)value; OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); } @@ -193,10 +194,10 @@ dummy_func(void) { op(_TO_BOOL_INT, (value -- res)) { sym_set_type(value, &PyLong_Type); if (is_const(value)) { - // TODO gh-115759: - // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) - ? Py_False : Py_True)); + PyObject *load = _PyLong_IsZero((PyLongObject *)get_const(value)) + ? Py_False : Py_True; + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); @@ -209,8 +210,9 @@ dummy_func(void) { } op(_TO_BOOL_NONE, (value -- res)) { - // TODO gh-115759: - // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW + if (get_const(value) == Py_None) { + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_None); + } sym_set_type(value, &_PyNone_Type); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); } @@ -218,10 +220,9 @@ dummy_func(void) { op(_TO_BOOL_STR, (value -- res)) { sym_set_type(value, &PyUnicode_Type); if (is_const(value)) { - // TODO gh-115759: - // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, - get_const(value) == &_Py_STR(empty) ? Py_False : Py_True)); + PyObject *load = get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index b161b74a0b3a58..cde29d5e3aa1c1 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -107,6 +107,7 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *res; value = stack_pointer[-1]; + (void)value; OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); stack_pointer[-1] = res; break; @@ -130,10 +131,10 @@ value = stack_pointer[-1]; sym_set_type(value, &PyLong_Type); if (is_const(value)) { - // TODO gh-115759: - // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, _PyLong_IsZero((PyLongObject *)get_const(value)) - ? Py_False : Py_True)); + PyObject *load = _PyLong_IsZero((PyLongObject *)get_const(value)) + ? Py_False : Py_True; + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); @@ -156,8 +157,9 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *res; value = stack_pointer[-1]; - // TODO gh-115759: - // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW + if (get_const(value) == Py_None) { + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_None); + } sym_set_type(value, &_PyNone_Type); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); stack_pointer[-1] = res; @@ -170,10 +172,9 @@ value = stack_pointer[-1]; sym_set_type(value, &PyUnicode_Type); if (is_const(value)) { - // TODO gh-115759: - // if value is None, we caxn replace with a _POP_TOP; _LOAD_CONST_BORROW - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, - get_const(value) == &_Py_STR(empty) ? Py_False : Py_True)); + PyObject *load = get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); + OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); @@ -1723,6 +1724,14 @@ break; } + case _POP_TOP_LOAD_CONST_INLINE_BORROW: { + _Py_UOpsSymType *value; + value = sym_new_unknown(ctx); + if (value == NULL) goto out_of_space; + stack_pointer[-1] = value; + break; + } + case _LOAD_CONST_INLINE_WITH_NULL: { _Py_UOpsSymType *value; _Py_UOpsSymType *null; From 3315ac54938838983926091e9af4acd313ac92bb Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 22 Feb 2024 01:43:01 +0800 Subject: [PATCH 06/13] partially address review --- Python/optimizer_analysis.c | 6 +++--- Python/tier2_redundancy_eliminator_bytecodes.c | 5 +++-- Python/tier2_redundancy_eliminator_cases.c.h | 5 +++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index fdd1d0c5c5593f..c45f412f40926b 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -596,10 +596,10 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, } while (0); #define ERROR_IF(COND, LABEL) \ - do { \ - if (COND) { \ + do { \ + if (COND) { \ goto LABEL; \ - } \ + } \ } while (0); #define _LOAD_ATTR_NOT_NULL \ diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index e916c37ab76302..a47d3d6074839b 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -179,7 +179,8 @@ dummy_func(void) { op(_TO_BOOL, (value -- res)) { (void)value; - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res); } op(_TO_BOOL_BOOL, (value -- value)) { @@ -211,7 +212,7 @@ dummy_func(void) { op(_TO_BOOL_NONE, (value -- res)) { if (get_const(value) == Py_None) { - REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_None); + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } sym_set_type(value, &_PyNone_Type); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index cde29d5e3aa1c1..8cf54dce8004d1 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -108,7 +108,8 @@ _Py_UOpsSymType *res; value = stack_pointer[-1]; (void)value; - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + res = sym_new_known_type(ctx, &PyBool_Type); + OUT_OF_SPACE_IF_NULL(res); stack_pointer[-1] = res; break; } @@ -158,7 +159,7 @@ _Py_UOpsSymType *res; value = stack_pointer[-1]; if (get_const(value) == Py_None) { - REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_None); + REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } sym_set_type(value, &_PyNone_Type); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); From 6c92d35544ae667f6ab311b7bd32d6a4a2ad98ab Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 22 Feb 2024 19:35:36 +0800 Subject: [PATCH 07/13] apply suggestions --- Python/bytecodes.c | 2 +- Python/tier2_redundancy_eliminator_bytecodes.c | 2 +- Python/tier2_redundancy_eliminator_cases.c.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 30c77eb5be235b..72fdf5c37da2aa 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4074,7 +4074,7 @@ dummy_func( } pure op (_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) { TIER_TWO_ONLY; - DECREF_INPUTS(); + Py_DECREF(pop); value = ptr; } diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index a47d3d6074839b..82e34e1d78974a 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -214,7 +214,7 @@ dummy_func(void) { if (get_const(value) == Py_None) { REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } - sym_set_type(value, &_PyNone_Type); + sym_set_const(value, Py_None); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); } diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 8cf54dce8004d1..e8d894615de4de 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -161,7 +161,7 @@ if (get_const(value) == Py_None) { REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } - sym_set_type(value, &_PyNone_Type); + sym_set_const(value, Py_None); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, Py_False)); stack_pointer[-1] = res; break; From 6018440efcb79a3cb07c26de37c50917aff8894e Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Fri, 23 Feb 2024 15:53:29 +0800 Subject: [PATCH 08/13] fix compilation problems --- Python/optimizer_analysis.c | 8 ++++++++ Python/tier2_redundancy_eliminator_bytecodes.c | 4 ++-- Python/tier2_redundancy_eliminator_cases.c.h | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 5cdbfe228d99b5..8a91e7cb130006 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -301,6 +301,14 @@ sym_set_null(_Py_UOpsSymType *sym) sym_set_flag(sym, KNOWN); } +static inline void +sym_set_const(_Py_UOpsSymType *sym, PyObject *const_val) +{ + sym_set_type(sym, Py_TYPE(const_val)); + sym_set_flag(sym, TRUE_CONST | KNOWN | NOT_NULL); + Py_XSETREF(sym->const_val, Py_NewRef(const_val)); + assert(sym_is_const(sym)); +} static inline _Py_UOpsSymType* sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx) diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index f92655898c07d2..56b4aa1184c165 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -229,8 +229,8 @@ dummy_func(void) { op(_TO_BOOL_STR, (value -- res)) { sym_set_type(value, &PyUnicode_Type); - if (is_const(value)) { - PyObject *load = get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; + if (sym_is_const(value)) { + PyObject *load = sym_get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 002bfff23ead81..1371ccfef2d500 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -172,8 +172,8 @@ _Py_UOpsSymType *res; value = stack_pointer[-1]; sym_set_type(value, &PyUnicode_Type); - if (is_const(value)) { - PyObject *load = get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; + if (sym_is_const(value)) { + PyObject *load = sym_get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } From 7a480e870b7cb2db4f958aaf0d5a6dc8f67697d1 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Fri, 23 Feb 2024 23:56:03 +0800 Subject: [PATCH 09/13] Forgot sym_is_const --- Python/tier2_redundancy_eliminator_bytecodes.c | 2 +- Python/tier2_redundancy_eliminator_cases.c.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index 56b4aa1184c165..25ffea750dab70 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -220,7 +220,7 @@ dummy_func(void) { } op(_TO_BOOL_NONE, (value -- res)) { - if (sym_get_const(value) == Py_None) { + if (sym_is_const(value) && (sym_get_const(value) == Py_None)) { REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } sym_set_const(value, Py_None); diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 1371ccfef2d500..535b8d421d184a 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -158,7 +158,7 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *res; value = stack_pointer[-1]; - if (sym_get_const(value) == Py_None) { + if (sym_is_const(value) && (sym_get_const(value) == Py_None)) { REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } sym_set_const(value, Py_None); From 52122314f2af1a73f6605a9e9d22ba687dcc5ca8 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 29 Feb 2024 04:48:15 +0800 Subject: [PATCH 10/13] remove unneded code --- Python/optimizer_analysis.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 8a91e7cb130006..5cdbfe228d99b5 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -301,14 +301,6 @@ sym_set_null(_Py_UOpsSymType *sym) sym_set_flag(sym, KNOWN); } -static inline void -sym_set_const(_Py_UOpsSymType *sym, PyObject *const_val) -{ - sym_set_type(sym, Py_TYPE(const_val)); - sym_set_flag(sym, TRUE_CONST | KNOWN | NOT_NULL); - Py_XSETREF(sym->const_val, Py_NewRef(const_val)); - assert(sym_is_const(sym)); -} static inline _Py_UOpsSymType* sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx) From 4c9c97bbabbf7397afc44b34c0f1443a8a056afe Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 29 Feb 2024 04:55:10 +0800 Subject: [PATCH 11/13] Merge upstream changes --- Python/bytecodes.c | 3 +-- Python/executor_cases.c.h | 1 - Python/optimizer_analysis.c | 7 ------ Python/optimizer_bytecodes.c | 46 +++++++++++++++++++++++------------- Python/optimizer_cases.c.h | 46 +++++++++++++++++++++++------------- 5 files changed, 61 insertions(+), 42 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4c908b7af48e88..3349030a8ca88a 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4042,8 +4042,7 @@ dummy_func( tier2 pure op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) { value = ptr; } - pure op (_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) { - TIER_TWO_ONLY; + tier2 pure op (_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) { Py_DECREF(pop); value = ptr; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 1cf41d8bb353ac..10548a8d15a5de 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3764,7 +3764,6 @@ PyObject *value; pop = stack_pointer[-1]; PyObject *ptr = (PyObject *)CURRENT_OPERAND(); - TIER_TWO_ONLY; Py_DECREF(pop); value = ptr; stack_pointer[-1] = value; diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 561c4da4455e86..8e408ffbb1c2b5 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -275,13 +275,6 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, } \ } while (0); -#define ERROR_IF(COND, LABEL) \ - do { \ - if (COND) { \ - goto LABEL; \ - } \ - } while (0); - #define _LOAD_ATTR_NOT_NULL \ do { \ OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); \ diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index cd9e533ac12bd8..fd30a735dfe34d 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -112,7 +112,9 @@ dummy_func(void) { assert(PyLong_CheckExact(sym_get_const(right))); PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(left), (PyLongObject *)sym_get_const(right)); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -128,7 +130,9 @@ dummy_func(void) { assert(PyLong_CheckExact(sym_get_const(right))); PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(left), (PyLongObject *)sym_get_const(right)); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -144,7 +148,9 @@ dummy_func(void) { assert(PyLong_CheckExact(sym_get_const(right))); PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(left), (PyLongObject *)sym_get_const(right)); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -161,7 +167,9 @@ dummy_func(void) { PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(sym_get_const(left)) + PyFloat_AS_DOUBLE(sym_get_const(right))); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -178,7 +186,9 @@ dummy_func(void) { PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(sym_get_const(left)) - PyFloat_AS_DOUBLE(sym_get_const(right))); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -195,7 +205,9 @@ dummy_func(void) { PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(sym_get_const(left)) * PyFloat_AS_DOUBLE(sym_get_const(right))); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -207,7 +219,7 @@ dummy_func(void) { op(_TO_BOOL, (value -- res)) { (void)value; - res = sym_new_known_type(ctx, &PyBool_Type); + res = sym_new_type(ctx, &PyBool_Type); OUT_OF_SPACE_IF_NULL(res); } @@ -221,25 +233,25 @@ dummy_func(void) { } op(_TO_BOOL_INT, (value -- res)) { - sym_set_type(value, &PyLong_Type); - if (sym_is_const(value)) { + if (sym_is_const(value) && sym_matches_type(value, &PyLong_Type)) { PyObject *load = _PyLong_IsZero((PyLongObject *)sym_get_const(value)) ? Py_False : Py_True; REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } + sym_set_type(value, &PyLong_Type); } op(_TO_BOOL_LIST, (value -- res)) { sym_set_type(value, &PyList_Type); - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } op(_TO_BOOL_NONE, (value -- res)) { - if (sym_is_const(value) && (sym_get_const(value) == Py_None)) { + if (sym_get_const(value) == Py_None) { REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } sym_set_const(value, Py_None); @@ -247,15 +259,15 @@ dummy_func(void) { } op(_TO_BOOL_STR, (value -- res)) { - sym_set_type(value, &PyUnicode_Type); - if (sym_is_const(value)) { + if (sym_is_const(value) && sym_matches_type(value, &PyUnicode_Type)) { PyObject *load = sym_get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } + sym_set_type(value, &PyUnicode_Type); } op(_LOAD_CONST, (-- value)) { @@ -397,7 +409,9 @@ dummy_func(void) { (void)callable; PyFunctionObject *func = (PyFunctionObject *)(this_instr + 2)->operand; - ERROR_IF(func == NULL, error); + if (func == NULL) { + goto error; + } PyCodeObject *co = (PyCodeObject *)func->func_code; assert(self_or_null != NULL); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index a8eb0719b763ad..4ed7ec51100397 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -108,7 +108,7 @@ _Py_UopsSymbol *res; value = stack_pointer[-1]; (void)value; - res = sym_new_known_type(ctx, &PyBool_Type); + res = sym_new_type(ctx, &PyBool_Type); OUT_OF_SPACE_IF_NULL(res); stack_pointer[-1] = res; break; @@ -130,16 +130,16 @@ _Py_UopsSymbol *value; _Py_UopsSymbol *res; value = stack_pointer[-1]; - sym_set_type(value, &PyLong_Type); - if (sym_is_const(value)) { + if (sym_is_const(value) && sym_matches_type(value, &PyLong_Type)) { PyObject *load = _PyLong_IsZero((PyLongObject *)sym_get_const(value)) ? Py_False : Py_True; REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } + sym_set_type(value, &PyLong_Type); stack_pointer[-1] = res; break; } @@ -149,7 +149,7 @@ _Py_UopsSymbol *res; value = stack_pointer[-1]; sym_set_type(value, &PyList_Type); - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); stack_pointer[-1] = res; break; } @@ -158,7 +158,7 @@ _Py_UopsSymbol *value; _Py_UopsSymbol *res; value = stack_pointer[-1]; - if (sym_is_const(value) && (sym_get_const(value) == Py_None)) { + if (sym_get_const(value) == Py_None) { REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_False); } sym_set_const(value, Py_None); @@ -171,15 +171,15 @@ _Py_UopsSymbol *value; _Py_UopsSymbol *res; value = stack_pointer[-1]; - sym_set_type(value, &PyUnicode_Type); - if (sym_is_const(value)) { + if (sym_is_const(value) && sym_matches_type(value, &PyUnicode_Type)) { PyObject *load = sym_get_const(value) == &_Py_STR(empty) ? Py_False : Py_True; REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load); OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, load)); } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyBool_Type)); + OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } + sym_set_type(value, &PyUnicode_Type); stack_pointer[-1] = res; break; } @@ -225,7 +225,9 @@ assert(PyLong_CheckExact(sym_get_const(right))); PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(left), (PyLongObject *)sym_get_const(right)); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -249,7 +251,9 @@ assert(PyLong_CheckExact(sym_get_const(right))); PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(left), (PyLongObject *)sym_get_const(right)); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -273,7 +277,9 @@ assert(PyLong_CheckExact(sym_get_const(right))); PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(left), (PyLongObject *)sym_get_const(right)); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! @@ -312,7 +318,9 @@ PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(sym_get_const(left)) * PyFloat_AS_DOUBLE(sym_get_const(right))); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -337,7 +345,9 @@ PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(sym_get_const(left)) + PyFloat_AS_DOUBLE(sym_get_const(right))); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -362,7 +372,9 @@ PyObject *temp = PyFloat_FromDouble( PyFloat_AS_DOUBLE(sym_get_const(left)) - PyFloat_AS_DOUBLE(sym_get_const(right))); - ERROR_IF(temp == NULL, error); + if (temp == NULL) { + goto error; + } OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and update tests! @@ -1447,7 +1459,9 @@ int argcount = oparg; (void)callable; PyFunctionObject *func = (PyFunctionObject *)(this_instr + 2)->operand; - ERROR_IF(func == NULL, error); + if (func == NULL) { + goto error; + } PyCodeObject *co = (PyCodeObject *)func->func_code; assert(self_or_null != NULL); assert(args != NULL); From 6ddc97c2b93c7c6ed82da3f18f9863036024d769 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Fri, 1 Mar 2024 03:07:04 +0800 Subject: [PATCH 12/13] check for bottom --- Python/optimizer_bytecodes.c | 16 ++++++++++++---- Python/optimizer_cases.c.h | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 1b574541c25475..2b47381ec76db4 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -265,7 +265,9 @@ dummy_func(void) { REPLACE_OP(this_instr, _NOP, 0, 0); } else { - sym_set_type(value, &PyBool_Type); + if(!sym_set_type(value, &PyBool_Type)) { + goto hit_bottom; + } } } @@ -279,11 +281,15 @@ dummy_func(void) { else { OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } - sym_set_type(value, &PyLong_Type); + if(!sym_set_type(value, &PyLong_Type)) { + goto hit_bottom; + } } op(_TO_BOOL_LIST, (value -- res)) { - sym_set_type(value, &PyList_Type); + if(!sym_set_type(value, &PyList_Type)) { + goto hit_bottom; + } OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } @@ -304,7 +310,9 @@ dummy_func(void) { else { OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } - sym_set_type(value, &PyUnicode_Type); + if(!sym_set_type(value, &PyUnicode_Type)) { + goto hit_bottom; + } } op(_LOAD_CONST, (-- value)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 01cd154725916b..9d7ebb80f62857 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -121,7 +121,9 @@ REPLACE_OP(this_instr, _NOP, 0, 0); } else { - sym_set_type(value, &PyBool_Type); + if(!sym_set_type(value, &PyBool_Type)) { + goto hit_bottom; + } } break; } @@ -139,7 +141,9 @@ else { OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } - sym_set_type(value, &PyLong_Type); + if(!sym_set_type(value, &PyLong_Type)) { + goto hit_bottom; + } stack_pointer[-1] = res; break; } @@ -148,7 +152,9 @@ _Py_UopsSymbol *value; _Py_UopsSymbol *res; value = stack_pointer[-1]; - sym_set_type(value, &PyList_Type); + if(!sym_set_type(value, &PyList_Type)) { + goto hit_bottom; + } OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); stack_pointer[-1] = res; break; @@ -179,7 +185,9 @@ else { OUT_OF_SPACE_IF_NULL(res = sym_new_type(ctx, &PyBool_Type)); } - sym_set_type(value, &PyUnicode_Type); + if(!sym_set_type(value, &PyUnicode_Type)) { + goto hit_bottom; + } stack_pointer[-1] = res; break; } From cdd15bde18fdb29c9c6d2937257a2682b3ea4d14 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Fri, 1 Mar 2024 03:12:15 +0800 Subject: [PATCH 13/13] add space --- Python/bytecodes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 7c146514eafb4b..095982d64f34d0 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4042,6 +4042,7 @@ dummy_func( tier2 pure op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) { value = ptr; } + tier2 pure op (_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) { Py_DECREF(pop); value = ptr;