summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-02-04 13:35:21 +1100
committerDamien George <damien.p.george@gmail.com>2018-02-04 13:35:21 +1100
commit253f2bd7be39e201db78960be456ac0f8c61b05f (patch)
treecd71af86aa0001133eeee2ae2b9076264cd59a02 /py
parent4b8e58756bf408f4a899d7cf787ed1961f6f9682 (diff)
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).
Diffstat (limited to 'py')
-rw-r--r--py/compile.c85
-rw-r--r--py/mpconfig.h2
2 files changed, 44 insertions, 43 deletions
diff --git a/py/compile.c b/py/compile.c
index 52d10ee5e..42ae8a829 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1941,51 +1941,52 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
} else {
plain_assign:
- if (MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
- && 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_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];
+ #if MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
+ 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_struct_t *pns0 = (mp_parse_node_struct_t*)pns->nodes[0];
- if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
- || MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)) {
- // can't optimise when it's a star expression on the lhs
- goto no_optimisation;
- }
- compile_node(comp, pns10->nodes[0]); // rhs
- compile_node(comp, pns10->nodes[1]); // rhs
- EMIT(rot_two);
- c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
- c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
- } else if (MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
- && 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_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[1]) == 3
- && MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 3) {
- // optimisation for a, b, c = d, e, f
- 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];
- if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
- || MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
- || MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr)) {
- // can't optimise when it's a star expression on the lhs
- goto no_optimisation;
+ pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
+ uint32_t n_pns0 = MP_PARSE_NODE_STRUCT_NUM_NODES(pns0);
+ // Can only optimise a tuple-to-tuple assignment when all of the following hold:
+ // - equal number of items in LHS and RHS tuples
+ // - 2 or 3 items in the tuples
+ // - there are no star expressions in the LHS tuple
+ if (n_pns0 == MP_PARSE_NODE_STRUCT_NUM_NODES(pns1)
+ && (n_pns0 == 2
+ #if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
+ || n_pns0 == 3
+ #endif
+ )
+ && !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
+ && !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
+ #if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
+ && (n_pns0 == 2 || !MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr))
+ #endif
+ ) {
+ // Optimisation for a, b = c, d or a, b, c = d, e, f
+ compile_node(comp, pns1->nodes[0]); // rhs
+ compile_node(comp, pns1->nodes[1]); // rhs
+ #if MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
+ if (n_pns0 == 3) {
+ compile_node(comp, pns1->nodes[2]); // rhs
+ EMIT(rot_three);
+ }
+ #endif
+ EMIT(rot_two);
+ c_assign(comp, pns0->nodes[0], 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
+ }
+ #endif
+ return;
}
- 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_two);
- 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[2], ASSIGN_STORE); // lhs store
- } else {
- no_optimisation:
- compile_node(comp, pns->nodes[1]); // rhs
- c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
}
+ #endif
+
+ compile_node(comp, pns->nodes[1]); // rhs
+ c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
}
} else {
goto plain_assign;
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 763bb378e..f2a8c98cb 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -347,7 +347,7 @@
#endif
// 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
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
#endif