Simplifier doing multiple iterations unnecessarily
When looking at the Simplifier, I came across a couple of places in which we were doing multiple Simplifier iterations where one would do.
I'm describing them here by quoting the Notes that I added when fixing them.
Strict data constructors
Note [Case elim in exprIsConApp_maybe]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose we have
data K a = MkK !a
$WMkK x = case x of y -> K y -- Wrapper for MkK
...case $WMkK v of K w -> <rhs>
We call `exprIsConApp_maybe` on ($WMkK v); we inline the wrapper
and beta-reduce, so we get to
exprIsConApp_maybe (case v of y -> K y)
So we may float the case, and end up with
case v of y -> <rhs>[y/w]
But if `v` is already evaluated, the next run of the Simplifier will
eliminate the case, and we may then make more progress with <rhs>.
Better to do it in one iteration. Hence the `do_case_elim`
check in `exprIsConApp_maybe`.
Used-one variables
Note [Post-inline for single-use things]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we have
let x = rhs in ...x...
and `x` is used exactly once, and not inside a lambda, then we will usually
preInlineUnconditinally. But we can still get this situation in
postInlineUnconditionally:
case K rhs of K x -> ...x....
Here we'll use `simplAuxBind` to bind `x` to (the already-simplified) `rhs`;
and `x` is used exactly once. It's beneficial to inline right away; otherwise
we risk creating
let x = rhs in ...x...
which will take another iteration of the Simplifier to eliminate. What a waste!
We take advantage of the used-once info in two places
1. In the full `postInlineUnconditionally` look for the special case
of "one occurrence, not under a lambda", and inline unconditionally then.
2. `simplAuxBind` does a kind of poor-man's `postInlineUnconditionally`. It
does not need to account for many of the cases (e.g. top level) that the
full `postInlineUnconditionally` does. Moreover, we don't have an
OutId, which `postInlineUnconditionally` needs. I got a slight improvement
in compiler performance when I added this test.