Note [notWorthFloating]

GHC/Core/Opt/SetLevels.hs:1174 compiler 1 ticket

`notWorthFloating` returns True if the expression would be replaced by something
bigger than it is now.  One big goal is that floating should be idempotent.  Eg
if we replace e with (lvl79 x y) and then run FloatOut again, don't want to
replace (lvl79 x y) with (lvl83 x y)!

For example:
  abs_vars = tvars only:  return True if e is trivial,
                          but False for anything bigger
  abs_vars = [x] (an Id): return True for trivial, or an application (f x)
                          but False for (f x x)

(NWF1a) It's important to float Integer literals, so that they get shared, rather
  than being allocated every time round the loop.  Hence the litIsTrivial.

  Ditto literal strings (LitString), which we'd like to float to top
  level, which is now possible.

(NWF1b) You might think that a literal should never be applied to a value
  (hence n=0) but actually we can get (see test T23024):
      RUBBISH @(a->b) (x::a)
  See Note [Rubbish literals] in GHC.Types.Literal.  (Mind you, we should be
  in dead code at this point!)

(NWF2) We don’t float out variables applied only to type arguments, since the
  extra binding would be pointless: type arguments are completely erased.
  But *coercion* arguments aren’t (see Note [Coercion tokens] in
  "GHC.CoreToStg" and Note [inlineBoringOk] in"GHC.Core.Unfold"),
  so we still want to float out variables applied only to
  coercion arguments.

(NWF3) Some expressions have trivial wrappers:
     - Casts (e |> co)
     - Unary-class applications:
          - Dictionary applications (MkC meth)
          - Class-op applictions    (op dict)
     - Case of empty alts
     - Unsafe-equality case
  In all these cases we say "not worth floating", and we do so /regardless/
  of the wrapped expression.  The SetLevels stuff may subsequently float the
  components of the expression.

  Example:  is it worth floating (f x |> co)?  No!  If we did we'd get
     lvl = f x |> co
     ...lvl....
  Then we'd do cast worker/wrapper and end up with.
     lvl' = f x
     ...(lvl' |> co)...
  Silly!  Better not to float it in the first place.  If we say "no" here,
  we'll subsequently say "yes" for (f x) and get
     lvl = f x
     ....(lvl |> co)...
  which is what we want.  In short: don't float trivial wrappers.

(NWF4) The only non-trivial expression that we say "not worth floating" for
  is an application
             f x y z
  where the number of value arguments is <= the number of abstracted Ids.
  This is what makes floating idempotent.  Hence counting the number of
  value arguments in `go`

(NWF5) In #24471 we had something like
     x1 = I# 1
     ...
     x1000 = I# 1000
     foo = f x1 (f x2 (f x3 ....))
  So every sub-expression in `foo` has lots and lots of free variables.  But
  none of these sub-expressions float anywhere; the entire float-out pass is a
  no-op.

  So `notWorthFloating` tries to avoid evaluating `n_abs_vars`, in cases where
  it obviously /is/ worth floating.  (In #24471 it turned out that we were
  testing `abs_vars` (a relatively complicated calculation that takes at least
  O(n-free-vars) time to compute) for every sub-expression.)

  Hence testing `n_abs_vars only` at the very end.

References 3

Referenced by 1