Skip to content

Commit 70ce2c8

Browse files
committed
fold in codegen instead of cfg
1 parent efbaea3 commit 70ce2c8

File tree

3 files changed

+19
-157
lines changed

3 files changed

+19
-157
lines changed

Lib/test/test_peepholer.py

-65
Original file line numberDiff line numberDiff line change
@@ -1349,71 +1349,6 @@ def test_fold_tuple_of_constants(self):
13491349
]
13501350
self.cfg_optimization_test(same, same, consts=[])
13511351

1352-
def test_fold_constant_intrinsic_list_to_tuple(self):
1353-
INTRINSIC_LIST_TO_TUPLE = 6
1354-
1355-
# long tuple
1356-
consts = 1000
1357-
before = (
1358-
[('BUILD_LIST', 0, 0)] +
1359-
[('LOAD_CONST', 0, 0), ('LIST_APPEND', 1, 0)] * consts +
1360-
[('CALL_INTRINSIC_1', INTRINSIC_LIST_TO_TUPLE, 0), ('RETURN_VALUE', None, 0)]
1361-
)
1362-
after = [
1363-
('LOAD_CONST', 1, 0),
1364-
('RETURN_VALUE', None, 0)
1365-
]
1366-
result_const = tuple(["test"] * consts)
1367-
self.cfg_optimization_test(before, after, consts=["test"], expected_consts=["test", result_const])
1368-
1369-
# empty list
1370-
before = [
1371-
('BUILD_LIST', 0, 0),
1372-
('CALL_INTRINSIC_1', INTRINSIC_LIST_TO_TUPLE, 0),
1373-
('RETURN_VALUE', None, 0)
1374-
]
1375-
after = [
1376-
('LOAD_CONST', 0, 0),
1377-
('RETURN_VALUE', None, 0)
1378-
]
1379-
self.cfg_optimization_test(before, after, consts=[], expected_consts=[()])
1380-
1381-
# multiple BUILD_LIST 0: ([], 1, [], 2)
1382-
same = [
1383-
('BUILD_LIST', 0, 0),
1384-
('BUILD_LIST', 0, 0),
1385-
('LIST_APPEND', 1, 0),
1386-
('LOAD_SMALL_INT', 1, 0),
1387-
('LIST_APPEND', 1, 0),
1388-
('BUILD_LIST', 0, 0),
1389-
('LIST_APPEND', 1, 0),
1390-
('LOAD_SMALL_INT', 2, 0),
1391-
('LIST_APPEND', 1, 0),
1392-
('CALL_INTRINSIC_1', INTRINSIC_LIST_TO_TUPLE, 0),
1393-
('RETURN_VALUE', None, 0)
1394-
]
1395-
self.cfg_optimization_test(same, same, consts=[])
1396-
1397-
# nested folding: (1, 1+1, 3)
1398-
before = [
1399-
('BUILD_LIST', 0, 0),
1400-
('LOAD_SMALL_INT', 1, 0),
1401-
('LIST_APPEND', 1, 0),
1402-
('LOAD_SMALL_INT', 1, 0),
1403-
('LOAD_SMALL_INT', 1, 0),
1404-
('BINARY_OP', get_binop_argval('NB_ADD'), 0),
1405-
('LIST_APPEND', 1, 0),
1406-
('LOAD_SMALL_INT', 3, 0),
1407-
('LIST_APPEND', 1, 0),
1408-
('CALL_INTRINSIC_1', INTRINSIC_LIST_TO_TUPLE, 0),
1409-
('RETURN_VALUE', None, 0)
1410-
]
1411-
after = [
1412-
('LOAD_CONST', 0, 0),
1413-
('RETURN_VALUE', None, 0)
1414-
]
1415-
self.cfg_optimization_test(before, after, consts=[], expected_consts=[(1, 2, 3)])
1416-
14171352
def test_optimize_if_const_list(self):
14181353
before = [
14191354
('NOP', None, 0),

Python/codegen.c

+19
Original file line numberDiff line numberDiff line change
@@ -3250,6 +3250,25 @@ starunpack_helper_impl(compiler *c, location loc,
32503250
}
32513251
int sequence_built = 0;
32523252
if (big) {
3253+
if (tuple) {
3254+
PyObject *newconst = PyTuple_New(n);
3255+
if (newconst == NULL) {
3256+
return ERROR;
3257+
}
3258+
bool is_const = true;
3259+
for (Py_ssize_t i = 0; i < n; i++) {
3260+
expr_ty elt = asdl_seq_GET(elts, i);
3261+
if (elt->kind != Constant_kind) {
3262+
is_const = false;
3263+
Py_DECREF(newconst);
3264+
break;
3265+
}
3266+
PyTuple_SET_ITEM(newconst, i, Py_NewRef(elt->v.Constant.value));
3267+
}
3268+
if (is_const) {
3269+
return codegen_addop_load_const(c, loc, newconst);
3270+
}
3271+
}
32533272
ADDOP_I(c, loc, build, pushed);
32543273
sequence_built = 1;
32553274
}

Python/flowgraph.c

-92
Original file line numberDiff line numberDiff line change
@@ -1452,95 +1452,6 @@ fold_tuple_of_constants(basicblock *bb, int i, PyObject *consts, PyObject *const
14521452
return SUCCESS;
14531453
}
14541454

1455-
/* Replace:
1456-
BUILD_LIST 0
1457-
LOAD_CONST c1
1458-
LIST_APPEND 1
1459-
LOAD_CONST c2
1460-
LIST_APPEND 1
1461-
...
1462-
LOAD_CONST cN
1463-
LIST_APPEND 1
1464-
CALL_INTRINSIC_1 INTRINSIC_LIST_TO_TUPLE
1465-
with:
1466-
LOAD_CONST (c1, c2, ... cN)
1467-
*/
1468-
static int
1469-
fold_constant_intrinsic_list_to_tuple(basicblock *bb, int i,
1470-
PyObject *consts, PyObject *const_cache)
1471-
{
1472-
assert(PyDict_CheckExact(const_cache));
1473-
assert(PyList_CheckExact(consts));
1474-
assert(i >= 0);
1475-
assert(i < bb->b_iused);
1476-
cfg_instr *intrinsic = &bb->b_instr[i];
1477-
assert(intrinsic->i_opcode == CALL_INTRINSIC_1);
1478-
assert(intrinsic->i_oparg == INTRINSIC_LIST_TO_TUPLE);
1479-
1480-
PyObject *list = PyList_New(0);
1481-
if (list == NULL) {
1482-
return ERROR;
1483-
}
1484-
1485-
bool expect_append = true;
1486-
1487-
for (int pos = i-1; pos >= 0; pos--) {
1488-
cfg_instr *instr = &bb->b_instr[pos];
1489-
1490-
if (instr->i_opcode == NOP) {
1491-
continue;
1492-
}
1493-
1494-
if (instr->i_opcode == BUILD_LIST && instr->i_oparg == 0) {
1495-
if (!expect_append) {
1496-
/* Not a sequence start */
1497-
goto exit;
1498-
}
1499-
/* Sequence start, we are done. */
1500-
if (PyList_Reverse(list) < 0) {
1501-
goto error;
1502-
}
1503-
PyObject *newconst = PyList_AsTuple(list);
1504-
if (newconst == NULL) {
1505-
goto error;
1506-
}
1507-
Py_DECREF(list);
1508-
int nops = (int)PyTuple_Size(newconst) * 2 + 1;
1509-
nop_out(bb, i-1, nops);
1510-
return instr_make_load_const(intrinsic, newconst, consts, const_cache);
1511-
}
1512-
1513-
if (expect_append) {
1514-
if (!(instr->i_opcode == LIST_APPEND && instr->i_oparg == 1)) {
1515-
goto exit;
1516-
}
1517-
}
1518-
else {
1519-
if (!loads_const(instr->i_opcode)) {
1520-
goto exit;
1521-
}
1522-
PyObject *constant = get_const_value(instr->i_opcode, instr->i_oparg, consts);
1523-
if (constant == NULL) {
1524-
goto error;
1525-
}
1526-
int r = PyList_Append(list, constant);
1527-
Py_DECREF(constant);
1528-
if (r < 0) {
1529-
goto error;
1530-
}
1531-
}
1532-
1533-
expect_append = !expect_append;
1534-
}
1535-
1536-
exit:
1537-
Py_DECREF(list);
1538-
return SUCCESS;
1539-
error:
1540-
Py_DECREF(list);
1541-
return ERROR;
1542-
}
1543-
15441455
#define MIN_CONST_SEQUENCE_SIZE 3
15451456
/*
15461457
Optimize lists and sets for:
@@ -2388,9 +2299,6 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
23882299
if (nextop == GET_ITER) {
23892300
INSTR_SET_OP0(inst, NOP);
23902301
}
2391-
else {
2392-
fold_constant_intrinsic_list_to_tuple(bb, i, consts, const_cache);
2393-
}
23942302
}
23952303
else if (oparg == INTRINSIC_UNARY_POSITIVE) {
23962304
RETURN_IF_ERROR(fold_const_unaryop(bb, i, consts, const_cache));

0 commit comments

Comments
 (0)