summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-05-31 15:09:23 (GMT)
committerGitHub <noreply@github.com>2023-05-31 15:09:23 (GMT)
commitdf396b59af9d50892e5e30463300e8458cb84263 (patch)
tree9361299693ffb3cb8c5fecadacea0218c4cf7929 /Python/bytecodes.c
parentfbc9d0dbb22549bac2706f61f3ab631239d357b4 (diff)
downloadcpython-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.c114
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,