Monadify specialise/Specialise: use do, return, standard monad functions and MonadUnique
[ghc-hetmet.git] / compiler / coreSyn / CoreSubst.lhs
index 8306c04..00eaadd 100644 (file)
@@ -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,7 @@ module CoreSubst (
 
        emptySubst, mkEmptySubst, mkSubst, substInScope, isEmptySubst, 
        extendIdSubst, extendIdSubstList, extendTvSubst, extendTvSubstList,
-       extendSubstList, zapSubstEnv,
+       extendSubst, extendSubstList, zapSubstEnv,
        extendInScope, extendInScopeList, extendInScopeIds, 
        isInScope,
 
@@ -45,6 +52,8 @@ import Outputable
 import PprCore         ()              -- Instances
 import Util
 import FastTypes
+
+import Data.List
 \end{code}
 
 
@@ -163,12 +172,13 @@ 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
+extendSubstList subst []             = subst
+extendSubstList subst ((var,rhs):prs) = extendSubstList (extendSubst subst var rhs) prs
+
+extendSubst (Subst in_scope ids tvs) tv (Type ty)
+  = ASSERT( isTyVar tv ) Subst in_scope ids (extendVarEnv tvs tv ty)
+extendSubst (Subst in_scope ids tvs) id expr
+  = ASSERT( isId id ) Subst in_scope (extendVarEnv ids id expr) tvs
 
 lookupIdSubst :: Subst -> Id -> CoreExpr
 lookupIdSubst (Subst in_scope ids tvs) v 
@@ -324,7 +334,7 @@ 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
@@ -367,7 +377,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}
 
@@ -412,11 +422,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
@@ -443,19 +453,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