From 74ceb3753e06ee48cf29a4e69f04878285454672 Mon Sep 17 00:00:00 2001 From: sweeneyde Date: Sat, 16 Oct 2021 23:24:26 -0400 Subject: [PATCH 1/4] Initial implementation of INPLACE_MULTIPLY specialization --- Include/internal/pycore_code.h | 1 + Include/opcode.h | 65 +++++++++++--------- Lib/opcode.py | 5 ++ Python/ceval.c | 109 ++++++++++++++++++++++++++++++--- Python/opcode_targets.h | 58 +++++++++--------- Python/specialize.c | 45 ++++++++++++++ 6 files changed, 216 insertions(+), 67 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index a91209b39f654a..6b3ebc8e0f3ef5 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -308,6 +308,7 @@ int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNI int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); int _Py_Specialize_BinaryAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr); +int _Py_Specialize_InplaceAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr); int _Py_Specialize_BinaryMultiply(PyObject *left, PyObject *right, _Py_CODEUNIT *instr); #define PRINT_SPECIALIZATION_STATS 0 diff --git a/Include/opcode.h b/Include/opcode.h index fabb8d123bb9ca..a5ac4b597cb419 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -141,36 +141,41 @@ extern "C" { #define BINARY_ADD_FLOAT 13 #define BINARY_ADD_UNICODE 14 #define BINARY_ADD_UNICODE_INPLACE_FAST 18 -#define BINARY_MULTIPLY_ADAPTIVE 21 -#define BINARY_MULTIPLY_INT 36 -#define BINARY_MULTIPLY_FLOAT 38 -#define BINARY_SUBSCR_ADAPTIVE 39 -#define BINARY_SUBSCR_LIST_INT 40 -#define BINARY_SUBSCR_TUPLE_INT 41 -#define BINARY_SUBSCR_DICT 42 -#define JUMP_ABSOLUTE_QUICK 43 -#define LOAD_ATTR_ADAPTIVE 44 -#define LOAD_ATTR_INSTANCE_VALUE 45 -#define LOAD_ATTR_WITH_HINT 46 -#define LOAD_ATTR_SLOT 47 -#define LOAD_ATTR_MODULE 48 -#define LOAD_GLOBAL_ADAPTIVE 58 -#define LOAD_GLOBAL_MODULE 80 -#define LOAD_GLOBAL_BUILTIN 81 -#define LOAD_METHOD_ADAPTIVE 87 -#define LOAD_METHOD_CACHED 88 -#define LOAD_METHOD_CLASS 120 -#define LOAD_METHOD_MODULE 122 -#define LOAD_METHOD_NO_DICT 123 -#define STORE_ATTR_ADAPTIVE 127 -#define STORE_ATTR_INSTANCE_VALUE 128 -#define STORE_ATTR_SLOT 134 -#define STORE_ATTR_WITH_HINT 140 -#define LOAD_FAST__LOAD_FAST 143 -#define STORE_FAST__LOAD_FAST 149 -#define LOAD_FAST__LOAD_CONST 150 -#define LOAD_CONST__LOAD_FAST 151 -#define STORE_FAST__STORE_FAST 153 +#define INPLACE_ADD_ADAPTIVE 21 +#define INPLACE_ADD_INT 36 +#define INPLACE_ADD_FLOAT 38 +#define INPLACE_ADD_UNICODE 39 +#define INPLACE_ADD_UNICODE_FAST 40 +#define BINARY_MULTIPLY_ADAPTIVE 41 +#define BINARY_MULTIPLY_INT 42 +#define BINARY_MULTIPLY_FLOAT 43 +#define BINARY_SUBSCR_ADAPTIVE 44 +#define BINARY_SUBSCR_LIST_INT 45 +#define BINARY_SUBSCR_TUPLE_INT 46 +#define BINARY_SUBSCR_DICT 47 +#define JUMP_ABSOLUTE_QUICK 48 +#define LOAD_ATTR_ADAPTIVE 58 +#define LOAD_ATTR_INSTANCE_VALUE 80 +#define LOAD_ATTR_WITH_HINT 81 +#define LOAD_ATTR_SLOT 87 +#define LOAD_ATTR_MODULE 88 +#define LOAD_GLOBAL_ADAPTIVE 120 +#define LOAD_GLOBAL_MODULE 122 +#define LOAD_GLOBAL_BUILTIN 123 +#define LOAD_METHOD_ADAPTIVE 127 +#define LOAD_METHOD_CACHED 128 +#define LOAD_METHOD_CLASS 134 +#define LOAD_METHOD_MODULE 140 +#define LOAD_METHOD_NO_DICT 143 +#define STORE_ATTR_ADAPTIVE 149 +#define STORE_ATTR_INSTANCE_VALUE 150 +#define STORE_ATTR_SLOT 151 +#define STORE_ATTR_WITH_HINT 153 +#define LOAD_FAST__LOAD_FAST 154 +#define STORE_FAST__LOAD_FAST 158 +#define LOAD_FAST__LOAD_CONST 159 +#define LOAD_CONST__LOAD_FAST 167 +#define STORE_FAST__STORE_FAST 168 #define DO_TRACING 255 #ifdef NEED_OPCODE_JUMP_TABLES static uint32_t _PyOpcode_RelativeJump[8] = { diff --git a/Lib/opcode.py b/Lib/opcode.py index 9d9f35855e25b5..80b7fcb4288210 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -225,6 +225,11 @@ def jabs_op(name, op): "BINARY_ADD_FLOAT", "BINARY_ADD_UNICODE", "BINARY_ADD_UNICODE_INPLACE_FAST", + "INPLACE_ADD_ADAPTIVE", + "INPLACE_ADD_INT", + "INPLACE_ADD_FLOAT", + "INPLACE_ADD_UNICODE", + "INPLACE_ADD_UNICODE_FAST", "BINARY_MULTIPLY_ADAPTIVE", "BINARY_MULTIPLY_INT", "BINARY_MULTIPLY_FLOAT", diff --git a/Python/ceval.c b/Python/ceval.c index de71ae5da0f82b..cb6afb264a873b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2446,21 +2446,113 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr } TARGET(INPLACE_ADD) { + PREDICTED(INPLACE_ADD); + STAT_INC(INPLACE_ADD, unquickened); PyObject *right = POP(); PyObject *left = TOP(); - PyObject *sum; - if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(tstate, left, right, frame, next_instr); - /* unicode_concatenate consumed the ref to left */ + PyObject *sum = PyNumber_InPlaceAdd(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(sum); + if (sum == NULL) + goto error; + DISPATCH(); + } + + TARGET(INPLACE_ADD_ADAPTIVE) { + if (oparg == 0) { + PyObject *left = SECOND(); + PyObject *right = TOP(); + next_instr--; + if (_Py_Specialize_InplaceAdd(left, right, next_instr) < 0) { + goto error; + } + DISPATCH(); } else { - sum = PyNumber_InPlaceAdd(left, right); - Py_DECREF(left); + STAT_INC(INPLACE_ADD, deferred); + UPDATE_PREV_INSTR_OPARG(next_instr, oparg - 1); + STAT_DEC(INPLACE_ADD, unquickened); + JUMP_TO_INSTRUCTION(INPLACE_ADD); } + } + + TARGET(INPLACE_ADD_INT) { + PyObject *left = SECOND(); + PyObject *right = TOP(); + DEOPT_IF(!PyLong_CheckExact(left), INPLACE_ADD); + DEOPT_IF(!PyLong_CheckExact(right), INPLACE_ADD); + STAT_INC(INPLACE_ADD, hit); + record_hit_inline(next_instr, oparg); + PyObject *sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); + SET_SECOND(sum); + Py_DECREF(left); Py_DECREF(right); - SET_TOP(sum); - if (sum == NULL) + STACK_SHRINK(1); + if (sum == NULL) { goto error; + } + DISPATCH(); + } + + TARGET(INPLACE_ADD_FLOAT) { + PyObject *left = SECOND(); + PyObject *right = TOP(); + DEOPT_IF(!PyFloat_CheckExact(left), INPLACE_ADD); + DEOPT_IF(!PyFloat_CheckExact(right), INPLACE_ADD); + STAT_INC(INPLACE_ADD, hit); + record_hit_inline(next_instr, oparg); + double dsum = ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + PyObject *sum = PyFloat_FromDouble(dsum); + SET_SECOND(sum); + Py_DECREF(left); + Py_DECREF(right); + STACK_SHRINK(1); + if (sum == NULL) { + goto error; + } + DISPATCH(); + } + + TARGET(INPLACE_ADD_UNICODE) { + PyObject *left = SECOND(); + PyObject *right = TOP(); + DEOPT_IF(!PyUnicode_CheckExact(left), INPLACE_ADD); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), INPLACE_ADD); + STAT_INC(BINARY_ADD, hit); + record_hit_inline(next_instr, oparg); + PyObject *res = PyUnicode_Concat(left, right); + STACK_SHRINK(1); + SET_TOP(res); + Py_DECREF(left); + Py_DECREF(right); + if (TOP() == NULL) { + goto error; + } + DISPATCH(); + } + + TARGET(INPLACE_ADD_UNICODE_FAST) { + PyObject *left = SECOND(); + PyObject *right = TOP(); + DEOPT_IF(!PyUnicode_CheckExact(left), INPLACE_ADD); + DEOPT_IF(!PyUnicode_CheckExact(right), INPLACE_ADD); + DEOPT_IF(Py_REFCNT(left) != 2, INPLACE_ADD); + int next_oparg = _Py_OPARG(*next_instr); + assert(_Py_OPCODE(*next_instr) == STORE_FAST); + PyObject *var = GETLOCAL(next_oparg); + DEOPT_IF(var != left, INPLACE_ADD); + STAT_INC(INPLACE_ADD, hit); + record_hit_inline(next_instr, oparg); + GETLOCAL(next_oparg) = NULL; + Py_DECREF(left); + STACK_SHRINK(1); + PyUnicode_Append(&TOP(), right); + Py_DECREF(right); + if (TOP() == NULL) { + goto error; + } DISPATCH(); } @@ -5013,6 +5105,7 @@ MISS_WITH_CACHE(LOAD_GLOBAL) MISS_WITH_CACHE(LOAD_METHOD) MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR) MISS_WITH_OPARG_COUNTER(BINARY_ADD) +MISS_WITH_OPARG_COUNTER(INPLACE_ADD) MISS_WITH_OPARG_COUNTER(BINARY_MULTIPLY) binary_subscr_dict_error: diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 7d701e81a9a48a..9ddc7e66ef833d 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -20,7 +20,7 @@ static void *opcode_targets[256] = { &&TARGET_BINARY_ADD_UNICODE_INPLACE_FAST, &&TARGET_BINARY_POWER, &&TARGET_BINARY_MULTIPLY, - &&TARGET_BINARY_MULTIPLY_ADAPTIVE, + &&TARGET_INPLACE_ADD_ADAPTIVE, &&TARGET_BINARY_MODULO, &&TARGET_BINARY_ADD, &&TARGET_BINARY_SUBTRACT, @@ -35,19 +35,19 @@ static void *opcode_targets[256] = { &&TARGET_MATCH_KEYS, &&TARGET_COPY_DICT_WITHOUT_KEYS, &&TARGET_PUSH_EXC_INFO, - &&TARGET_BINARY_MULTIPLY_INT, + &&TARGET_INPLACE_ADD_INT, &&TARGET_POP_EXCEPT_AND_RERAISE, + &&TARGET_INPLACE_ADD_FLOAT, + &&TARGET_INPLACE_ADD_UNICODE, + &&TARGET_INPLACE_ADD_UNICODE_FAST, + &&TARGET_BINARY_MULTIPLY_ADAPTIVE, + &&TARGET_BINARY_MULTIPLY_INT, &&TARGET_BINARY_MULTIPLY_FLOAT, &&TARGET_BINARY_SUBSCR_ADAPTIVE, &&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT, &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_JUMP_ABSOLUTE_QUICK, - &&TARGET_LOAD_ATTR_ADAPTIVE, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_ATTR_SLOT, - &&TARGET_LOAD_ATTR_MODULE, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, @@ -57,7 +57,7 @@ static void *opcode_targets[256] = { &&TARGET_INPLACE_ADD, &&TARGET_INPLACE_SUBTRACT, &&TARGET_INPLACE_MULTIPLY, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, + &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_INPLACE_MODULO, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, @@ -79,15 +79,15 @@ static void *opcode_targets[256] = { &&TARGET_INPLACE_AND, &&TARGET_INPLACE_XOR, &&TARGET_INPLACE_OR, - &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_LOAD_GLOBAL_BUILTIN, + &&TARGET_LOAD_ATTR_INSTANCE_VALUE, + &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, &&TARGET_YIELD_VALUE, - &&TARGET_LOAD_METHOD_ADAPTIVE, - &&TARGET_LOAD_METHOD_CACHED, + &&TARGET_LOAD_ATTR_SLOT, + &&TARGET_LOAD_ATTR_MODULE, &&TARGET_POP_EXCEPT, &&TARGET_STORE_NAME, &&TARGET_DELETE_NAME, @@ -119,46 +119,46 @@ static void *opcode_targets[256] = { &&TARGET_IS_OP, &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, - &&TARGET_LOAD_METHOD_CLASS, + &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_JUMP_IF_NOT_EXC_MATCH, - &&TARGET_LOAD_METHOD_MODULE, - &&TARGET_LOAD_METHOD_NO_DICT, + &&TARGET_LOAD_GLOBAL_MODULE, + &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_FAST, &&TARGET_STORE_FAST, &&TARGET_DELETE_FAST, - &&TARGET_STORE_ATTR_ADAPTIVE, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_LOAD_METHOD_ADAPTIVE, + &&TARGET_LOAD_METHOD_CACHED, &&TARGET_GEN_START, &&TARGET_RAISE_VARARGS, &&TARGET_CALL_FUNCTION, &&TARGET_MAKE_FUNCTION, &&TARGET_BUILD_SLICE, - &&TARGET_STORE_ATTR_SLOT, + &&TARGET_LOAD_METHOD_CLASS, &&TARGET_MAKE_CELL, &&TARGET_LOAD_CLOSURE, &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, - &&TARGET_STORE_ATTR_WITH_HINT, + &&TARGET_LOAD_METHOD_MODULE, &&TARGET_CALL_FUNCTION_KW, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_LOAD_FAST__LOAD_FAST, + &&TARGET_LOAD_METHOD_NO_DICT, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, - &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_STORE_ATTR_ADAPTIVE, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_STORE_ATTR_SLOT, &&TARGET_MATCH_CLASS, - &&TARGET_STORE_FAST__STORE_FAST, - &&_unknown_opcode, + &&TARGET_STORE_ATTR_WITH_HINT, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_STORE_FAST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_METHOD, &&TARGET_CALL_METHOD, &&TARGET_LIST_EXTEND, @@ -166,8 +166,8 @@ static void *opcode_targets[256] = { &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, &&TARGET_CALL_METHOD_KW, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_STORE_FAST__STORE_FAST, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/specialize.c b/Python/specialize.c index 529eabf6bc3abf..24aa140cf35fca 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -124,6 +124,7 @@ _Py_GetSpecializationStats(void) { err += add_stat_dict(stats, LOAD_GLOBAL, "load_global"); err += add_stat_dict(stats, LOAD_METHOD, "load_method"); err += add_stat_dict(stats, BINARY_ADD, "binary_add"); + err += add_stat_dict(stats, INPLACE_ADD, "inplace_add"); err += add_stat_dict(stats, BINARY_MULTIPLY, "binary_multiply"); err += add_stat_dict(stats, BINARY_SUBSCR, "binary_subscr"); err += add_stat_dict(stats, STORE_ATTR, "store_attr"); @@ -181,6 +182,7 @@ _Py_PrintSpecializationStats(void) print_stats(out, &_specialization_stats[LOAD_GLOBAL], "load_global"); print_stats(out, &_specialization_stats[LOAD_METHOD], "load_method"); print_stats(out, &_specialization_stats[BINARY_ADD], "binary_add"); + print_stats(out, &_specialization_stats[INPLACE_ADD], "inplace_add"); print_stats(out, &_specialization_stats[BINARY_MULTIPLY], "binary_multiply"); print_stats(out, &_specialization_stats[BINARY_SUBSCR], "binary_subscr"); print_stats(out, &_specialization_stats[STORE_ATTR], "store_attr"); @@ -232,6 +234,7 @@ static uint8_t adaptive_opcodes[256] = { [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, [BINARY_ADD] = BINARY_ADD_ADAPTIVE, + [INPLACE_ADD] = INPLACE_ADD_ADAPTIVE, [BINARY_MULTIPLY] = BINARY_MULTIPLY_ADAPTIVE, [BINARY_SUBSCR] = BINARY_SUBSCR_ADAPTIVE, [STORE_ATTR] = STORE_ATTR_ADAPTIVE, @@ -243,6 +246,7 @@ static uint8_t cache_requirements[256] = { [LOAD_GLOBAL] = 2, /* _PyAdaptiveEntry and _PyLoadGlobalCache */ [LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */ [BINARY_ADD] = 0, + [INPLACE_ADD] = 0, [BINARY_MULTIPLY] = 0, [BINARY_SUBSCR] = 0, [STORE_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ @@ -1193,6 +1197,47 @@ _Py_Specialize_BinaryAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr) return 0; } +int +_Py_Specialize_InplaceAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr) +{ + PyTypeObject *left_type = Py_TYPE(left); + if (left_type != Py_TYPE(right)) { + SPECIALIZATION_FAIL(INPLACE_ADD, SPEC_FAIL_DIFFERENT_TYPES); + goto fail; + } + if (left_type == &PyUnicode_Type) { + int next_opcode = _Py_OPCODE(instr[1]); + if (next_opcode == STORE_FAST) { + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_UNICODE_FAST, saturating_start()); + } + else { + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_UNICODE, saturating_start()); + } + goto success; + } + else if (left_type == &PyLong_Type) { + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_INT, saturating_start()); + goto success; + } + else if (left_type == &PyFloat_Type) { + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_FLOAT, saturating_start()); + goto success; + + } + else { + SPECIALIZATION_FAIL(INPLACE_ADD, SPEC_FAIL_OTHER); + } +fail: + STAT_INC(INPLACE_ADD, specialization_failure); + assert(!PyErr_Occurred()); + *instr = _Py_MAKECODEUNIT(_Py_OPCODE(*instr), ADAPTIVE_CACHE_BACKOFF); + return 0; +success: + STAT_INC(INPLACE_ADD, specialization_success); + assert(!PyErr_Occurred()); + return 0; +} + int _Py_Specialize_BinaryMultiply(PyObject *left, PyObject *right, _Py_CODEUNIT *instr) { From 62c1d3839a9598da1ce9f40a37e8b2a5ea165959 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 09:54:58 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core and Builtins/2021-10-18-09-54-55.bpo-45508.6sPZsS.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-10-18-09-54-55.bpo-45508.6sPZsS.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-10-18-09-54-55.bpo-45508.6sPZsS.rst b/Misc/NEWS.d/next/Core and Builtins/2021-10-18-09-54-55.bpo-45508.6sPZsS.rst new file mode 100644 index 00000000000000..abbc7f6007b054 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-10-18-09-54-55.bpo-45508.6sPZsS.rst @@ -0,0 +1 @@ +Specialized the ``INPLACE_ADD`` opcode to match the specializations of ``BINARY_ADD`` (see PEP 659 for details). \ No newline at end of file From 89ea6ba0431fe70dea97534265adf4cb8dc46f2b Mon Sep 17 00:00:00 2001 From: sweeneyde Date: Mon, 18 Oct 2021 06:26:48 -0400 Subject: [PATCH 3/4] Remove unused unicode_concatenate --- Python/ceval.c | 56 -------------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 37ffcdea2ded77..e511ad83487ae9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -92,8 +92,6 @@ static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); static int import_all_from(PyThreadState *, PyObject *, PyObject *); static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); -static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, - InterpreterFrame *, const _Py_CODEUNIT *); static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int); @@ -7092,60 +7090,6 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevop } } -static PyObject * -unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w, - InterpreterFrame *frame, const _Py_CODEUNIT *next_instr) -{ - PyObject *res; - if (Py_REFCNT(v) == 2) { - /* In the common case, there are 2 references to the value - * stored in 'variable' when the += is performed: one on the - * value stack (in 'v') and one still stored in the - * 'variable'. We try to delete the variable now to reduce - * the refcnt to 1. - */ - int opcode, oparg; - NEXTOPARG(); - next_instr++; - switch (opcode) { - case STORE_FAST: - { - if (GETLOCAL(oparg) == v) - SETLOCAL(oparg, NULL); - break; - } - case STORE_DEREF: - { - PyObject *c = _PyFrame_GetLocalsArray(frame)[oparg]; - if (PyCell_GET(c) == v) { - PyCell_SET(c, NULL); - Py_DECREF(v); - } - break; - } - case STORE_NAME: - { - PyObject *names = frame->f_code->co_names; - PyObject *name = GETITEM(names, oparg); - PyObject *locals = frame->f_locals; - if (locals && PyDict_CheckExact(locals)) { - PyObject *w = PyDict_GetItemWithError(locals, name); - if ((w == v && PyDict_DelItem(locals, name) != 0) || - (w == NULL && _PyErr_Occurred(tstate))) - { - Py_DECREF(v); - return NULL; - } - } - break; - } - } - } - res = v; - PyUnicode_Append(&res, w); - return res; -} - #ifdef DYNAMIC_EXECUTION_PROFILE static PyObject * From e4a1871d717fb4388254c1faf50a6ffc44f253c0 Mon Sep 17 00:00:00 2001 From: sweeneyde Date: Thu, 21 Oct 2021 22:49:03 -0400 Subject: [PATCH 4/4] remove record_hit_inline calls --- Python/ceval.c | 4 ---- Python/specialize.c | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 03af2e16b94e18..57319c94297ab8 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2472,7 +2472,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DEOPT_IF(!PyLong_CheckExact(left), INPLACE_ADD); DEOPT_IF(!PyLong_CheckExact(right), INPLACE_ADD); STAT_INC(INPLACE_ADD, hit); - record_hit_inline(next_instr, oparg); PyObject *sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); SET_SECOND(sum); Py_DECREF(left); @@ -2490,7 +2489,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DEOPT_IF(!PyFloat_CheckExact(left), INPLACE_ADD); DEOPT_IF(!PyFloat_CheckExact(right), INPLACE_ADD); STAT_INC(INPLACE_ADD, hit); - record_hit_inline(next_instr, oparg); double dsum = ((PyFloatObject *)left)->ob_fval + ((PyFloatObject *)right)->ob_fval; PyObject *sum = PyFloat_FromDouble(dsum); @@ -2510,7 +2508,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DEOPT_IF(!PyUnicode_CheckExact(left), INPLACE_ADD); DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), INPLACE_ADD); STAT_INC(BINARY_ADD, hit); - record_hit_inline(next_instr, oparg); PyObject *res = PyUnicode_Concat(left, right); STACK_SHRINK(1); SET_TOP(res); @@ -2533,7 +2530,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *var = GETLOCAL(next_oparg); DEOPT_IF(var != left, INPLACE_ADD); STAT_INC(INPLACE_ADD, hit); - record_hit_inline(next_instr, oparg); GETLOCAL(next_oparg) = NULL; Py_DECREF(left); STACK_SHRINK(1); diff --git a/Python/specialize.c b/Python/specialize.c index a4ac6acd40dc3d..63658d720b2558 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1239,19 +1239,19 @@ _Py_Specialize_InplaceAdd(PyObject *left, PyObject *right, _Py_CODEUNIT *instr) if (left_type == &PyUnicode_Type) { int next_opcode = _Py_OPCODE(instr[1]); if (next_opcode == STORE_FAST) { - *instr = _Py_MAKECODEUNIT(INPLACE_ADD_UNICODE_FAST, saturating_start()); + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_UNICODE_FAST, initial_counter_value()); } else { - *instr = _Py_MAKECODEUNIT(INPLACE_ADD_UNICODE, saturating_start()); + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_UNICODE, initial_counter_value()); } goto success; } else if (left_type == &PyLong_Type) { - *instr = _Py_MAKECODEUNIT(INPLACE_ADD_INT, saturating_start()); + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_INT, initial_counter_value()); goto success; } else if (left_type == &PyFloat_Type) { - *instr = _Py_MAKECODEUNIT(INPLACE_ADD_FLOAT, saturating_start()); + *instr = _Py_MAKECODEUNIT(INPLACE_ADD_FLOAT, initial_counter_value()); goto success; }