[commit: ghc] wip/T14152: Get in_scope_set right for CSE’ed exitification (bfa9c26)

git at git.haskell.org git at git.haskell.org
Wed Sep 6 23:30:59 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/T14152
Link       : http://ghc.haskell.org/trac/ghc/changeset/bfa9c262a87480e1852a16422d0b9f5a2601db5b/ghc

>---------------------------------------------------------------

commit bfa9c262a87480e1852a16422d0b9f5a2601db5b
Author: Joachim Breitner <mail at joachim-breitner.de>
Date:   Thu Sep 7 00:23:13 2017 +0100

    Get in_scope_set right for CSE’ed exitification
    
    (this patch will be squashed with the CSE patch)


>---------------------------------------------------------------

bfa9c262a87480e1852a16422d0b9f5a2601db5b
 compiler/simplCore/Exitify.hs | 58 ++++++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 20 deletions(-)

diff --git a/compiler/simplCore/Exitify.hs b/compiler/simplCore/Exitify.hs
index c1b64b1..b9973e2 100644
--- a/compiler/simplCore/Exitify.hs
+++ b/compiler/simplCore/Exitify.hs
@@ -60,7 +60,7 @@ exitifyProgram binds = map goTopLvl binds
 -- join-points outside the joinrec.
 exitify :: InScopeSet -> [(Var,CoreExpr)] -> (CoreExpr -> CoreExpr)
 exitify in_scope pairs =
-    \body ->mkExitLets exits (mkLetRec pairs' body)
+    \body -> mkExitLets exits (mkLetRec pairs' body)
   where
     mkExitLets ((exitId, exitRhs):exits') = mkLetNonRec exitId exitRhs . mkExitLets exits'
     mkExitLets [] = id
@@ -72,14 +72,13 @@ exitify in_scope pairs =
     -- Which are the recursive calls?
     recursive_calls = mkVarSet $ map fst pairs
 
-    (pairs',st) = (`runState` ExitifyState [] emptyTM) $ do
+    (pairs',exits) = runExitifyState in_scope $
         forM ann_pairs $ \(x,rhs) -> do
             -- go past the lambdas of the join point
             let (args, body) = collectNAnnBndrs (idJoinArity x) rhs
             body' <- go args body
             let rhs' = mkLams args body'
             return (x, rhs')
-    exits = es_joins st
 
     -- main working function. Goes through the RHS (tail-call positions only),
     -- checks if there are no more recursive calls, if so, abstracts over
@@ -109,10 +108,10 @@ exitify in_scope pairs =
         | is_exit = do
             -- Assemble the RHS of the exit join point
             let rhs = mkLams args e
-                ty = exprType rhs
-            let avoid = in_scope `extendInScopeSetList` captured
+            -- Remember what is in scope here
+            nowInScope captured
             -- Remember this binding under a suitable name
-            v <- addExit avoid ty (length args) rhs
+            v <- addExit (length args) rhs
             -- And call it from here
             return $ mkVarApps (Var v) args
       where
@@ -171,16 +170,41 @@ exitify in_scope pairs =
     go _ ann_e = return (deAnnotate ann_e)
 
 
+type ExitifyM = State ExitifyState
+data ExitifyState = ExitifyState
+        { es_in_scope_acc :: InScopeSet -- ^ combined in_scope_set of all call sites
+        , es_in_scope     :: InScopeSet -- ^ final in_scope_set
+        , es_joins        :: [(JoinId, CoreExpr)] -- ^ exit join points
+        , es_map          :: CoreMap JoinId
+            -- ^ reverse lookup map, see Note [Avoid duplicate exit points]
+        }
+
+-- Runs the ExitifyM monad, and feeds in the final es_in_scope_acc as the
+-- es_in_scope to use
+runExitifyState :: InScopeSet -> ExitifyM a -> (a, [(JoinId, CoreExpr)])
+runExitifyState in_scope_init f = (res, es_joins state)
+  where
+    (res, state) = runState f (ExitifyState in_scope_init in_scope [] emptyTM)
+    in_scope = es_in_scope_acc state
+
+-- Keeps track of what is in scope at all the various positions where
+-- we want to call an exit join point
+nowInScope :: [Var] -> ExitifyM ()
+nowInScope captured = do
+    st <- get
+    put (st { es_in_scope_acc = es_in_scope_acc st `extendInScopeSetList` captured})
+
 -- Picks a new unique, which is disjoint from
 --  * the free variables of the whole joinrec
 --  * any bound variables (captured)
 --  * any exit join points created so far.
-mkExitJoinId :: InScopeSet -> Type -> JoinArity -> ExitifyM JoinId
-mkExitJoinId in_scope ty join_arity = do
+mkExitJoinId :: Type -> JoinArity -> ExitifyM JoinId
+mkExitJoinId ty join_arity = do
     st <- get
-    let avoid = in_scope `extendInScopeSetList` (map fst (es_joins st))
-                         `extendInScopeSet` exit_id_tmpl -- just cosmetics
-    return (uniqAway avoid exit_id_tmpl)
+    let in_scope = es_in_scope st `extendInScopeSet` exit_id_tmpl -- cosmetic only
+    let v = uniqAway in_scope exit_id_tmpl
+    put (st { es_in_scope = es_in_scope st `extendInScopeSet` v})
+    return v
   where
     exit_id_tmpl = mkSysLocal (fsLit "exit") initExitJoinUnique ty
                     `asJoinId` join_arity
@@ -194,22 +218,16 @@ mkExitJoinId in_scope ty join_arity = do
 
 -- Adds a new exit join point
 -- (or re-uses an existing one)
-addExit :: InScopeSet -> Type -> JoinArity -> CoreExpr -> ExitifyM JoinId
-addExit in_scope ty join_arity rhs = do
+addExit :: JoinArity -> CoreExpr -> ExitifyM JoinId
+addExit join_arity rhs = do
     st <- get
     case lookupTM rhs (es_map st) of
         Just v -> return v
         Nothing -> do
             -- Pick a suitable name
-            v <- mkExitJoinId in_scope ty join_arity
+            v <- mkExitJoinId (exprType rhs) join_arity
             st <- get
             put (st { es_joins = (v,rhs) : es_joins st
                     , es_map = insertTM rhs v (es_map st)
                     })
             return v
-
-data ExitifyState = ExitifyState { es_joins :: [(JoinId, CoreExpr)]
-                                 , es_map :: CoreMap JoinId
-                                 }
-
-type ExitifyM = State ExitifyState



More information about the ghc-commits mailing list