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).
This commit is contained in:
Damien George 2018-02-04 13:35:21 +11:00
parent 4b8e58756b
commit 253f2bd7be
2 changed files with 44 additions and 43 deletions

View File

@ -1941,52 +1941,53 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
} }
} else { } else {
plain_assign: plain_assign:
if (MICROPY_COMP_DOUBLE_TUPLE_ASSIGN #if MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr) if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)) {
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 2
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 2) {
// optimisation for a, b = c, d
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns->nodes[1];
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0]; mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr) pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)) { uint32_t n_pns0 = MP_PARSE_NODE_STRUCT_NUM_NODES(pns0);
// can't optimise when it's a star expression on the lhs // Can only optimise a tuple-to-tuple assignment when all of the following hold:
goto no_optimisation; // - equal number of items in LHS and RHS tuples
} // - 2 or 3 items in the tuples
compile_node(comp, pns10->nodes[0]); // rhs // - there are no star expressions in the LHS tuple
compile_node(comp, pns10->nodes[1]); // rhs if (n_pns0 == MP_PARSE_NODE_STRUCT_NUM_NODES(pns1)
EMIT(rot_two); && (n_pns0 == 2
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store #if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store || n_pns0 == 3
} else if (MICROPY_COMP_TRIPLE_TUPLE_ASSIGN #endif
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr) )
&& MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr) && !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 3 && !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
&& MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 3) { #if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
// optimisation for a, b, c = d, e, f && (n_pns0 == 2 || !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr))
mp_parse_node_struct_t *pns10 = (mp_parse_node_struct_t*)pns->nodes[1]; #endif
mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0]; ) {
if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr) // Optimisation for a, b = c, d or a, b, c = d, e, f
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr) compile_node(comp, pns1->nodes[0]); // rhs
|| MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr)) { compile_node(comp, pns1->nodes[1]); // rhs
// can't optimise when it's a star expression on the lhs #if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
goto no_optimisation; if (n_pns0 == 3) {
} compile_node(comp, pns1->nodes[2]); // rhs
compile_node(comp, pns10->nodes[0]); // rhs
compile_node(comp, pns10->nodes[1]); // rhs
compile_node(comp, pns10->nodes[2]); // rhs
EMIT(rot_three); EMIT(rot_three);
}
#endif
EMIT(rot_two); EMIT(rot_two);
c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
#if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
if (n_pns0 == 3) {
c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
} else { }
no_optimisation: #endif
return;
}
}
#endif
compile_node(comp, pns->nodes[1]); // rhs compile_node(comp, pns->nodes[1]); // rhs
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
} }
}
} else { } else {
goto plain_assign; goto plain_assign;
} }

View File

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