[commit: ghc] wip/T14152: Exitify: Keep track of an InScopeSet (103e621)
git at git.haskell.org
git at git.haskell.org
Thu Aug 31 21:27:38 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/T14152
Link : http://ghc.haskell.org/trac/ghc/changeset/103e6217d58eae1922171ad606fa13b1777bd6a1/ghc
>---------------------------------------------------------------
commit 103e6217d58eae1922171ad606fa13b1777bd6a1
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Thu Aug 31 22:26:51 2017 +0100
Exitify: Keep track of an InScopeSet
more reliable than avoiding freeVars
>---------------------------------------------------------------
103e6217d58eae1922171ad606fa13b1777bd6a1
compiler/simplCore/Exitify.hs | 69 ++++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 31 deletions(-)
diff --git a/compiler/simplCore/Exitify.hs b/compiler/simplCore/Exitify.hs
index d86b02d..cc4172d 100644
--- a/compiler/simplCore/Exitify.hs
+++ b/compiler/simplCore/Exitify.hs
@@ -25,36 +25,45 @@ import Control.Monad
exitifyProgram :: CoreProgram -> CoreProgram
exitifyProgram binds = map goTopLvl binds
where
- goTopLvl (NonRec v e) = NonRec v (go e)
- goTopLvl (Rec pairs) = Rec (map (second go) pairs)
-
- go e@(Var{}) = e
- go e@(Lit {}) = e
- go e@(Type {}) = e
- go e@(Coercion {}) = e
-
- go (Lam v e') = Lam v (go e')
- go (App e1 e2) = App (go e1) (go e2)
- go (Case scrut bndr ty alts) = Case (go scrut) bndr ty (map goAlt alts)
- go (Cast e' c) = Cast (go e') c
- go (Tick t e') = Tick t (go e')
- go (Let bind body) = goBind bind (go body)
-
- goAlt :: CoreAlt -> CoreAlt
- goAlt (dc, pats, rhs) = (dc, pats, go rhs)
-
- goBind :: CoreBind -> (CoreExpr -> CoreExpr)
- goBind (NonRec v rhs) = Let (NonRec v (go rhs))
- goBind (Rec pairs)
- | is_join_rec = exitify pairs'
+ goTopLvl (NonRec v e) = NonRec v (go in_scope_toplvl e)
+ goTopLvl (Rec pairs) = Rec (map (second (go in_scope_toplvl)) pairs)
+
+ in_scope_toplvl = emptyInScopeSet `extendInScopeSetList` bindersOfBinds binds
+
+ go :: InScopeSet -> CoreExpr -> CoreExpr
+ go _ e@(Var{}) = e
+ go _ e@(Lit {}) = e
+ go _ e@(Type {}) = e
+ go _ e@(Coercion {}) = e
+
+ go in_scope (Lam v e') = Lam v (go in_scope' e')
+ where in_scope' = in_scope `extendInScopeSet` v
+ go in_scope (App e1 e2) = App (go in_scope e1) (go in_scope e2)
+ go in_scope (Case scrut bndr ty alts)
+ = Case (go in_scope scrut) bndr ty (map (goAlt in_scope') alts)
+ where in_scope' = in_scope `extendInScopeSet` bndr
+ go in_scope (Cast e' c) = Cast (go in_scope e') c
+ go in_scope (Tick t e') = Tick t (go in_scope e')
+ go in_scope (Let bind body) = goBind in_scope bind (go in_scope' body)
+ where in_scope' = in_scope `extendInScopeSetList` bindersOf bind
+
+ goAlt :: InScopeSet -> CoreAlt -> CoreAlt
+ goAlt in_scope (dc, pats, rhs) = (dc, pats, go in_scope' rhs)
+ where in_scope' = in_scope `extendInScopeSetList` pats
+
+ goBind :: InScopeSet -> CoreBind -> (CoreExpr -> CoreExpr)
+ goBind in_scope (NonRec v rhs) = Let (NonRec v (go in_scope rhs))
+ goBind in_scope (Rec pairs)
+ | is_join_rec = exitify in_scope' pairs'
| otherwise = Let (Rec pairs')
- where pairs' = map (second go) pairs
+ where pairs' = map (second (go in_scope')) pairs
is_join_rec = any (isJoinId . fst) pairs
+ in_scope' = in_scope `extendInScopeSetList` bindersOf (Rec pairs)
-- | Given a recursive group of a joinrec, identifies “exit paths” and binds them as
-- join-points outside the joinrec.
-exitify :: [(Var,CoreExpr)] -> (CoreExpr -> CoreExpr)
-exitify pairs =
+exitify :: InScopeSet -> [(Var,CoreExpr)] -> (CoreExpr -> CoreExpr)
+exitify in_scope pairs =
ASSERT (all (isJoinId . fst) pairs)
\body ->mkExitLets exits (mkLetRec pairs' body)
where
@@ -65,8 +74,6 @@ exitify pairs =
-- annotate the AST with them
ann_pairs = map (second freeVars) pairs
- -- What is in scope on the top level?
- joinrec_fv = unionVarSets $ map (dVarSetToVarSet . freeVarsOf . snd) ann_pairs
-- Which are the recursive calls?
recursive_calls = mkVarSet $ map fst pairs
@@ -137,10 +144,10 @@ exitify pairs =
-- * any exit join points created so far.
mkExitJoinId ty join_arity captured = do
fs <- get
- let avoid = joinrec_fv `unionVarSet` mkVarSet captured
- `unionVarSet` mkVarSet (map fst fs)
- `extendVarSet` exit_id_tmpl -- just cosmetics
- return (uniqAway (mkInScopeSet avoid) exit_id_tmpl)
+ let avoid = in_scope `extendInScopeSetList` captured
+ `extendInScopeSetList` (map fst fs)
+ `extendInScopeSet` exit_id_tmpl -- just cosmetics
+ return (uniqAway avoid exit_id_tmpl)
where
exit_id_tmpl = mkSysLocal (fsLit "exit") initExitJoinUnique ty
`asJoinId` join_arity
More information about the ghc-commits
mailing list