@@ -603,12 +603,13 @@ void compile_generic_tuple(compiler_t *comp, mp_parse_node_struct_t *pns) {
603603}
604604
605605STATIC bool node_is_const_false (mp_parse_node_t pn ) {
606- return MP_PARSE_NODE_IS_TOKEN_KIND (pn , MP_TOKEN_KW_FALSE );
607- // untested: || (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) == 0);
606+ return MP_PARSE_NODE_IS_TOKEN_KIND (pn , MP_TOKEN_KW_FALSE )
607+ || (MP_PARSE_NODE_IS_SMALL_INT (pn ) && MP_PARSE_NODE_LEAF_SMALL_INT (pn ) == 0 );
608608}
609609
610610STATIC bool node_is_const_true (mp_parse_node_t pn ) {
611- return MP_PARSE_NODE_IS_TOKEN_KIND (pn , MP_TOKEN_KW_TRUE ) || (MP_PARSE_NODE_IS_SMALL_INT (pn ) && MP_PARSE_NODE_LEAF_SMALL_INT (pn ) == 1 );
611+ return MP_PARSE_NODE_IS_TOKEN_KIND (pn , MP_TOKEN_KW_TRUE )
612+ || (MP_PARSE_NODE_IS_SMALL_INT (pn ) && MP_PARSE_NODE_LEAF_SMALL_INT (pn ) != 0 );
612613}
613614
614615#if MICROPY_EMIT_CPYTHON
@@ -1658,24 +1659,30 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
16581659
16591660 uint l_end = comp_next_label (comp );
16601661
1661- uint l_fail = comp_next_label (comp );
1662- c_if_cond (comp , pns -> nodes [0 ], false, l_fail ); // if condition
1662+ // optimisation: don't emit anything when "if False" (not in CPython)
1663+ if (MICROPY_EMIT_CPYTHON || !node_is_const_false (pns -> nodes [0 ])) {
1664+ uint l_fail = comp_next_label (comp );
1665+ c_if_cond (comp , pns -> nodes [0 ], false, l_fail ); // if condition
16631666
1664- compile_node (comp , pns -> nodes [1 ]); // if block
1667+ compile_node (comp , pns -> nodes [1 ]); // if block
16651668
1666- if (
1667- #if !MICROPY_EMIT_CPYTHON
1668- // optimisation to not jump over non-existent elif/else blocks (this optimisation is not in CPython)
1669- !(MP_PARSE_NODE_IS_NULL (pns -> nodes [2 ]) && MP_PARSE_NODE_IS_NULL (pns -> nodes [3 ])) &&
1670- #endif
1671- // optimisation to not jump if last instruction was return
1672- !EMIT (last_emit_was_return_value )
1673- ) {
1674- // jump over elif/else blocks
1675- EMIT_ARG (jump , l_end );
1676- }
1669+ // optimisation: skip everything else when "if True" (not in CPython)
1670+ if (!MICROPY_EMIT_CPYTHON && node_is_const_true (pns -> nodes [0 ])) {
1671+ goto done ;
1672+ }
16771673
1678- EMIT_ARG (label_assign , l_fail );
1674+ if (
1675+ // optimisation: don't jump over non-existent elif/else blocks (not in CPython)
1676+ (MICROPY_EMIT_CPYTHON || !(MP_PARSE_NODE_IS_NULL (pns -> nodes [2 ]) && MP_PARSE_NODE_IS_NULL (pns -> nodes [3 ])))
1677+ // optimisation: don't jump if last instruction was return
1678+ && !EMIT (last_emit_was_return_value )
1679+ ) {
1680+ // jump over elif/else blocks
1681+ EMIT_ARG (jump , l_end );
1682+ }
1683+
1684+ EMIT_ARG (label_assign , l_fail );
1685+ }
16791686
16801687 // compile elif blocks (if any)
16811688 mp_parse_node_t * pn_elif ;
@@ -1684,19 +1691,30 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
16841691 assert (MP_PARSE_NODE_IS_STRUCT_KIND (pn_elif [i ], PN_if_stmt_elif )); // should be
16851692 mp_parse_node_struct_t * pns_elif = (mp_parse_node_struct_t * )pn_elif [i ];
16861693
1687- l_fail = comp_next_label (comp );
1688- c_if_cond (comp , pns_elif -> nodes [0 ], false, l_fail ); // elif condition
1694+ // optimisation: don't emit anything when "if False" (not in CPython)
1695+ if (MICROPY_EMIT_CPYTHON || !node_is_const_false (pns_elif -> nodes [0 ])) {
1696+ uint l_fail = comp_next_label (comp );
1697+ c_if_cond (comp , pns_elif -> nodes [0 ], false, l_fail ); // elif condition
16891698
1690- compile_node (comp , pns_elif -> nodes [1 ]); // elif block
1691- if (!EMIT (last_emit_was_return_value )) { // simple optimisation to align with CPython
1692- EMIT_ARG (jump , l_end );
1699+ compile_node (comp , pns_elif -> nodes [1 ]); // elif block
1700+
1701+ // optimisation: skip everything else when "elif True" (not in CPython)
1702+ if (!MICROPY_EMIT_CPYTHON && node_is_const_true (pns_elif -> nodes [0 ])) {
1703+ goto done ;
1704+ }
1705+
1706+ // optimisation: don't jump if last instruction was return
1707+ if (!EMIT (last_emit_was_return_value )) {
1708+ EMIT_ARG (jump , l_end );
1709+ }
1710+ EMIT_ARG (label_assign , l_fail );
16931711 }
1694- EMIT_ARG (label_assign , l_fail );
16951712 }
16961713
16971714 // compile else block
16981715 compile_node (comp , pns -> nodes [3 ]); // can be null
16991716
1717+ done :
17001718 EMIT_ARG (label_assign , l_end );
17011719}
17021720
@@ -1735,12 +1753,16 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
17351753 EMIT (pop_block );
17361754 }
17371755#else
1738- uint top_label = comp_next_label (comp );
1739- EMIT_ARG (jump , continue_label );
1740- EMIT_ARG (label_assign , top_label );
1741- compile_node (comp , pns -> nodes [1 ]); // body
1742- EMIT_ARG (label_assign , continue_label );
1743- c_if_cond (comp , pns -> nodes [0 ], true, top_label ); // condition
1756+ if (!node_is_const_false (pns -> nodes [0 ])) { // optimisation: don't emit anything for "while False"
1757+ uint top_label = comp_next_label (comp );
1758+ if (!node_is_const_true (pns -> nodes [0 ])) { // optimisation: don't jump to cond for "while True"
1759+ EMIT_ARG (jump , continue_label );
1760+ }
1761+ EMIT_ARG (label_assign , top_label );
1762+ compile_node (comp , pns -> nodes [1 ]); // body
1763+ EMIT_ARG (label_assign , continue_label );
1764+ c_if_cond (comp , pns -> nodes [0 ], true, top_label ); // condition
1765+ }
17441766#endif
17451767
17461768 // break/continue apply to outer loop (if any) in the else block
0 commit comments