From 233e32f93614255bf5fc7c93cd98af453e58cc98 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 13 Mar 2023 10:34:54 +0000 Subject: GH-102300: Reuse objects with refcount == 1 in float specialized binary ops. (GH-102301) --- .../2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst | 1 + Python/bytecodes.c | 15 +++------------ Python/ceval_macros.h | 20 ++++++++++++++++++++ Python/generated_cases.c.h | 15 +++------------ 4 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst new file mode 100644 index 0000000..4227014 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst @@ -0,0 +1 @@ +Reuse operands with refcount of 1 in float specializations of BINARY_OP. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index dc2a20f..178519f 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -195,10 +195,7 @@ dummy_func( STAT_INC(BINARY_OP, hit); double dprod = ((PyFloatObject *)left)->ob_fval * ((PyFloatObject *)right)->ob_fval; - prod = PyFloat_FromDouble(dprod); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - ERROR_IF(prod == NULL, error); + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod); } inst(BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- sub)) { @@ -218,10 +215,7 @@ dummy_func( DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); STAT_INC(BINARY_OP, hit); double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; - sub = PyFloat_FromDouble(dsub); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - ERROR_IF(sub == NULL, error); + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub); } inst(BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) { @@ -278,10 +272,7 @@ dummy_func( STAT_INC(BINARY_OP, hit); double dsum = ((PyFloatObject *)left)->ob_fval + ((PyFloatObject *)right)->ob_fval; - sum = PyFloat_FromDouble(dsum); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - ERROR_IF(sum == NULL, error); + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum); } inst(BINARY_OP_ADD_INT, (unused/1, left, right -- sum)) { diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index ac1fec7..98b72ec 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -350,3 +350,23 @@ GETITEM(PyObject *v, Py_ssize_t i) { #define KWNAMES_LEN() \ (kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(kwnames))) + +#define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \ +do { \ + if (Py_REFCNT(left) == 1) { \ + ((PyFloatObject *)left)->ob_fval = (dval); \ + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);\ + result = (left); \ + } \ + else if (Py_REFCNT(right) == 1) {\ + ((PyFloatObject *)right)->ob_fval = (dval); \ + _Py_DECREF_NO_DEALLOC(left); \ + result = (right); \ + }\ + else { \ + result = PyFloat_FromDouble(dval); \ + if ((result) == NULL) goto error; \ + _Py_DECREF_NO_DEALLOC(left); \ + _Py_DECREF_NO_DEALLOC(right); \ + } \ +} while (0) diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 3839aee..21073cb 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -263,10 +263,7 @@ STAT_INC(BINARY_OP, hit); double dprod = ((PyFloatObject *)left)->ob_fval * ((PyFloatObject *)right)->ob_fval; - prod = PyFloat_FromDouble(dprod); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - if (prod == NULL) goto pop_2_error; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod); STACK_SHRINK(1); stack_pointer[-1] = prod; next_instr += 1; @@ -300,10 +297,7 @@ DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); STAT_INC(BINARY_OP, hit); double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; - sub = PyFloat_FromDouble(dsub); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - if (sub == NULL) goto pop_2_error; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub); STACK_SHRINK(1); stack_pointer[-1] = sub; next_instr += 1; @@ -372,10 +366,7 @@ STAT_INC(BINARY_OP, hit); double dsum = ((PyFloatObject *)left)->ob_fval + ((PyFloatObject *)right)->ob_fval; - sum = PyFloat_FromDouble(dsum); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - if (sum == NULL) goto pop_2_error; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum); STACK_SHRINK(1); stack_pointer[-1] = sum; next_instr += 1; -- cgit v0.12