bpo-41323: compiler: Reuse tuple in constant tuple folding (GH-25419)

This commit is contained in:
Inada Naoki 2021-04-16 14:01:04 +09:00 committed by GitHub
parent ff3d9c0f1a
commit 8a232c7b17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 3280 additions and 3265 deletions

View file

@ -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);