Note [Do not eta-expand join points]
Similarly to CPR (see Note [Don't w/w join points for CPR] in GHC.Core.Opt.WorkWrap), a join point stands well to gain from its outer binding's eta-expansion, and eta-expanding a join point is fraught with issues like how to deal with a cast: let join $j1 :: IO () $j1 = ... $j2 :: Int -> IO () $j2 n = if n > 0 then $j1 else ... => let join $j1 :: IO () $j1 = (\eta -> ...) `cast` N:IO :: State# RealWorld -> (# State# RealWorld, ()) ~ IO () $j2 :: Int -> IO () $j2 n = (\eta -> if n > 0 then $j1 else ...) `cast` N:IO :: State# RealWorld -> (# State# RealWorld, ()) ~ IO () The cast here can't be pushed inside the lambda (since it's not casting to a function type), so the lambda has to stay, but it can't because it contains a reference to a join point. In fact, $j2 can't be eta-expanded at all. Rather than try and detect this situation (and whatever other situations crop up!), we don't bother; again, any surrounding eta-expansion will improve these join points anyway, since an outer cast can *always* be pushed inside. By the time CorePrep comes around, the code is very likely to look more like this: let join $j1 :: State# RealWorld -> (# State# RealWorld, ()) $j1 = (...) eta $j2 :: Int -> State# RealWorld -> (# State# RealWorld, ()) $j2 = if n > 0 then $j1 else (...) eta
References 1
- Don't w/w join points for CPR GHC.Core.Opt.WorkWrap
Referenced by 7
- GHC.CoreToStg.Prep call site ×2
- Invariants on join points GHC.Core
- Arity for recursive join bindings GHC.Core.Opt.Arity
- GHC.Core.Opt.Arity call site
- Eta-expand stable unfoldings GHC.Core.Opt.Simplify.Iteration
- GHC.Core.Opt.Simplify.Utils call site