diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2022-06-28 09:34:36 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2022-06-28 09:37:13 +0100 |
commit | efa5c3a1d33439194be37a7337166a7e30b8921a (patch) | |
tree | 9faee26612d728f84693f2315e3b37e214885296 /compiler/GHC/Core/Lint.hs | |
parent | 16b9100c9ef6b34b88a52b3b9e663dd40abd028f (diff) | |
download | haskell-wip/T21716.tar.gz |
Comments only, about join pointswip/T21716
This MR just adds some documentation about why casts
destroy join points, following #21716.
Diffstat (limited to 'compiler/GHC/Core/Lint.hs')
-rw-r--r-- | compiler/GHC/Core/Lint.hs | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/compiler/GHC/Core/Lint.hs b/compiler/GHC/Core/Lint.hs index 738dec2444..c126f6e981 100644 --- a/compiler/GHC/Core/Lint.hs +++ b/compiler/GHC/Core/Lint.hs @@ -884,7 +884,8 @@ lintCoreExpr (Lit lit) = return (literalType lit, zeroUE) lintCoreExpr (Cast expr co) - = do (expr_ty, ue) <- markAllJoinsBad $ lintCoreExpr expr + = do (expr_ty, ue) <- markAllJoinsBad (lintCoreExpr expr) + -- markAllJoinsBad: see Note [Join points and casts] to_ty <- lintCastExpr expr expr_ty co return (to_ty, ue) @@ -1214,7 +1215,40 @@ checkLinearity body_ue lam_var = err_msg mult = text "Linearity failure in lambda:" <+> ppr lam_var $$ ppr lhs <+> text "⊈" <+> ppr mult -{- +{- Note [Join points and casts] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You might think that this should be OK: + join j x = rhs + in (case e of + A -> alt1 + B x -> (jump j x) |> co) + +You might think that, since the cast is ultimately erased, the jump to +`j` should still be OK as a join point. But no! See #21716. Suppose + + newtype Age = MkAge Int -- axAge :: Age ~ Int + f :: Int -> ... -- f strict in it's first argument + +and consider the expression + + f (join j :: Bool -> Age + j x = (rhs1 :: Age) + in case v of + Just x -> (j x |> axAge :: Int) + Nothing -> rhs2) + +Then, if the Simplifier pushes the strict call into the join points +and alternatives we'll get + + join j' x = f (rhs1 :: Age) + in case v of + Just x -> j' x |> axAge + Nothing -> f rhs2 + +Utterly bogus. `f` expects an `Int` and we are giving it an `Age`. +No no no. Casts destroy the tail-call property. Henc markAllJoinsBad +in the (Cast expr co) case of lintCoreExpr. + Note [No alternatives lint check] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Case expressions with no alternatives are odd beasts, and it would seem |