Selectors are inlined too vigorously
See this Note in GHC.Core.Utils
Note [Case expressions are work-free]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Are case-expressions work-free? Consider
let v = case x of (p,q) -> p
go = \y -> ...case v of ...
Should we inline 'v' at its use site inside the loop? At the moment
we do. I experimented with saying that case are *not* work-free, but
that increased allocation slightly. It's a fairly small effect, and at
the moment we go for the slightly more aggressive version which treats
(case x of ....) as work-free if the alternatives are.
Moreover it improves arities of overloaded functions where
there is only dictionary selection (no construction) involved
But when I was looking at the compiled code for mkTyConApp
I found that code like
let key = case tc of
FunTyCon u _ _ _ -> u
AlgTyCon u _ _ _ -> u
etc
in
...key...key...key...
was inlining that key at all the call sites, and thereby duplicating the eval of tc
and the case-branching involved. We should just do this once.
One solution: reverse the above Note. Another, less dramatic one: restrict it to cases where there is just one alternative.