diff options
author | Guido van Rossum <guido@python.org> | 2023-05-31 15:09:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-31 15:09:23 (GMT) |
commit | df396b59af9d50892e5e30463300e8458cb84263 (patch) | |
tree | 9361299693ffb3cb8c5fecadacea0218c4cf7929 /Python/bytecodes.c | |
parent | fbc9d0dbb22549bac2706f61f3ab631239d357b4 (diff) | |
download | cpython-df396b59af9d50892e5e30463300e8458cb84263.zip cpython-df396b59af9d50892e5e30463300e8458cb84263.tar.gz cpython-df396b59af9d50892e5e30463300e8458cb84263.tar.bz2 |
gh-104909: Split BINARY_OP into micro-ops (#104910)
Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 114 |
1 files changed, 68 insertions, 46 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 0baf245..5f73fc8 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -279,57 +279,94 @@ dummy_func( family(binary_op, INLINE_CACHE_ENTRIES_BINARY_OP) = { BINARY_OP, - BINARY_OP_ADD_FLOAT, + BINARY_OP_MULTIPLY_INT, BINARY_OP_ADD_INT, - BINARY_OP_ADD_UNICODE, - // BINARY_OP_INPLACE_ADD_UNICODE, // This is an odd duck. + BINARY_OP_SUBTRACT_INT, BINARY_OP_MULTIPLY_FLOAT, - BINARY_OP_MULTIPLY_INT, + BINARY_OP_ADD_FLOAT, BINARY_OP_SUBTRACT_FLOAT, - BINARY_OP_SUBTRACT_INT, + BINARY_OP_ADD_UNICODE, + // BINARY_OP_INPLACE_ADD_UNICODE, // See comments at that opcode. }; - - inst(BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- prod)) { + op(_GUARD_BOTH_INT, (left, right -- left, right)) { DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + } + + op(_BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- res)) { STAT_INC(BINARY_OP, hit); - prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); + res = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - ERROR_IF(prod == NULL, error); + ERROR_IF(res == NULL, error); } - inst(BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- prod)) { - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + op(_BINARY_OP_ADD_INT, (unused/1, left, right -- res)) { STAT_INC(BINARY_OP, hit); - double dprod = ((PyFloatObject *)left)->ob_fval * - ((PyFloatObject *)right)->ob_fval; - DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod); + res = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(res == NULL, error); } - inst(BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- sub)) { - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + op(_BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- res)) { STAT_INC(BINARY_OP, hit); - sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); + res = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - ERROR_IF(sub == NULL, error); + ERROR_IF(res == NULL, error); } - inst(BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- sub)) { + macro(BINARY_OP_MULTIPLY_INT) = + _GUARD_BOTH_INT + _BINARY_OP_MULTIPLY_INT; + macro(BINARY_OP_ADD_INT) = + _GUARD_BOTH_INT + _BINARY_OP_ADD_INT; + macro(BINARY_OP_SUBTRACT_INT) = + _GUARD_BOTH_INT + _BINARY_OP_SUBTRACT_INT; + + op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) { DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + } + + op(_BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- res)) { STAT_INC(BINARY_OP, hit); - double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; - DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub); + double dres = + ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); + } + + op(_BINARY_OP_ADD_FLOAT, (unused/1, left, right -- res)) { + STAT_INC(BINARY_OP, hit); + double dres = + ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); + } + + op(_BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- res)) { + STAT_INC(BINARY_OP, hit); + double dres = + ((PyFloatObject *)left)->ob_fval - + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); } - inst(BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) { + macro(BINARY_OP_MULTIPLY_FLOAT) = + _GUARD_BOTH_FLOAT + _BINARY_OP_MULTIPLY_FLOAT; + macro(BINARY_OP_ADD_FLOAT) = + _GUARD_BOTH_FLOAT + _BINARY_OP_ADD_FLOAT; + macro(BINARY_OP_SUBTRACT_FLOAT) = + _GUARD_BOTH_FLOAT + _BINARY_OP_SUBTRACT_FLOAT; + + op(_GUARD_BOTH_UNICODE, (left, right -- left, right)) { DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); + } + + op(_BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) { STAT_INC(BINARY_OP, hit); res = PyUnicode_Concat(left, right); _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); @@ -337,15 +374,16 @@ dummy_func( ERROR_IF(res == NULL, error); } + macro(BINARY_OP_ADD_UNICODE) = + _GUARD_BOTH_UNICODE + _BINARY_OP_ADD_UNICODE; + // This is a subtle one. It's a super-instruction for // BINARY_OP_ADD_UNICODE followed by STORE_FAST // where the store goes into the left argument. // So the inputs are the same as for all BINARY_OP // specializations, but there is no output. // At the end we just skip over the STORE_FAST. - inst(BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) { - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) { _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; assert(true_next.op.code == STORE_FAST || true_next.op.code == STORE_FAST__LOAD_FAST); @@ -372,24 +410,8 @@ dummy_func( JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); } - inst(BINARY_OP_ADD_FLOAT, (unused/1, left, right -- sum)) { - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dsum = ((PyFloatObject *)left)->ob_fval + - ((PyFloatObject *)right)->ob_fval; - DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum); - } - - inst(BINARY_OP_ADD_INT, (unused/1, left, right -- sum)) { - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); - _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - ERROR_IF(sum == NULL, error); - } + macro(BINARY_OP_INPLACE_ADD_UNICODE) = + _GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE; family(binary_subscr, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = { BINARY_SUBSCR, |