Skip to content

Commit 345ba3f

Browse files
authored
bpo-45510: Specialize BINARY_SUBTRACT (GH-29523)
1 parent 0920b61 commit 345ba3f

File tree

7 files changed

+107
-50
lines changed

7 files changed

+107
-50
lines changed

Include/internal/pycore_long.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static inline PyObject* _PyLong_GetOne(void)
2323

2424
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
2525
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
26+
PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
2627

2728
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
2829
_PyBytes_DecodeEscape(), etc. */

Include/opcode.h

Lines changed: 35 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/opcode.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ def jabs_op(name, op):
231231
"BINARY_OP_INPLACE_ADD_UNICODE",
232232
"BINARY_OP_MULTIPLY_INT",
233233
"BINARY_OP_MULTIPLY_FLOAT",
234+
"BINARY_OP_SUBTRACT_INT",
235+
"BINARY_OP_SUBTRACT_FLOAT",
234236
"BINARY_SUBSCR_ADAPTIVE",
235237
"BINARY_SUBSCR_LIST_INT",
236238
"BINARY_SUBSCR_TUPLE_INT",

Objects/longobject.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,14 +3155,11 @@ long_add(PyLongObject *a, PyLongObject *b)
31553155
return _PyLong_Add(a, b);
31563156
}
31573157

3158-
3159-
static PyObject *
3160-
long_sub(PyLongObject *a, PyLongObject *b)
3158+
PyObject *
3159+
_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
31613160
{
31623161
PyLongObject *z;
31633162

3164-
CHECK_BINOP(a, b);
3165-
31663163
if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) {
31673164
return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b));
31683165
}
@@ -3187,6 +3184,13 @@ long_sub(PyLongObject *a, PyLongObject *b)
31873184
return (PyObject *)z;
31883185
}
31893186

3187+
static PyObject *
3188+
long_sub(PyLongObject *a, PyLongObject *b)
3189+
{
3190+
CHECK_BINOP(a, b);
3191+
return _PyLong_Subtract(a, b);
3192+
}
3193+
31903194
/* Grade school multiplication, ignoring the signs.
31913195
* Returns the absolute value of the product, or NULL if error.
31923196
*/

Python/ceval.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,41 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
20092009
DISPATCH();
20102010
}
20112011

2012+
TARGET(BINARY_OP_SUBTRACT_INT) {
2013+
PyObject *left = SECOND();
2014+
PyObject *right = TOP();
2015+
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
2016+
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
2017+
STAT_INC(BINARY_OP, hit);
2018+
PyObject *sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right);
2019+
SET_SECOND(sub);
2020+
Py_DECREF(right);
2021+
Py_DECREF(left);
2022+
STACK_SHRINK(1);
2023+
if (sub == NULL) {
2024+
goto error;
2025+
}
2026+
DISPATCH();
2027+
}
2028+
2029+
TARGET(BINARY_OP_SUBTRACT_FLOAT) {
2030+
PyObject *left = SECOND();
2031+
PyObject *right = TOP();
2032+
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
2033+
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
2034+
STAT_INC(BINARY_OP, hit);
2035+
double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval;
2036+
PyObject *sub = PyFloat_FromDouble(dsub);
2037+
SET_SECOND(sub);
2038+
Py_DECREF(right);
2039+
Py_DECREF(left);
2040+
STACK_SHRINK(1);
2041+
if (sub == NULL) {
2042+
goto error;
2043+
}
2044+
DISPATCH();
2045+
}
2046+
20122047
TARGET(BINARY_OP_ADD_UNICODE) {
20132048
PyObject *left = SECOND();
20142049
PyObject *right = TOP();

Python/opcode_targets.h

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,19 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
14241424
goto success;
14251425
}
14261426
break;
1427+
case NB_SUBTRACT:
1428+
case NB_INPLACE_SUBTRACT:
1429+
if (PyLong_CheckExact(lhs)) {
1430+
*instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT,
1431+
_Py_OPARG(*instr));
1432+
goto success;
1433+
}
1434+
if (PyFloat_CheckExact(lhs)) {
1435+
*instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_FLOAT,
1436+
_Py_OPARG(*instr));
1437+
goto success;
1438+
}
1439+
break;
14271440
default:
14281441
// These operators don't have any available specializations. Rather
14291442
// than repeatedly attempting to specialize them, just convert them

0 commit comments

Comments
 (0)