Note [Floating in CorePrep]

GHC/CoreToStg/Prep.hs:287 compiler

ANFisation risks producing a lot of nested lets that obscures values:
  let v = (:) (f 14) [] in e
  ==> { ANF in CorePrep }
  let v = let sat = f 14 in (:) sat [] in e
Here, `v` is not a value anymore, and we'd allocate a thunk closure for `v` that
allocates a thunk for `sat` and then allocates the cons cell.
Hence we carry around a bunch of floated bindings with us so that we again
expose the values:
  let v = let sat = f 14 in (:) sat [] in e
  ==> { Float sat }
  let sat = f 14 in
  let v = (:) sat [] in e
(We will not do this transformation if `v` does not become a value afterwards;
see Note [wantFloatLocal].)
If `v` is bound at the top-level, we might even float `sat` to top-level;
see Note [Floating out of top level bindings].
For nested let bindings, we have to keep in mind Note [Core letrec invariant]
and may exploit strict contexts; see Note [wantFloatLocal].

There are 3 main categories of floats, encoded in the `FloatingBind` type:

  * `Float`: A floated binding, as `sat` above.
    These come in different flavours as described by their `FloatInfo` and
    `BindInfo`, which captures how far the binding can be floated and whether or
    not we want to case-bind. See Note [BindInfo and FloatInfo].
  * `UnsafeEqualityCase`: Used for floating around unsafeEqualityProof bindings;
    see (U3) of Note [Implementing unsafeCoerce].
    It's exactly a `Float` that is `CaseBound` and `LazyContextFloatable`
    (see `mkNonRecFloat`), but one that has a non-DEFAULT Case alternative to
    bind the unsafe coercion field of the Refl constructor.
  * `FloatTick`: A floated `Tick`. See Note [Floating Ticks in CorePrep].

It is quite essential that CorePrep *does not* rearrange the order in which
evaluations happen, in contrast to, e.g., FloatOut, because CorePrep lowers
the seq# primop into a Case (see Note [seq# magic]). Fortunately, CorePrep does
not attempt to reorder the telescope of Floats or float out out of non-floated
binding sites (such as Case alts) in the first place; for that it would have to
do some kind of data dependency analysis.

References 7

Referenced by 3