Need a bit more case-of-case in Inital Phase
This comment in !7997 (merged) describes an infelicity in floating.
In the nofib simple
benchmark we have
polynomial degree ... = ....(\xyz. foldr k z [1..degree])....
By the time we get to FloatOut we have (roughly)
polynomial degree ... = ....(\xyz. foldr k z (case degree of I# d# -> build (enum 1# d#))...
Do we float that [1..degree]
out of the \xyz
? Doing so kills fusion; but it shares the [1..degree]
which in general may be a big win.
General principle: trust the programmer: if fusion can happen, do it, even at the cost of floating.
In HEAD
- Fusion does not happen in
InitialPhase
because thecase
gets in between thefoldr
and thebuild
. - The
case
does not get pulled out of the strict argument becausesm_case_case
is off inInitialPhase
. - We don't float because of the bizarre
Case [MFEs]
in SetLevels (c.f. #19001). It's a strict argument position, headed by acase
so we don't float. I'm trying to get rid of this strange special case. - So in the subsequent Phase 2 simplification (with
sm_case_case
on) fusion can happen, quite coincidentally.
So in HEAD we get fusion, but only by a fluke; and !7997 (merged) removes some of the bizarreness, so the fluke no longer happens.
As a result, simple
allocates 28% more.
I think the right solution is to make more fusion happen in InitialPhase
. Maybe we can make sm_case_case
switch off case-of-case only for multi-alternative cases. I think those are the ones that are the true target of sm_case_case=False
(a sadly un-documented design).