X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FcoreSyn%2FCoreSubst.lhs;h=9cedf2dc031602f436150292353f400f619c6bc2;hb=aafdba3bce91afb003f5f50e001e141744837bae;hp=321ea8fc3603a37936a9a8ea9db6983815cc956a;hpb=94b170a053c161d1e0cc4418b37a6a4807872a5f;p=ghc-hetmet.git diff --git a/compiler/coreSyn/CoreSubst.lhs b/compiler/coreSyn/CoreSubst.lhs index 321ea8f..9cedf2d 100644 --- a/compiler/coreSyn/CoreSubst.lhs +++ b/compiler/coreSyn/CoreSubst.lhs @@ -6,6 +6,13 @@ Utility functions on @Core@ syntax \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module CoreSubst ( -- Substitution stuff Subst, TvSubstEnv, IdSubstEnv, InScopeSet, @@ -16,7 +23,8 @@ module CoreSubst ( emptySubst, mkEmptySubst, mkSubst, substInScope, isEmptySubst, extendIdSubst, extendIdSubstList, extendTvSubst, extendTvSubstList, - extendInScope, extendInScopeIds, + extendSubstList, zapSubstEnv, + extendInScope, extendInScopeList, extendInScopeIds, isInScope, -- Binders @@ -44,6 +52,8 @@ import Outputable import PprCore () -- Instances import Util import FastTypes + +import Data.List \end{code} @@ -56,6 +66,7 @@ import FastTypes \begin{code} data Subst = Subst InScopeSet -- Variables in in scope (both Ids and TyVars) + -- *after* applying the substitution IdSubstEnv -- Substitution for Ids TvSubstEnv -- Substitution for TyVars @@ -144,8 +155,8 @@ mkSubst in_scope tvs ids = Subst in_scope ids tvs substInScope :: Subst -> InScopeSet substInScope (Subst in_scope _ _) = in_scope --- zapSubstEnv :: Subst -> Subst --- zapSubstEnv (Subst in_scope _ _) = Subst in_scope emptyVarEnv emptyVarEnv +zapSubstEnv :: Subst -> Subst +zapSubstEnv (Subst in_scope _ _) = Subst in_scope emptyVarEnv emptyVarEnv -- ToDo: add an ASSERT that fvs(subst-result) is already in the in-scope set extendIdSubst :: Subst -> Id -> CoreExpr -> Subst @@ -160,6 +171,14 @@ extendTvSubst (Subst in_scope ids tvs) v r = Subst in_scope ids (extendVarEnv tv extendTvSubstList :: Subst -> [(TyVar,Type)] -> Subst extendTvSubstList (Subst in_scope ids tvs) prs = Subst in_scope ids (extendVarEnvList tvs prs) +extendSubstList :: Subst -> [(Var,CoreArg)] -> Subst +extendSubstList subst [] + = subst +extendSubstList (Subst in_scope ids tvs) ((tv,Type ty):prs) + = ASSERT( isTyVar tv ) extendSubstList (Subst in_scope ids (extendVarEnv tvs tv ty)) prs +extendSubstList (Subst in_scope ids tvs) ((id,expr):prs) + = ASSERT( isId id ) extendSubstList (Subst in_scope (extendVarEnv ids id expr) tvs) prs + lookupIdSubst :: Subst -> Id -> CoreExpr lookupIdSubst (Subst in_scope ids tvs) v | not (isLocalId v) = Var v @@ -181,6 +200,11 @@ extendInScope (Subst in_scope ids tvs) v = Subst (in_scope `extendInScopeSet` v) (ids `delVarEnv` v) (tvs `delVarEnv` v) +extendInScopeList :: Subst -> [Var] -> Subst +extendInScopeList (Subst in_scope ids tvs) vs + = Subst (in_scope `extendInScopeSetList` vs) + (ids `delVarEnvList` vs) (tvs `delVarEnvList` vs) + extendInScopeIds :: Subst -> [Id] -> Subst extendInScopeIds (Subst in_scope ids tvs) vs = Subst (in_scope `extendInScopeSetList` vs) @@ -292,6 +316,7 @@ substRecBndrs subst bndrs substIdBndr :: Subst -- Substitution to use for the IdInfo -> Subst -> Id -- Substitition and Id to transform -> (Subst, Id) -- Transformed pair + -- NB: unfolding may be zapped substIdBndr rec_subst subst@(Subst in_scope env tvs) old_id = (Subst (in_scope `extendInScopeSet` new_id) new_env tvs, new_id) @@ -308,7 +333,8 @@ substIdBndr rec_subst subst@(Subst in_scope env tvs) old_id -- The lazy-set is because we're in a loop here, with -- rec_subst, when dealing with a mutually-recursive group new_id = maybeModifyIdInfo mb_new_info id2 - mb_new_info = substIdInfo rec_subst (idInfo id2) + mb_new_info = substIdInfo rec_subst id2 (idInfo id2) + -- NB: unfolding info may be zapped -- Extend the substitution if the unique has changed -- See the notes with substTyVarBndr for the delVarEnv @@ -350,7 +376,7 @@ clone_id rec_subst subst@(Subst in_scope env tvs) (old_id, uniq) where id1 = setVarUnique old_id uniq id2 = substIdType subst id1 - new_id = maybeModifyIdInfo (substIdInfo rec_subst (idInfo old_id)) id2 + new_id = maybeModifyIdInfo (substIdInfo rec_subst id2 (idInfo old_id)) id2 new_env = extendVarEnv env old_id (Var new_id) \end{code} @@ -395,11 +421,11 @@ substIdType subst@(Subst in_scope id_env tv_env) id old_ty = idType id ------------------ -substIdInfo :: Subst -> IdInfo -> Maybe IdInfo +substIdInfo :: Subst -> Id -> IdInfo -> Maybe IdInfo -- Always zaps the unfolding, to save substitution work -substIdInfo subst info +substIdInfo subst new_id info | nothing_to_do = Nothing - | otherwise = Just (info `setSpecInfo` substSpec subst old_rules + | otherwise = Just (info `setSpecInfo` substSpec subst new_id old_rules `setWorkerInfo` substWorker subst old_wrkr `setUnfoldingInfo` noUnfolding) where @@ -426,19 +452,21 @@ substWorker subst (HasWorker w a) -- via postInlineUnconditionally, hence warning) ------------------ -substSpec :: Subst -> SpecInfo -> SpecInfo +substSpec :: Subst -> Id -> SpecInfo -> SpecInfo -substSpec subst spec@(SpecInfo rules rhs_fvs) +substSpec subst new_fn spec@(SpecInfo rules rhs_fvs) | isEmptySubst subst = spec | otherwise = seqSpecInfo new_rules `seq` new_rules where + new_name = idName new_fn new_rules = SpecInfo (map do_subst rules) (substVarSet subst rhs_fvs) do_subst rule@(BuiltinRule {}) = rule do_subst rule@(Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs }) - = rule { ru_bndrs = bndrs', + = rule { ru_bndrs = bndrs', + ru_fn = new_name, -- Important: the function may have changed its name! ru_args = map (substExpr subst') args, ru_rhs = substExpr subst' rhs } where