Skip to content

Commit 8a232c7

Browse files
authored
bpo-41323: compiler: Reuse tuple in constant tuple folding (GH-25419)
1 parent ff3d9c0 commit 8a232c7

File tree

5 files changed

+3268
-3253
lines changed

5 files changed

+3268
-3253
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Constant tuple folding in bytecode optimizer now reuses tuple in constant
2+
table.

Python/compile.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6751,7 +6751,7 @@ static int
67516751
normalize_basic_block(basicblock *bb);
67526752

67536753
static int
6754-
optimize_cfg(struct assembler *a, PyObject *consts);
6754+
optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts);
67556755

67566756
static int
67576757
ensure_exits_have_lineno(struct compiler *c);
@@ -6850,7 +6850,7 @@ assemble(struct compiler *c, int addNone)
68506850
if (consts == NULL) {
68516851
goto error;
68526852
}
6853-
if (optimize_cfg(&a, consts)) {
6853+
if (optimize_cfg(c, &a, consts)) {
68546854
goto error;
68556855
}
68566856

@@ -6898,7 +6898,8 @@ assemble(struct compiler *c, int addNone)
68986898
Called with codestr pointing to the first LOAD_CONST.
68996899
*/
69006900
static int
6901-
fold_tuple_on_constants(struct instr *inst,
6901+
fold_tuple_on_constants(struct compiler *c,
6902+
struct instr *inst,
69026903
int n, PyObject *consts)
69036904
{
69046905
/* Pre-conditions */
@@ -6923,15 +6924,27 @@ fold_tuple_on_constants(struct instr *inst,
69236924
Py_INCREF(constant);
69246925
PyTuple_SET_ITEM(newconst, i, constant);
69256926
}
6926-
Py_ssize_t index = PyList_GET_SIZE(consts);
6927-
if ((size_t)index >= (size_t)INT_MAX - 1) {
6927+
if (merge_const_one(c, &newconst) == 0) {
69286928
Py_DECREF(newconst);
6929-
PyErr_SetString(PyExc_OverflowError, "too many constants");
69306929
return -1;
69316930
}
6932-
if (PyList_Append(consts, newconst)) {
6933-
Py_DECREF(newconst);
6934-
return -1;
6931+
6932+
Py_ssize_t index;
6933+
for (index = 0; index < PyList_GET_SIZE(consts); index++) {
6934+
if (PyList_GET_ITEM(consts, index) == newconst) {
6935+
break;
6936+
}
6937+
}
6938+
if (index == PyList_GET_SIZE(consts)) {
6939+
if ((size_t)index >= (size_t)INT_MAX - 1) {
6940+
Py_DECREF(newconst);
6941+
PyErr_SetString(PyExc_OverflowError, "too many constants");
6942+
return -1;
6943+
}
6944+
if (PyList_Append(consts, newconst)) {
6945+
Py_DECREF(newconst);
6946+
return -1;
6947+
}
69356948
}
69366949
Py_DECREF(newconst);
69376950
for (int i = 0; i < n; i++) {
@@ -6968,7 +6981,7 @@ eliminate_jump_to_jump(basicblock *bb, int opcode) {
69686981

69696982
/* Optimization */
69706983
static int
6971-
optimize_basic_block(basicblock *bb, PyObject *consts)
6984+
optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
69726985
{
69736986
assert(PyList_CheckExact(consts));
69746987
struct instr nop;
@@ -7056,7 +7069,7 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
70567069
break;
70577070
}
70587071
if (i >= oparg) {
7059-
if (fold_tuple_on_constants(inst-oparg, oparg, consts)) {
7072+
if (fold_tuple_on_constants(c, inst-oparg, oparg, consts)) {
70607073
goto error;
70617074
}
70627075
}
@@ -7390,10 +7403,10 @@ propogate_line_numbers(struct assembler *a) {
73907403
*/
73917404

73927405
static int
7393-
optimize_cfg(struct assembler *a, PyObject *consts)
7406+
optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts)
73947407
{
73957408
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
7396-
if (optimize_basic_block(b, consts)) {
7409+
if (optimize_basic_block(c, b, consts)) {
73977410
return -1;
73987411
}
73997412
clean_basic_block(b, -1);

0 commit comments

Comments
 (0)