Skip to content

Commit 253f2bd

Browse files
committed
py/compile: Combine compiler-opt of 2 and 3 tuple-to-tuple assignment.
This patch combines the compiler optimisation code for double and triple tuple-to-tuple assignment, taking it from two separate if-blocks to one combined if-block. This can be done because the code for both of these optimisations has a lot in common. Combining them together reduces code size for ports that have the triple-tuple optimisation enabled (and doesn't change code size for ports that have it disabled).
1 parent 4b8e587 commit 253f2bd

2 files changed

Lines changed: 44 additions & 43 deletions

File tree

py/compile.c

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,51 +1941,52 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
19411941
}
19421942
} else {
19431943
plain_assign:
1944-
if (MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
1945-
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
1946-
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1947-
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 2
1948-
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 2) {
1949-
// optimisation for a, b = c, d
1950-
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns->nodes[1];
1944+
#if MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
1945+
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
1946+
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)) {
19511947
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
1952-
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
1953-
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)) {
1954-
// can't optimise when it's a star expression on the lhs
1955-
goto no_optimisation;
1956-
}
1957-
compile_node(comp, pns10->nodes[0]); // rhs
1958-
compile_node(comp, pns10->nodes[1]); // rhs
1959-
EMIT(rot_two);
1960-
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1961-
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1962-
} else if (MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
1963-
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
1964-
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1965-
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 3
1966-
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 3) {
1967-
// optimisation for a, b, c = d, e, f
1968-
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns->nodes[1];
1969-
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
1970-
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
1971-
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
1972-
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr)) {
1973-
// can't optimise when it's a star expression on the lhs
1974-
goto no_optimisation;
1948+
pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
1949+
uint32_t n_pns0 = MP_PARSE_NODE_STRUCT_NUM_NODES(pns0);
1950+
// Can only optimise a tuple-to-tuple assignment when all of the following hold:
1951+
// - equal number of items in LHS and RHS tuples
1952+
// - 2 or 3 items in the tuples
1953+
// - there are no star expressions in the LHS tuple
1954+
if (n_pns0 == MP_PARSE_NODE_STRUCT_NUM_NODES(pns1)
1955+
&& (n_pns0 == 2
1956+
#if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
1957+
|| n_pns0 == 3
1958+
#endif
1959+
)
1960+
&& !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
1961+
&& !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
1962+
#if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
1963+
&& (n_pns0 == 2 || !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr))
1964+
#endif
1965+
) {
1966+
// Optimisation for a, b = c, d or a, b, c = d, e, f
1967+
compile_node(comp, pns1->nodes[0]); // rhs
1968+
compile_node(comp, pns1->nodes[1]); // rhs
1969+
#if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
1970+
if (n_pns0 == 3) {
1971+
compile_node(comp, pns1->nodes[2]); // rhs
1972+
EMIT(rot_three);
1973+
}
1974+
#endif
1975+
EMIT(rot_two);
1976+
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1977+
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1978+
#if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
1979+
if (n_pns0 == 3) {
1980+
c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1981+
}
1982+
#endif
1983+
return;
19751984
}
1976-
compile_node(comp, pns10->nodes[0]); // rhs
1977-
compile_node(comp, pns10->nodes[1]); // rhs
1978-
compile_node(comp, pns10->nodes[2]); // rhs
1979-
EMIT(rot_three);
1980-
EMIT(rot_two);
1981-
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1982-
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1983-
c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1984-
} else {
1985-
no_optimisation:
1986-
compile_node(comp, pns->nodes[1]); // rhs
1987-
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
19881985
}
1986+
#endif
1987+
1988+
compile_node(comp, pns->nodes[1]); // rhs
1989+
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
19891990
}
19901991
} else {
19911992
goto plain_assign;

py/mpconfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@
347347
#endif
348348

349349
// Whether to enable optimisation of: a, b, c = d, e, f
350-
// Cost 156 bytes (Thumb2)
350+
// Requires MICROPY_COMP_DOUBLE_TUPLE_ASSIGN and costs 68 bytes (Thumb2)
351351
#ifndef MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
352352
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
353353
#endif

0 commit comments

Comments
 (0)