diff options
author | Inada Naoki <songofacandy@gmail.com> | 2021-04-16 05:01:04 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-16 05:01:04 (GMT) |
commit | 8a232c7b17a2e41ae14d8bb7937ddfea69301dce (patch) | |
tree | d6e4d24b52f610acfca2271fcb4adc22cdf05fee /Python/compile.c | |
parent | ff3d9c0f1a960c3d677d7eb0200d59f3aa2a8b1b (diff) | |
download | cpython-8a232c7b17a2e41ae14d8bb7937ddfea69301dce.zip cpython-8a232c7b17a2e41ae14d8bb7937ddfea69301dce.tar.gz cpython-8a232c7b17a2e41ae14d8bb7937ddfea69301dce.tar.bz2 |
bpo-41323: compiler: Reuse tuple in constant tuple folding (GH-25419)
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/Python/compile.c b/Python/compile.c index 11d910b..496b4b0 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -6751,7 +6751,7 @@ static int normalize_basic_block(basicblock *bb); static int -optimize_cfg(struct assembler *a, PyObject *consts); +optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts); static int ensure_exits_have_lineno(struct compiler *c); @@ -6850,7 +6850,7 @@ assemble(struct compiler *c, int addNone) if (consts == NULL) { goto error; } - if (optimize_cfg(&a, consts)) { + if (optimize_cfg(c, &a, consts)) { goto error; } @@ -6898,7 +6898,8 @@ assemble(struct compiler *c, int addNone) Called with codestr pointing to the first LOAD_CONST. */ static int -fold_tuple_on_constants(struct instr *inst, +fold_tuple_on_constants(struct compiler *c, + struct instr *inst, int n, PyObject *consts) { /* Pre-conditions */ @@ -6923,15 +6924,27 @@ fold_tuple_on_constants(struct instr *inst, Py_INCREF(constant); PyTuple_SET_ITEM(newconst, i, constant); } - Py_ssize_t index = PyList_GET_SIZE(consts); - if ((size_t)index >= (size_t)INT_MAX - 1) { + if (merge_const_one(c, &newconst) == 0) { Py_DECREF(newconst); - PyErr_SetString(PyExc_OverflowError, "too many constants"); return -1; } - if (PyList_Append(consts, newconst)) { - Py_DECREF(newconst); - return -1; + + Py_ssize_t index; + for (index = 0; index < PyList_GET_SIZE(consts); index++) { + if (PyList_GET_ITEM(consts, index) == newconst) { + break; + } + } + if (index == PyList_GET_SIZE(consts)) { + if ((size_t)index >= (size_t)INT_MAX - 1) { + Py_DECREF(newconst); + PyErr_SetString(PyExc_OverflowError, "too many constants"); + return -1; + } + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return -1; + } } Py_DECREF(newconst); for (int i = 0; i < n; i++) { @@ -6968,7 +6981,7 @@ eliminate_jump_to_jump(basicblock *bb, int opcode) { /* Optimization */ static int -optimize_basic_block(basicblock *bb, PyObject *consts) +optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) { assert(PyList_CheckExact(consts)); struct instr nop; @@ -7056,7 +7069,7 @@ optimize_basic_block(basicblock *bb, PyObject *consts) break; } if (i >= oparg) { - if (fold_tuple_on_constants(inst-oparg, oparg, consts)) { + if (fold_tuple_on_constants(c, inst-oparg, oparg, consts)) { goto error; } } @@ -7390,10 +7403,10 @@ propogate_line_numbers(struct assembler *a) { */ static int -optimize_cfg(struct assembler *a, PyObject *consts) +optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts) { for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (optimize_basic_block(b, consts)) { + if (optimize_basic_block(c, b, consts)) { return -1; } clean_basic_block(b, -1); |