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.