SpecConstr: Denest local, non-recursive lets
Suppose we see (local or at top-level)
f xs = let binds in g as;
rest
where
-
binds
bindsg
-
xs
don't occur inbinds
and -
as
do not mentionbinds
. In this situation it might be interesting to specialisef
andg
for call patterns inrest
, but it is difficult to do it in this nested form, because- We only get to see
ScrutOcc
s ong
, in its RHS - The interesting call patterns in
rest
apply only tof
- Specialising
f
andg
for those call patterns duplicatesbinds
twice: We keep one copy ofbind
in the originalf
, one copy ofbind
in$sf
and another specialised copy$sbind
(containing$sg
) in$sf
.
- We only get to see
So for SpecConstr, we should float out binds
(removing potential join-point-ness)
binds; rest[f:=\xs -> g as]
Because now all call patterns of f
directly apply to g
and might match up
with one of the ScrutOcc
s in its RHS, while only needing a single duplicate of
bind
.
The idea works around some of the badness in #14951 and makes fixing #14844 less important.