Note [Abstract over coercions]
If a coercion variable (g :: a ~ Int) is free in the RHS, then so is the
type variable a. Rather than sort this mess out, we simply bale out and abstract
wrt all the type variables if any of them are coercion variables.
Historical note: if you use let-bindings instead of a substitution, beware of this:
Suppose we start with:
x = /\ a -> let g = G in E
Then we'll float to get
x = let poly_g = /\ a -> G
in /\ a -> let g = poly_g a in E
But now the occurrence analyser will see just one occurrence
of poly_g, not inside a lambda, so the simplifier will
PreInlineUnconditionally poly_g back into g! Badk to square 1!
(I used to think that the "don't inline lone occurrences" stuff
would stop this happening, but since it's the *only* occurrence,
PreInlineUnconditionally kicks in first!)
Solution: put an INLINE note on g's RHS, so that poly_g seems
to appear many times. (NB: mkInlineMe eliminates
such notes on trivial RHSs, so do it manually.)
************************************************************************
* *
prepareAlts
* *
************************************************************************
prepareAlts tries these things:
1. filterAlts: eliminate alternatives that cannot match, including
the DEFAULT alternative. Here "cannot match" includes knowledge
from GADTs
2. refineDefaultAlt: if the DEFAULT alternative can match only one
possible constructor, then make that constructor explicit.
e.g.
case e of x { DEFAULT -> rhs }
===>
case e of x { (a,b) -> rhs }
where the type is a single constructor type. This gives better code
when rhs also scrutinises x or e.
See GHC.Core.Utils Note [Refine DEFAULT case alternatives]
3. combineIdenticalAlts: combine identical alternatives into a DEFAULT.
See CoreUtils Note [Combine identical alternatives], which also
says why we do this on InAlts not on OutAlts
4. Returns a list of the constructors that cannot holds in the
DEFAULT alternative (if there is one)
It's a good idea to do this stuff before simplifying the alternatives, to
avoid simplifying alternatives we know can't happen, and to come up with
the list of constructors that are handled, to put into the IdInfo of the
case binder, for use when simplifying the alternatives.
Eliminating the default alternative in (1) isn't so obvious, but it can
happen:
data Colour = Red | Green | Blue
f x = case x of
Red -> ..
Green -> ..
DEFAULT -> h x
h y = case y of
Blue -> ..
DEFAULT -> [ case y of ... ]
If we inline h into f, the default case of the inlined h can't happen.
If we don't notice this, we may end up filtering out *all* the cases
of the inner case y, which give us nowhere to go! References 2
- Combine identical alternatives GHC.Core.Utils
- Refine DEFAULT case alternatives GHC.Core.Utils
Referenced by 0
Nothing in the tree points here.