[commit: ghc] master: Comments about join-point return types (0c07208)
git at git.haskell.org
git at git.haskell.org
Thu Sep 13 13:01:15 UTC 2018
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/0c0720874868f2a53d3411831b7faa2c03f3a393/ghc
>---------------------------------------------------------------
commit 0c0720874868f2a53d3411831b7faa2c03f3a393
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Wed Sep 12 13:21:02 2018 +0100
Comments about join-point return types
>---------------------------------------------------------------
0c0720874868f2a53d3411831b7faa2c03f3a393
compiler/simplCore/SimplEnv.hs | 42 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/compiler/simplCore/SimplEnv.hs b/compiler/simplCore/SimplEnv.hs
index 18d9f57..1d55f35 100644
--- a/compiler/simplCore/SimplEnv.hs
+++ b/compiler/simplCore/SimplEnv.hs
@@ -694,6 +694,34 @@ lookupRecBndr (SimplEnv { seInScope = in_scope, seIdSubst = ids }) v
These functions are in the monad only so that they can be made strict via seq.
+
+Note [Return type for join points]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider
+
+ (join j :: Char -> Int -> Int) 77
+ ( j x = \y. y + ord x )
+ (in case v of )
+ ( A -> j 'x' )
+ ( B -> j 'y' )
+ ( C -> <blah> )
+
+The simplifier pushes the "apply to 77" continuation inwards to give
+
+ join j :: Char -> Int
+ j x = (\y. y + ord x) 77
+ in case v of
+ A -> j 'x'
+ B -> j 'y'
+ C -> <blah> 77
+
+Notice that the "apply to 77" continuation went into the RHS of the
+join point. And that meant that the return type of the join point
+changed!!
+
+That's why we pass res_ty into simplNonRecJoinBndr, and substIdBndr
+takes a (Just res_ty) argument so that it knows to do the type-changing
+thing.
-}
simplBinders :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])
@@ -722,8 +750,9 @@ simplNonRecBndr env id
---------------
simplNonRecJoinBndr :: SimplEnv -> OutType -> InBndr
-> SimplM (SimplEnv, OutBndr)
--- A non-recursive let binder for a join point; context being pushed inward may
--- change the type
+-- A non-recursive let binder for a join point;
+-- context being pushed inward may change the type
+-- See Note [Return type for join points]
simplNonRecJoinBndr env res_ty id
= do { let (env1, id1) = substIdBndr (Just res_ty) env id
; seqId id1 `seq` return (env1, id1) }
@@ -738,8 +767,9 @@ simplRecBndrs env@(SimplEnv {}) ids
---------------
simplRecJoinBndrs :: SimplEnv -> OutType -> [InBndr] -> SimplM SimplEnv
--- Recursive let binders for join points; context being pushed inward may
--- change types
+-- Recursive let binders for join points;
+-- context being pushed inward may change types
+-- See Note [Return type for join points]
simplRecJoinBndrs env@(SimplEnv {}) res_ty ids
= ASSERT(all isJoinId ids)
do { let (env1, ids1) = mapAccumL (substIdBndr (Just res_ty)) env ids
@@ -755,6 +785,7 @@ substIdBndr new_res_ty env bndr
---------------
substNonCoVarIdBndr
:: Maybe OutType -- New result type, if a join binder
+ -- See Note [Return type for join points]
-> SimplEnv
-> InBndr -- Env and binder to transform
-> (SimplEnv, OutBndr)
@@ -785,10 +816,13 @@ substNonCoVarIdBndr new_res_ty
where
id1 = uniqAway in_scope old_id
id2 = substIdType env id1
+
id3 | Just res_ty <- new_res_ty
= id2 `setIdType` setJoinResTy (idJoinArity id2) res_ty (idType id2)
+ -- See Note [Return type for join points]
| otherwise
= id2
+
new_id = zapFragileIdInfo id3 -- Zaps rules, worker-info, unfolding
-- and fragile OccInfo
More information about the ghc-commits
mailing list