diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2025-03-02 21:21:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-02 21:21:34 (GMT) |
commit | 7afa476874b9a432ad6dbe9fb3e65d62f2999f88 (patch) | |
tree | 53e88fb36267f0bacc8d326f38dcadfb441f8c6e /Python/optimizer_bytecodes.c | |
parent | c6513f7a627c8918a5e3f3733fa47d34a94ddff9 (diff) | |
download | cpython-7afa476874b9a432ad6dbe9fb3e65d62f2999f88.zip cpython-7afa476874b9a432ad6dbe9fb3e65d62f2999f88.tar.gz cpython-7afa476874b9a432ad6dbe9fb3e65d62f2999f88.tar.bz2 |
GH-130415: Use boolean guards to narrow types to values in the JIT (GH-130659)
Diffstat (limited to 'Python/optimizer_bytecodes.c')
-rw-r--r-- | Python/optimizer_bytecodes.c | 115 |
1 files changed, 62 insertions, 53 deletions
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index f3625a1..c4e4b28 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -34,6 +34,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; #define sym_tuple_getitem _Py_uop_sym_tuple_getitem #define sym_tuple_length _Py_uop_sym_tuple_length #define sym_is_immortal _Py_uop_sym_is_immortal +#define sym_new_truthiness _Py_uop_sym_new_truthiness extern int optimize_to_bool( @@ -198,11 +199,11 @@ dummy_func(void) { // Case C: res = sym_new_type(ctx, &PyFloat_Type); } - else if (!sym_is_const(right)) { + else if (!sym_is_const(ctx, right)) { // Case A or B... can't know without the sign of the RHS: res = sym_new_unknown(ctx); } - else if (_PyLong_IsNegative((PyLongObject *)sym_get_const(right))) { + else if (_PyLong_IsNegative((PyLongObject *)sym_get_const(ctx, right))) { // Case B: res = sym_new_type(ctx, &PyFloat_Type); } @@ -223,13 +224,13 @@ dummy_func(void) { } op(_BINARY_OP_ADD_INT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(ctx, left), + (PyLongObject *)sym_get_const(ctx, right)); if (temp == NULL) { goto error; } @@ -244,13 +245,13 @@ dummy_func(void) { } op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(ctx, left), + (PyLongObject *)sym_get_const(ctx, right)); if (temp == NULL) { goto error; } @@ -265,13 +266,13 @@ dummy_func(void) { } op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + assert(PyLong_CheckExact(sym_get_const(ctx, left))); + assert(PyLong_CheckExact(sym_get_const(ctx, right))); + PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(ctx, left), + (PyLongObject *)sym_get_const(ctx, right)); if (temp == NULL) { goto error; } @@ -286,14 +287,14 @@ dummy_func(void) { } op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyFloat_Type) && sym_matches_type(right, &PyFloat_Type)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + assert(PyFloat_CheckExact(sym_get_const(ctx, left))); + assert(PyFloat_CheckExact(sym_get_const(ctx, right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) + - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) + + PyFloat_AS_DOUBLE(sym_get_const(ctx, right))); if (temp == NULL) { goto error; } @@ -308,14 +309,14 @@ dummy_func(void) { } op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyFloat_Type) && sym_matches_type(right, &PyFloat_Type)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + assert(PyFloat_CheckExact(sym_get_const(ctx, left))); + assert(PyFloat_CheckExact(sym_get_const(ctx, right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) - - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) - + PyFloat_AS_DOUBLE(sym_get_const(ctx, right))); if (temp == NULL) { goto error; } @@ -330,14 +331,14 @@ dummy_func(void) { } op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyFloat_Type) && sym_matches_type(right, &PyFloat_Type)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + assert(PyFloat_CheckExact(sym_get_const(ctx, left))); + assert(PyFloat_CheckExact(sym_get_const(ctx, right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) * - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) * + PyFloat_AS_DOUBLE(sym_get_const(ctx, right))); if (temp == NULL) { goto error; } @@ -352,9 +353,9 @@ dummy_func(void) { } op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyUnicode_Type) && sym_matches_type(right, &PyUnicode_Type)) { - PyObject *temp = PyUnicode_Concat(sym_get_const(left), sym_get_const(right)); + PyObject *temp = PyUnicode_Concat(sym_get_const(ctx, left), sym_get_const(ctx, right)); if (temp == NULL) { goto error; } @@ -368,9 +369,9 @@ dummy_func(void) { op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- )) { JitOptSymbol *res; - if (sym_is_const(left) && sym_is_const(right) && + if (sym_is_const(ctx, left) && sym_is_const(ctx, right) && sym_matches_type(left, &PyUnicode_Type) && sym_matches_type(right, &PyUnicode_Type)) { - PyObject *temp = PyUnicode_Concat(sym_get_const(left), sym_get_const(right)); + PyObject *temp = PyUnicode_Concat(sym_get_const(ctx, left), sym_get_const(ctx, right)); if (temp == NULL) { goto error; } @@ -391,14 +392,14 @@ dummy_func(void) { op(_TO_BOOL, (value -- res)) { if (!optimize_to_bool(this_instr, ctx, value, &res)) { - res = sym_new_type(ctx, &PyBool_Type); + res = sym_new_truthiness(ctx, value, true); } } op(_TO_BOOL_BOOL, (value -- res)) { if (!optimize_to_bool(this_instr, ctx, value, &res)) { sym_set_type(value, &PyBool_Type); - res = value; + res = sym_new_truthiness(ctx, value, true); } } @@ -430,6 +431,11 @@ dummy_func(void) { } } + op(_UNARY_NOT, (value -- res)) { + sym_set_type(value, &PyBool_Type); + res = sym_new_truthiness(ctx, value, false); + } + op(_COMPARE_OP, (left, right -- res)) { if (oparg & 16) { res = sym_new_type(ctx, &PyBool_Type); @@ -521,8 +527,8 @@ dummy_func(void) { (void)dict_version; (void)index; attr = NULL; - if (sym_is_const(owner)) { - PyModuleObject *mod = (PyModuleObject *)sym_get_const(owner); + if (sym_is_const(ctx, owner)) { + PyModuleObject *mod = (PyModuleObject *)sym_get_const(ctx, owner); if (PyModule_CheckExact(mod)) { PyObject *dict = mod->md_dict; uint64_t watched_mutations = get_mutations(dict); @@ -599,19 +605,19 @@ dummy_func(void) { } op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { - if (sym_is_const(callable) && sym_matches_type(callable, &PyFunction_Type)) { - assert(PyFunction_Check(sym_get_const(callable))); + if (sym_is_const(ctx, callable) && sym_matches_type(callable, &PyFunction_Type)) { + assert(PyFunction_Check(sym_get_const(ctx, callable))); REPLACE_OP(this_instr, _CHECK_FUNCTION_VERSION_INLINE, 0, func_version); - this_instr->operand1 = (uintptr_t)sym_get_const(callable); + this_instr->operand1 = (uintptr_t)sym_get_const(ctx, callable); } sym_set_type(callable, &PyFunction_Type); } op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { assert(sym_matches_type(callable, &PyFunction_Type)); - if (sym_is_const(callable)) { + if (sym_is_const(ctx, callable)) { if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - PyFunctionObject *func = (PyFunctionObject *)sym_get_const(callable); + PyFunctionObject *func = (PyFunctionObject *)sym_get_const(ctx, callable); PyCodeObject *co = (PyCodeObject *)func->func_code; if (co->co_argcount == oparg + !sym_is_null(self_or_null)) { REPLACE_OP(this_instr, _NOP, 0 ,0); @@ -812,24 +818,26 @@ dummy_func(void) { } op(_GUARD_IS_TRUE_POP, (flag -- )) { - if (sym_is_const(flag)) { - PyObject *value = sym_get_const(flag); + if (sym_is_const(ctx, flag)) { + PyObject *value = sym_get_const(ctx, flag); assert(value != NULL); eliminate_pop_guard(this_instr, value != Py_True); } + sym_set_const(flag, Py_True); } op(_GUARD_IS_FALSE_POP, (flag -- )) { - if (sym_is_const(flag)) { - PyObject *value = sym_get_const(flag); + if (sym_is_const(ctx, flag)) { + PyObject *value = sym_get_const(ctx, flag); assert(value != NULL); eliminate_pop_guard(this_instr, value != Py_False); } + sym_set_const(flag, Py_False); } op(_GUARD_IS_NONE_POP, (flag -- )) { - if (sym_is_const(flag)) { - PyObject *value = sym_get_const(flag); + if (sym_is_const(ctx, flag)) { + PyObject *value = sym_get_const(ctx, flag); assert(value != NULL); eliminate_pop_guard(this_instr, !Py_IsNone(value)); } @@ -837,11 +845,12 @@ dummy_func(void) { assert(!sym_matches_type(flag, &_PyNone_Type)); eliminate_pop_guard(this_instr, true); } + sym_set_const(flag, Py_None); } op(_GUARD_IS_NOT_NONE_POP, (flag -- )) { - if (sym_is_const(flag)) { - PyObject *value = sym_get_const(flag); + if (sym_is_const(ctx, flag)) { + PyObject *value = sym_get_const(ctx, flag); assert(value != NULL); eliminate_pop_guard(this_instr, Py_IsNone(value)); } |