[commit: ghc] wip/T14152: Implement exitify (unused for now) #14152 (fc56305)
git at git.haskell.org
git at git.haskell.org
Sun Aug 27 18:31:49 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/T14152
Link : http://ghc.haskell.org/trac/ghc/changeset/fc563059b338d18059db4b4b28bf2d12b44a39a0/ghc
>---------------------------------------------------------------
commit fc563059b338d18059db4b4b28bf2d12b44a39a0
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Sat Aug 26 14:35:50 2017 +0200
Implement exitify (unused for now) #14152
>---------------------------------------------------------------
fc563059b338d18059db4b4b28bf2d12b44a39a0
compiler/simplCore/Simplify.hs | 89 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/compiler/simplCore/Simplify.hs b/compiler/simplCore/Simplify.hs
index 6ccd1f2..ce25b58 100644
--- a/compiler/simplCore/Simplify.hs
+++ b/compiler/simplCore/Simplify.hs
@@ -53,6 +53,10 @@ import Pair
import Util
import ErrUtils
import Module ( moduleName, pprModuleName )
+import State
+import Unique
+import VarSet
+import CoreFVs
{-
The guts of the simplifier is in this module, but the driver loop for
@@ -1682,6 +1686,91 @@ maybeLoopify (Rec [(bndr, rhs)])
}
maybeLoopify _ = Nothing
+-- TODO: Move to a more appropriate module
+--
+-- | Given a recursive group of a joinrec), identifies “exit paths” and binds them as
+-- join-points outside the joinrec.
+exitify :: [Unique] -> [(InId,InExpr)] -> (InExpr -> InExpr)
+exitify exitUniques pairs =
+ ASSERT (all (isJoinId . fst) pairs)
+ \body -> mkExitLets exits (mkLetRec pairs' body)
+ where
+ mkExitLets ((exitId, exitRhs):exits') = mkLetNonRec exitId exitRhs . mkExitLets exits'
+ mkExitLets [] = id
+
+ (exits,pairs') = (`evalState` (exitUniques, [])) $ do
+ pairs' <- forM pairs $ \(x,rhs) -> do
+ -- go past the lambdas
+ let (args, body) = collectNBinders (idJoinArity x) rhs
+ body' <- go args body
+ let rhs' = mkLams args body'
+ return (x, rhs')
+ exits <- gets snd
+ return (exits, pairs')
+
+ recursive_calls = mkVarSet $ map fst pairs
+
+ -- main working function. Goes through the RHS (tail-call positions only),
+ -- checks if there are no more recursive calls, if so, abstracts over
+ -- variables bound on the way and lifts it out as a join point.
+ --
+ -- Uses a state monad to track of the fresh uniques for the new join points,
+ -- and the floated binds
+ go :: [Var] -- ^ variables to abstract over
+ -> InExpr -- ^ current expression in tail position
+ -> State ([Unique], [(InId, InExpr)]) InExpr
+
+ go captured e
+ -- Do not touch an expression that is already a join call with no free variables
+ -- in the arguments
+ | (Var f, args) <- collectArgs e
+ , isJoinId f
+ , isEmptyVarSet (exprsFreeVars args `minusVarSet` mkVarSet captured)
+ = return e
+
+ -- Do not touch a boring expression
+ | is_exit, not is_interesting = return e
+
+ -- We have something to float out!
+ | is_exit = do
+ -- create an id for the exit path
+ u <- getUnique
+ let res_ty = exprType e
+ args = filter (`elemVarSet` fvs) captured
+ args_tys = map idType args
+ ty = mkFunTys args_tys res_ty
+ v = mkSysLocal (fsLit "exit") u ty `asJoinId` length args
+ rhs = mkLams args e
+ e' = mkVarApps (Var v) args
+ addExit v rhs
+ return e'
+ where
+ -- An exit expression has no recursive calls
+ is_exit = disjointVarSet fvs recursive_calls
+ -- An interesting exit expression has free variables from
+ -- outside the recursive group
+ is_interesting = not (isEmptyVarSet (fvs `minusVarSet` mkVarSet captured))
+ fvs = exprFreeVars e
+
+
+ go captured (Case scrut bndr ty alts) = do
+ alts' <- mapM (goAlt (bndr:captured)) alts
+ return $ Case scrut bndr ty alts'
+ go _ e = return e
+
+ goAlt captured (dc, pats, rhs) = do
+ rhs' <- go (pats ++ captured) rhs
+ return (dc, pats, rhs')
+
+ getUnique = do
+ (u:us, fs) <- get
+ put (us, fs)
+ return u
+
+ addExit v rhs = do
+ (us, fs) <- get
+ put (us, (v,rhs):fs)
+
{-
************************************************************************
* *
More information about the ghc-commits
mailing list