Note [Binder swap]

GHC/Core/Opt/OccurAnal.hs:3188 compiler

The "binder swap" transformation swaps occurrence of the
scrutinee of a case for occurrences of the case-binder:

 (1)  case x of b { pi -> ri }
         ==>
      case x of b { pi -> ri[b/x] }

 (2)  case (x |> co) of b { pi -> ri }
        ==>
      case (x |> co) of b { pi -> ri[b |> sym co/x] }

The substitution ri[b/x] etc is done by the occurrence analyser.
See Note [The binder-swap substitution].

There are two reasons for making this swap:

(A) It reduces the number of occurrences of the scrutinee, x.
    That in turn might reduce its occurrences to one, so we
    can inline it and save an allocation.  E.g.
      let x = factorial y in case x of b { I# v -> ...x... }
    If we replace 'x' by 'b' in the alternative we get
      let x = factorial y in case x of b { I# v -> ...b... }
    and now we can inline 'x', thus
      case (factorial y) of b { I# v -> ...b... }

(B) The case-binder b has unfolding information; in the
    example above we know that b = I# v. That in turn allows
    nested cases to simplify.  Consider
       case x of b { I# v ->
       ...(case x of b2 { I# v2 -> rhs })...
    If we replace 'x' by 'b' in the alternative we get
       case x of b { I# v ->
       ...(case b of b2 { I# v2 -> rhs })...
    and now it is trivial to simplify the inner case:
       case x of b { I# v ->
       ...(let b2 = b in rhs)...

    The same can happen even if the scrutinee is a variable
    with a cast: see Note [Case of cast]

The reason for doing these transformations /here in the occurrence
analyser/ is because it allows us to adjust the OccInfo for 'x' and
'b' as we go.

  * Suppose the only occurrences of 'x' are the scrutinee and in the
    ri; then this transformation makes it occur just once, and hence
    get inlined right away.

  * If instead the Simplifier replaces occurrences of x with
    occurrences of b, that will mess up b's occurrence info. That in
    turn might have consequences.

There is a danger though.  Consider
      let v = x +# y
      in case (f v) of w -> ...v...v...
And suppose that (f v) expands to just v.  Then we'd like to
use 'w' instead of 'v' in the alternative.  But it may be too
late; we may have substituted the (cheap) x+#y for v in the
same simplifier pass that reduced (f v) to v.

I think this is just too bad.  CSE will recover some of it.

References 2

Referenced by 5