Skip to content

Commit 48d7761

Browse files
committed
Implement Specializing BINARY_SUBTRACT.
1 parent dd86f63 commit 48d7761

File tree

8 files changed

+174
-67
lines changed

8 files changed

+174
-67
lines changed

Include/internal/pycore_code.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *na
269269
int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr);
270270
int _Py_Specialize_BinaryAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr);
271271
int _Py_Specialize_BinaryMultiply(PyObject *left, PyObject *right, _Py_CODEUNIT *instr);
272+
int _Py_Specialize_BinarySubtract(PyObject *left, PyObject *right, _Py_CODEUNIT *instr);
272273
int _Py_Specialize_CallFunction(PyObject *callable, _Py_CODEUNIT *instr, int nargs, SpecializedCacheEntry *cache, PyObject *builtins);
273274

274275
#define PRINT_SPECIALIZATION_STATS 0

Include/internal/pycore_long.h

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

3737
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
3838
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
39+
PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
3940

4041
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
4142
_PyBytes_DecodeEscape(), etc. */

Include/opcode.h

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

Lib/opcode.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ def jabs_op(name, op):
225225
"BINARY_ADD_FLOAT",
226226
"BINARY_ADD_UNICODE",
227227
"BINARY_ADD_UNICODE_INPLACE_FAST",
228+
"BINARY_SUBTRACT_ADAPTIVE",
229+
"BINARY_SUBTRACT_INT",
230+
"BINARY_SUBTRACT_FLOAT",
228231
"BINARY_MULTIPLY_ADAPTIVE",
229232
"BINARY_MULTIPLY_INT",
230233
"BINARY_MULTIPLY_FLOAT",

Objects/longobject.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3158,9 +3158,8 @@ long_add(PyLongObject *a, PyLongObject *b)
31583158
return _PyLong_Add(a, b);
31593159
}
31603160

3161-
3162-
static PyObject *
3163-
long_sub(PyLongObject *a, PyLongObject *b)
3161+
PyObject *
3162+
_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
31643163
{
31653164
PyLongObject *z;
31663165

@@ -3190,6 +3189,13 @@ long_sub(PyLongObject *a, PyLongObject *b)
31903189
return (PyObject *)z;
31913190
}
31923191

3192+
static PyObject *
3193+
long_sub(PyLongObject *a, PyLongObject *b)
3194+
{
3195+
CHECK_BINOP(a, b);
3196+
return _PyLong_Subtract(a, b);
3197+
}
3198+
31933199
/* Grade school multiplication, ignoring the signs.
31943200
* Returns the absolute value of the product, or NULL if error.
31953201
*/

Python/ceval.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2171,14 +2171,72 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
21712171
}
21722172

21732173
TARGET(BINARY_SUBTRACT) {
2174+
PREDICTED(BINARY_SUBTRACT);
2175+
STAT_INC(BINARY_SUBTRACT, unquickened);
21742176
PyObject *right = POP();
21752177
PyObject *left = TOP();
21762178
PyObject *diff = PyNumber_Subtract(left, right);
21772179
Py_DECREF(right);
21782180
Py_DECREF(left);
21792181
SET_TOP(diff);
2180-
if (diff == NULL)
2182+
if (diff == NULL) {
21812183
goto error;
2184+
}
2185+
DISPATCH();
2186+
}
2187+
2188+
TARGET(BINARY_SUBTRACT_ADAPTIVE) {
2189+
if (oparg == 0) {
2190+
PyObject *left = SECOND();
2191+
PyObject *right = TOP();
2192+
next_instr--;
2193+
if (_Py_Specialize_BinarySubtract(left, right, next_instr) < 0) {
2194+
goto error;
2195+
}
2196+
DISPATCH();
2197+
}
2198+
else {
2199+
STAT_INC(BINARY_SUBTRACT, deferred);
2200+
UPDATE_PREV_INSTR_OPARG(next_instr, oparg - 1);
2201+
STAT_DEC(BINARY_SUBTRACT, unquickened);
2202+
JUMP_TO_INSTRUCTION(BINARY_SUBTRACT);
2203+
}
2204+
}
2205+
2206+
TARGET(BINARY_SUBTRACT_INT) {
2207+
PyObject *left = SECOND();
2208+
PyObject *right = TOP();
2209+
DEOPT_IF(!PyLong_CheckExact(left), BINARY_SUBTRACT);
2210+
DEOPT_IF(!PyLong_CheckExact(right), BINARY_SUBTRACT);
2211+
STAT_INC(BINARY_SUBTRACT, hit);
2212+
record_hit_inline(next_instr, oparg);
2213+
PyObject *sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right);
2214+
SET_SECOND(sub);
2215+
Py_DECREF(right);
2216+
Py_DECREF(left);
2217+
STACK_SHRINK(1);
2218+
if (sub == NULL) {
2219+
goto error;
2220+
}
2221+
DISPATCH();
2222+
}
2223+
2224+
TARGET(BINARY_SUBTRACT_FLOAT) {
2225+
PyObject *left = SECOND();
2226+
PyObject *right = TOP();
2227+
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_SUBTRACT);
2228+
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_SUBTRACT);
2229+
STAT_INC(BINARY_SUBTRACT, hit);
2230+
record_hit_inline(next_instr, oparg);
2231+
double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval;
2232+
PyObject *sub = PyFloat_FromDouble(dsub);
2233+
SET_SECOND(sub);
2234+
Py_DECREF(right);
2235+
Py_DECREF(left);
2236+
STACK_SHRINK(1);
2237+
if (sub == NULL) {
2238+
goto error;
2239+
}
21822240
DISPATCH();
21832241
}
21842242

@@ -5135,6 +5193,7 @@ MISS_WITH_CACHE(CALL_FUNCTION)
51355193
MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR)
51365194
MISS_WITH_OPARG_COUNTER(BINARY_ADD)
51375195
MISS_WITH_OPARG_COUNTER(BINARY_MULTIPLY)
5196+
MISS_WITH_OPARG_COUNTER(BINARY_SUBTRACT)
51385197

51395198
binary_subscr_dict_error:
51405199
{

Python/opcode_targets.h

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

0 commit comments

Comments
 (0)