Note [Pin evaluatedness on floats]

GHC/CoreToStg/Prep.hs:1820 compiler

When creating a new float `sat=e` in `mkNonRecFloat`, we propagate `sat` with an
`evaldUnfolding` if `e` is a value.

To see why, consider a call to a CBV function, such as a DataCon worker with
*strict* fields, in an argument context, such as

  data Box a = Box !a
  ... f (Box e) ...

where `f` is *lazy* and `e` is ok-for-spec, e.g. `e = I# (x +# 1#)`.
After ANFisation, we want to get the very nice code

  case x +# 1# of x' ->
  let sat = I# x' in
  let sat2 = Box sat in
  f sat2

Note that Case (2) of Note [wantFloatLocal] is in effect. That is,

  * x' is unlifted but ok-for-spec, hence floated out of the lazy arg of f
  * Since x' is unlifted, `I# x'` is a value, and so `sat` can be let-bound.
  * Since `sat` is a value, `Box sat` is a value as well, and so `sat2` can
    be let-bound.

Hence no thunk needs to be allocated! However, in order to recognise
`Box sat` as a value, it is crucial that the newly created `sat` has an
`evaldUnfolding`; otherwise the strict worker `Box` forces an eval on `sat`.
and we would get the far worse code

  let sat2 =
    case x +# 1# of x' ->
    case I# x' of sat' ->
    Box sat in
  f sat2

A live example of this is T24730, inspired by $walexGetByte.

References 1

Referenced by 1