This will remove most potential size regressions from #10240 and #10381, and will also reduce code size slightly by itself.
If a JS if/else block has at least one branch break control flow (break, continue, throw, return), if we always flip the conditional so that it is the "then" block that has the control flow, we can drop the "else".
if (foo) {
return bar;
} else {
return baz;
}
should instead be simply
if (foo) {
return bar;
}
return baz;
(Obviously this is simplified - such a simple construct should be rewritten as a ternary, but I think the idea is clear).
Other cases:
if (foo) {
bar++;
} else {
break;
}
should instead be
if (!foo) {
break;
}
bar++;
We pay an extra byte to negate the boolean, but save 4 by dropping the else (and potentially more if the {}s were required).
This should be a very late normalization pass, so that other optimization passes get the benefit of this clear branching structure, and to ensure no mistake lets the JsStaticEval pass rewrite any extra !s back out to save a byte by flipping if/else again.
This will remove most potential size regressions from #10240 and #10381, and will also reduce code size slightly by itself.
If a JS if/else block has at least one branch break control flow (break, continue, throw, return), if we always flip the conditional so that it is the "then" block that has the control flow, we can drop the "else".
should instead be simply
(Obviously this is simplified - such a simple construct should be rewritten as a ternary, but I think the idea is clear).
Other cases:
should instead be
We pay an extra byte to negate the boolean, but save 4 by dropping the else (and potentially more if the
{}s were required).This should be a very late normalization pass, so that other optimization passes get the benefit of this clear branching structure, and to ensure no mistake lets the JsStaticEval pass rewrite any extra
!s back out to save a byte by flipping if/else again.