X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FcoreSyn%2FCoreFVs.lhs;h=90d76196495b8122587ea16a8390d28d3b67cd4a;hp=a15362a5853b0e7cb587a90545efc47721475b09;hb=a51fe79ebcdcb8285573a18f12cade2101533419;hpb=d95ce839533391e7118257537044f01cbb1d6694 diff --git a/compiler/coreSyn/CoreFVs.lhs b/compiler/coreSyn/CoreFVs.lhs index a15362a..90d7619 100644 --- a/compiler/coreSyn/CoreFVs.lhs +++ b/compiler/coreSyn/CoreFVs.lhs @@ -26,8 +26,9 @@ module CoreFVs ( exprFreeNames, exprsFreeNames, -- * Free variables of Rules, Vars and Ids - idRuleVars, idRuleRhsVars, idFreeVars, idInlineFreeVars, - varTypeTyVars, + varTypeTyVars, varTypeTcTyVars, + idUnfoldingVars, idFreeVars, idRuleAndUnfoldingVars, + idRuleVars, idRuleRhsVars, ruleRhsFreeVars, rulesFreeVars, ruleLhsFreeNames, ruleLhsFreeIds, @@ -200,7 +201,8 @@ expr_fvs (Let (Rec pairs) body) --------- rhs_fvs :: (Id,CoreExpr) -> FV -rhs_fvs (bndr, rhs) = expr_fvs rhs `union` someVars (bndrRuleVars bndr) +rhs_fvs (bndr, rhs) = expr_fvs rhs `union` + someVars (bndrRuleAndUnfoldingVars bndr) -- Treat any RULES as extra RHSs of the binding --------- @@ -277,6 +279,7 @@ ruleRhsFreeVars (Rule { ru_fn = fn, ru_bndrs = bndrs, ru_rhs = rhs }) -- | Those variables free in the both the left right hand sides of a rule ruleFreeVars :: CoreRule -> VarSet +ruleFreeVars (BuiltinRule {}) = noFVs ruleFreeVars (Rule { ru_fn = fn, ru_bndrs = bndrs, ru_rhs = rhs, ru_args = args }) = delFromUFM fvs fn -- Note [Rule free var hack] where @@ -340,8 +343,8 @@ delBinderFV :: Var -> VarSet -> VarSet -- (b `delBinderFV` s) removes the binder b from the free variable set s, -- but *adds* to s --- (a) the free variables of b's type --- (b) the idSpecVars of b +-- +-- the free variables of b's type -- -- This is really important for some lambdas: -- In (\x::a -> x) the only mention of "a" is in the binder. @@ -376,32 +379,53 @@ varTypeTyVars var | isLocalId var || isCoVar var = tyVarsOfType (idType var) | otherwise = emptyVarSet -- Global Ids and non-coercion TyVars -idFreeVars :: Id -> VarSet -idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` varTypeTyVars id - -bndrRuleVars ::Var -> VarSet -bndrRuleVars v | isTyVar v = emptyVarSet - | otherwise = idRuleVars v - -idRuleVars ::Id -> VarSet -idRuleVars id = ASSERT( isId id) - specInfoFreeVars (idSpecialisation id) `unionVarSet` - idInlineFreeVars id -- And the variables in an INLINE rule +varTypeTcTyVars :: Var -> TyVarSet +-- Find the type variables free in the type of the variable +-- Remember, coercion variables can mention type variables... +varTypeTcTyVars var + | isLocalId var || isCoVar var = tcTyVarsOfType (idType var) + | otherwise = emptyVarSet -- Global Ids and non-coercion TyVars -idRuleRhsVars :: Id -> VarSet +idFreeVars :: Id -> VarSet +-- Type variables, rule variables, and inline variables +idFreeVars id = ASSERT( isId id) + varTypeTyVars id `unionVarSet` + idRuleAndUnfoldingVars id + +bndrRuleAndUnfoldingVars ::Var -> VarSet +-- A 'let' can bind a type variable, and idRuleVars assumes +-- it's seeing an Id. This function tests first. +bndrRuleAndUnfoldingVars v | isTyCoVar v = emptyVarSet + | otherwise = idRuleAndUnfoldingVars v + +idRuleAndUnfoldingVars :: Id -> VarSet +idRuleAndUnfoldingVars id = ASSERT( isId id) + idRuleVars id `unionVarSet` + idUnfoldingVars id + +idRuleVars ::Id -> VarSet -- Does *not* include CoreUnfolding vars +idRuleVars id = ASSERT( isId id) specInfoFreeVars (idSpecialisation id) + +idRuleRhsVars :: Id -> VarSet -- Does *not* include the CoreUnfolding vars -- Just the variables free on the *rhs* of a rule -- See Note [Choosing loop breakers] in Simplify.lhs idRuleRhsVars id = foldr (unionVarSet . ruleRhsFreeVars) - (idInlineFreeVars id) + emptyVarSet (idCoreRules id) -idInlineFreeVars :: Id -> VarSet --- Produce free vars for an InlineRule, BUT NOT for an ordinary unfolding --- An InlineRule behaves *very like* a RULE, and that is what we are after here -idInlineFreeVars id - = case idUnfolding id of - InlineRule { uf_tmpl = tmpl } -> exprFreeVars tmpl - _ -> emptyVarSet +idUnfoldingVars :: Id -> VarSet +-- Produce free vars for an unfolding, but NOT for an ordinary +-- (non-inline) unfolding, since it is a dup of the rhs +-- and we'll get exponential behaviour if we look at both unf and rhs! +-- But do look at the *real* unfolding, even for loop breakers, else +-- we might get out-of-scope variables +idUnfoldingVars id + = case realIdUnfolding id of + CoreUnfolding { uf_tmpl = rhs, uf_src = src } + | isStableSource src + -> exprFreeVars rhs + DFunUnfolding _ _ args -> exprsFreeVars args + _ -> emptyVarSet \end{code} @@ -452,7 +476,9 @@ freeVars (Case scrut bndr ty alts) rhs2 = freeVars rhs freeVars (Let (NonRec binder rhs) body) - = (freeVarsOf rhs2 `unionFVs` body_fvs `unionFVs` bndrRuleVars binder, + = (freeVarsOf rhs2 + `unionFVs` body_fvs + `unionFVs` bndrRuleAndUnfoldingVars binder, -- Remember any rules; cf rhs_fvs above AnnLet (AnnNonRec binder rhs2) body2) where @@ -468,7 +494,7 @@ freeVars (Let (Rec binds) body) rhss2 = map freeVars rhss rhs_body_fvs = foldr (unionFVs . freeVarsOf) body_fvs rhss2 - all_fvs = foldr (unionFVs . idRuleVars) rhs_body_fvs binders + all_fvs = foldr (unionFVs . idRuleAndUnfoldingVars) rhs_body_fvs binders -- The "delBinderFV" happens after adding the idSpecVars, -- since the latter may add some of the binders as fvs