[commit: ghc] master: Fix three problems with occurrence analysis on case alternatives. (5d5655e)
git at git.haskell.org
git at git.haskell.org
Tue Aug 19 04:34:12 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/5d5655e9911dba10088b66421e98165c6cb8176e/ghc
>---------------------------------------------------------------
commit 5d5655e9911dba10088b66421e98165c6cb8176e
Author: Andrew Farmer <afarmer at ittc.ku.edu>
Date: Mon Aug 18 21:40:12 2014 -0500
Fix three problems with occurrence analysis on case alternatives.
Summary:
1. Respect condition (a) in Note [Binder swap]
2. Respect condition (b) in Note [Binder swap]
3. Return usage of any coercion variables in binder swap
Fixes T9440
Test Plan: See #9440
Reviewers: simonpj, austin
Reviewed By: simonpj, austin
Subscribers: simonpj, simonmar, relrod, ezyang, carter
Differential Revision: https://phabricator.haskell.org/D156
GHC Trac Issues: #9440
>---------------------------------------------------------------
5d5655e9911dba10088b66421e98165c6cb8176e
compiler/simplCore/OccurAnal.lhs | 53 ++++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 21 deletions(-)
diff --git a/compiler/simplCore/OccurAnal.lhs b/compiler/simplCore/OccurAnal.lhs
index c932335..42a6167 100644
--- a/compiler/simplCore/OccurAnal.lhs
+++ b/compiler/simplCore/OccurAnal.lhs
@@ -1172,10 +1172,10 @@ occAnal env expr@(Var v) = (mkOneOcc env v False, expr)
occAnal _ (Coercion co)
= (addIdOccs emptyDetails (coVarsOfCo co), Coercion co)
- -- See Note [Gather occurrences of coercion veriables]
+ -- See Note [Gather occurrences of coercion variables]
\end{code}
-Note [Gather occurrences of coercion veriables]
+Note [Gather occurrences of coercion variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We need to gather info about what coercion variables appear, so that
we can sort them into the right place when doing dependency analysis.
@@ -1269,7 +1269,7 @@ occAnal env (Case scrut bndr ty alts)
Just _ -> (usage `delVarEnv` bndr, setIdOccInfo bndr NoOccInfo)
alt_env = mkAltEnv env scrut bndr
- occ_anal_alt = occAnalAlt alt_env bndr
+ occ_anal_alt = occAnalAlt alt_env
occ_anal_scrut (Var v) (alt1 : other_alts)
| not (null other_alts) || not (isDefaultAlt alt1)
@@ -1404,30 +1404,41 @@ scrutinised y).
\begin{code}
occAnalAlt :: (OccEnv, Maybe (Id, CoreExpr))
- -> CoreBndr
-> CoreAlt
-> (UsageDetails, Alt IdWithOccInfo)
-occAnalAlt (env, scrut_bind) case_bndr (con, bndrs, rhs)
+occAnalAlt (env, scrut_bind) (con, bndrs, rhs)
= case occAnal env rhs of { (rhs_usage1, rhs1) ->
let
- (rhs_usage2, rhs2) =
- wrapProxy (occ_binder_swap env) scrut_bind case_bndr rhs_usage1 rhs1
- (alt_usg, tagged_bndrs) = tagLamBinders rhs_usage2 bndrs
- bndrs' = tagged_bndrs -- See Note [Binders in case alternatives]
+ (alt_usg, tagged_bndrs) = tagLamBinders rhs_usage1 bndrs
+ -- See Note [Binders in case alternatives]
+ (alt_usg', rhs2) =
+ wrapAltRHS env scrut_bind alt_usg tagged_bndrs rhs1
in
- (alt_usg, (con, bndrs', rhs2)) }
-
-wrapProxy :: Bool -> Maybe (Id, CoreExpr) -> Id -> UsageDetails -> CoreExpr -> (UsageDetails, CoreExpr)
-wrapProxy enable_binder_swap (Just (scrut_var, rhs)) case_bndr body_usg body
- | enable_binder_swap,
- scrut_var `usedIn` body_usg
- = ( body_usg' +++ unitVarEnv case_bndr NoOccInfo
- , Let (NonRec tagged_scrut_var rhs) body )
- where
- (body_usg', tagged_scrut_var) = tagBinder body_usg scrut_var
+ (alt_usg', (con, tagged_bndrs, rhs2)) }
-wrapProxy _ _ _ body_usg body
- = (body_usg, body)
+wrapAltRHS :: OccEnv
+ -> Maybe (Id, CoreExpr) -- proxy mapping generated by mkAltEnv
+ -> UsageDetails -- usage for entire alt (p -> rhs)
+ -> [Var] -- alt binders
+ -> CoreExpr -- alt RHS
+ -> (UsageDetails, CoreExpr)
+wrapAltRHS env (Just (scrut_var, let_rhs)) alt_usg bndrs alt_rhs
+ | occ_binder_swap env
+ , scrut_var `usedIn` alt_usg -- bndrs are not be present in alt_usg so this
+ -- handles condition (a) in Note [Binder swap]
+ , not captured -- See condition (b) in Note [Binder swap]
+ = ( alt_usg' +++ let_rhs_usg
+ , Let (NonRec tagged_scrut_var let_rhs') alt_rhs )
+ where
+ captured = any (`usedIn` let_rhs_usg) bndrs
+ -- The rhs of the let may include coercion variables
+ -- if the scrutinee was a cast, so we must gather their
+ -- usage. See Note [Gather occurrences of coercion variables]
+ (let_rhs_usg, let_rhs') = occAnal env let_rhs
+ (alt_usg', tagged_scrut_var) = tagBinder alt_usg scrut_var
+
+wrapAltRHS _ _ alt_usg _ alt_rhs
+ = (alt_usg, alt_rhs)
\end{code}
More information about the ghc-commits
mailing list