Skip to content

Commit 694a5fd

Browse files
committed
make 2 passes to avoid unnecessary allocations
1 parent c8ceedf commit 694a5fd

File tree

1 file changed

+36
-39
lines changed

1 file changed

+36
-39
lines changed

Python/flowgraph.c

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

1480-
PyObject *list = PyList_New(0);
1481-
if (list == NULL) {
1482-
return ERROR;
1483-
}
1480+
int consts_found = 0;
1481+
bool start_found = false;
1482+
bool expect_append = true;
14841483

14851484
for (int pos = i-1; pos >= 0; pos--) {
14861485
cfg_instr *instr = &bb->b_instr[pos];
1487-
14881486
if (instr->i_opcode == NOP) {
14891487
continue;
14901488
}
14911489

1492-
if (instr->i_opcode == BUILD_LIST && instr->i_oparg == 0) {
1493-
/* Sequence start, we are done. */
1494-
if (PyList_Reverse(list) < 0) {
1495-
goto error;
1490+
if (instr->i_opcode == BUILD_LIST &&instr->i_oparg == 0) {
1491+
start_found = expect_append;
1492+
break;
1493+
}
1494+
1495+
if (expect_append) {
1496+
if (!(instr->i_opcode == LIST_APPEND && instr->i_oparg == 1)) {
1497+
break;
14961498
}
1497-
PyObject *newconst = PyList_AsTuple(list);
1498-
if (newconst == NULL) {
1499-
goto error;
1499+
}
1500+
else {
1501+
if (!loads_const(instr->i_opcode)) {
1502+
break;
15001503
}
1501-
Py_DECREF(list);
1502-
int nops = (int)PyTuple_Size(newconst) * 2 + 1;
1503-
nop_out(bb, i-1, nops);
1504-
return instr_make_load_const(intrinsic, newconst, consts, const_cache);
1504+
consts_found++;
15051505
}
15061506

1507-
if (pos < 1) {
1508-
/* Can't process 2 instructions. */
1509-
goto exit;
1510-
}
1507+
expect_append = !expect_append;
1508+
}
15111509

1512-
if (!(instr->i_opcode == LIST_APPEND && instr->i_oparg == 1)) {
1513-
goto exit;
1514-
}
1510+
if (!start_found) {
1511+
return SUCCESS;
1512+
}
15151513

1516-
instr = &bb->b_instr[--pos];
1514+
PyObject *newconst = PyTuple_New((Py_ssize_t)consts_found);
1515+
if (newconst == NULL) {
1516+
return ERROR;
1517+
}
1518+
1519+
int nops = consts_found * 2 + 1;
1520+
for (int pos = i-1; pos >= 0 && consts_found > 0; pos--) {
1521+
cfg_instr *instr = &bb->b_instr[pos];
15171522
if (!loads_const(instr->i_opcode)) {
1518-
goto exit;
1523+
continue;
15191524
}
1520-
15211525
PyObject *constant = get_const_value(instr->i_opcode, instr->i_oparg, consts);
15221526
if (constant == NULL) {
1523-
goto error;
1524-
}
1525-
1526-
int r = PyList_Append(list, constant);
1527-
Py_DECREF(constant);
1528-
if (r < 0) {
1529-
goto error;
1527+
Py_DECREF(newconst);
1528+
return ERROR;
15301529
}
1530+
PyTuple_SET_ITEM(newconst, --consts_found, constant);
15311531
}
15321532

1533-
exit:
1534-
Py_DECREF(list);
1535-
return SUCCESS;
1536-
error:
1537-
Py_DECREF(list);
1538-
return ERROR;
1533+
assert(consts_found == 0);
1534+
nop_out(bb, i-1, nops);
1535+
return instr_make_load_const(intrinsic, newconst, consts, const_cache);
15391536
}
15401537

15411538
#define MIN_CONST_SEQUENCE_SIZE 3

0 commit comments

Comments
 (0)