summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorInada Naoki <songofacandy@gmail.com>2021-04-16 05:01:04 (GMT)
committerGitHub <noreply@github.com>2021-04-16 05:01:04 (GMT)
commit8a232c7b17a2e41ae14d8bb7937ddfea69301dce (patch)
treed6e4d24b52f610acfca2271fcb4adc22cdf05fee /Python/compile.c
parentff3d9c0f1a960c3d677d7eb0200d59f3aa2a8b1b (diff)
downloadcpython-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.c39
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);