Skip to content

Commit 939fbee

Browse files
committed
make 2 passes to avoid unnecessary allocations
1 parent f0429c8 commit 939fbee

1 file changed

Lines changed: 36 additions & 39 deletions

File tree

Python/flowgraph.c

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,65 +1507,62 @@ fold_constant_intrinsic_list_to_tuple(basicblock *bb, int i,
15071507
assert(intrinsic->i_opcode == CALL_INTRINSIC_1);
15081508
assert(intrinsic->i_oparg == INTRINSIC_LIST_TO_TUPLE);
15091509

1510-
PyObject *list = PyList_New(0);
1511-
if (list == NULL) {
1512-
return ERROR;
1513-
}
1510+
int consts_found = 0;
1511+
bool start_found = false;
1512+
bool expect_append = true;
15141513

15151514
for (int pos = i-1; pos >= 0; pos--) {
15161515
cfg_instr *instr = &bb->b_instr[pos];
1517-
15181516
if (instr->i_opcode == NOP) {
15191517
continue;
15201518
}
15211519

1522-
if (instr->i_opcode == BUILD_LIST && instr->i_oparg == 0) {
1523-
/* Sequence start, we are done. */
1524-
if (PyList_Reverse(list) < 0) {
1525-
goto error;
1520+
if (instr->i_opcode == BUILD_LIST &&instr->i_oparg == 0) {
1521+
start_found = expect_append;
1522+
break;
1523+
}
1524+
1525+
if (expect_append) {
1526+
if (!(instr->i_opcode == LIST_APPEND && instr->i_oparg == 1)) {
1527+
break;
15261528
}
1527-
PyObject *newconst = PyList_AsTuple(list);
1528-
if (newconst == NULL) {
1529-
goto error;
1529+
}
1530+
else {
1531+
if (!loads_const(instr->i_opcode)) {
1532+
break;
15301533
}
1531-
Py_DECREF(list);
1532-
int nops = (int)PyTuple_Size(newconst) * 2 + 1;
1533-
nop_out(bb, i-1, nops);
1534-
return instr_make_load_const(intrinsic, newconst, consts, const_cache);
1534+
consts_found++;
15351535
}
15361536

1537-
if (pos < 1) {
1538-
/* Can't process 2 instructions. */
1539-
goto exit;
1540-
}
1537+
expect_append = !expect_append;
1538+
}
15411539

1542-
if (!(instr->i_opcode == LIST_APPEND && instr->i_oparg == 1)) {
1543-
goto exit;
1544-
}
1540+
if (!start_found) {
1541+
return SUCCESS;
1542+
}
15451543

1546-
instr = &bb->b_instr[--pos];
1544+
PyObject *newconst = PyTuple_New((Py_ssize_t)consts_found);
1545+
if (newconst == NULL) {
1546+
return ERROR;
1547+
}
1548+
1549+
int nops = consts_found * 2 + 1;
1550+
for (int pos = i-1; pos >= 0 && consts_found > 0; pos--) {
1551+
cfg_instr *instr = &bb->b_instr[pos];
15471552
if (!loads_const(instr->i_opcode)) {
1548-
goto exit;
1553+
continue;
15491554
}
1550-
15511555
PyObject *constant = get_const_value(instr->i_opcode, instr->i_oparg, consts);
15521556
if (constant == NULL) {
1553-
goto error;
1554-
}
1555-
1556-
int r = PyList_Append(list, constant);
1557-
Py_DECREF(constant);
1558-
if (r < 0) {
1559-
goto error;
1557+
Py_DECREF(newconst);
1558+
return ERROR;
15601559
}
1560+
PyTuple_SET_ITEM(newconst, --consts_found, constant);
15611561
}
15621562

1563-
exit:
1564-
Py_DECREF(list);
1565-
return SUCCESS;
1566-
error:
1567-
Py_DECREF(list);
1568-
return ERROR;
1563+
assert(consts_found == 0);
1564+
nop_out(bb, i-1, nops);
1565+
return instr_make_load_const(intrinsic, newconst, consts, const_cache);
15691566
}
15701567

15711568
#define MIN_CONST_SEQUENCE_SIZE 3

0 commit comments

Comments
 (0)