Skip to content

SpecConstr: Denest local, non-recursive lets

Suppose we see (local or at top-level)

  f xs = let binds in g as;
  rest

where

  • binds binds g

  • xs don't occur in binds and

  • as do not mention binds. In this situation it might be interesting to specialise f and g for call patterns in rest, but it is difficult to do it in this nested form, because

    1. We only get to see ScrutOccs on g, in its RHS
    2. The interesting call patterns in rest apply only to f
    3. Specialising f and g for those call patterns duplicates binds twice: We keep one copy of bind in the original f, one copy of bind in $sf and another specialised copy $sbind (containing $sg) in $sf.

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 ScrutOccs 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.

Edited by Sebastian Graf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information