Simplifier improvements, esp avoiding unnecessary iteration
This ticket started when I noted that the simplifier was taking two iterations when one would do, but that led me down a long rabbit hole. Here are the things I found:
-
Consider
case K e of K y{Occ=Once} -> blah
Since y occurs just once in
blah
we can do preInlineUnconditionally when we eliminate the case. We weren't doing that. -
We were repeatedly simplify coercions, some of which were big. This happened when we have
let f = \x. ...|> co.... in ...
and then inline f, where f is big. We don't want to re-simplify co each time we inline f. Once is enough!
-
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 toexprIsConApp_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. -
We make join point that are so small that we immediately inline them again. Silly.
-
There is also a long-running but hard-to-describe saga about how to inline join points. If you are too eager, you get exponential blowup. I ran into more of this when I was in the rabbit hole.