Reorganisation of the source tree
[ghc-hetmet.git] / ghc / compiler / coreSyn / CoreSubst.lhs
diff --git a/ghc/compiler/coreSyn/CoreSubst.lhs b/ghc/compiler/coreSyn/CoreSubst.lhs
deleted file mode 100644 (file)
index c432d55..0000000
+++ /dev/null
@@ -1,393 +0,0 @@
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-%
-\section[CoreUtils]{Utility functions on @Core@ syntax}
-
-\begin{code}
-module CoreSubst (
-       -- Substitution stuff
-       Subst, TvSubstEnv, IdSubstEnv, InScopeSet,
-
-       substTy, substExpr, substSpec, substWorker,
-       lookupIdSubst, lookupTvSubst, 
-
-       emptySubst, mkEmptySubst, mkSubst, substInScope, isEmptySubst, 
-       extendIdSubst, extendIdSubstList, extendTvSubst, extendTvSubstList,
-       extendInScope, extendInScopeIds,
-       isInScope,
-
-       -- Binders
-       substBndr, substBndrs, substRecBndrs,
-       cloneIdBndr, cloneIdBndrs, cloneRecIdBndrs
-    ) where
-
-#include "HsVersions.h"
-
-import CoreSyn         ( Expr(..), Bind(..), Note(..), CoreExpr,
-                         CoreRule(..), hasUnfolding, noUnfolding
-                       )
-import CoreFVs         ( exprFreeVars )
-import CoreUtils       ( exprIsTrivial )
-
-import qualified Type  ( substTy, substTyVarBndr )
-import Type            ( Type, tyVarsOfType, TvSubstEnv, TvSubst(..), mkTyVarTy )
-import VarSet
-import VarEnv
-import Var             ( setVarUnique, isId )
-import Id              ( idType, setIdType, maybeModifyIdInfo, isLocalId )
-import IdInfo          ( IdInfo, SpecInfo(..), specInfo, setSpecInfo, isEmptySpecInfo,
-                         unfoldingInfo, setUnfoldingInfo, seqSpecInfo,
-                         WorkerInfo(..), workerExists, workerInfo, setWorkerInfo
-                       )
-import Unique          ( Unique )
-import UniqSupply      ( UniqSupply, uniqFromSupply, uniqsFromSupply )
-import Var             ( Var, Id, TyVar, isTyVar )
-import Maybes          ( orElse )
-import Outputable
-import PprCore         ()              -- Instances
-import Util            ( mapAccumL )
-import FastTypes
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\subsection{Substitutions}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-data Subst 
-  = Subst InScopeSet   -- Variables in in scope (both Ids and TyVars)
-         IdSubstEnv    -- Substitution for Ids
-         TvSubstEnv    -- Substitution for TyVars
-
-       -- INVARIANT 1: The (domain of the) in-scope set is a superset
-       --              of the free vars of the range of the substitution
-       --              that might possibly clash with locally-bound variables
-       --              in the thing being substituted in.
-       -- This is what lets us deal with name capture properly
-       -- It's a hard invariant to check...
-       -- There are various ways of causing it to happen:
-       --      - arrange that the in-scope set really is all the things in scope
-       --      - arrange that it's the free vars of the range of the substitution
-       --      - make it empty because all the free vars of the subst are fresh,
-       --              and hence can't possibly clash.a
-       --
-       -- INVARIANT 2: The substitution is apply-once; see notes with
-       --              Types.TvSubstEnv
-
-type IdSubstEnv = IdEnv CoreExpr
-
-----------------------------
-isEmptySubst :: Subst -> Bool
-isEmptySubst (Subst _ id_env tv_env) = isEmptyVarEnv id_env && isEmptyVarEnv tv_env
-
-emptySubst :: Subst
-emptySubst = Subst emptyInScopeSet emptyVarEnv emptyVarEnv
-
-mkEmptySubst :: InScopeSet -> Subst
-mkEmptySubst in_scope = Subst in_scope emptyVarEnv emptyVarEnv
-
-mkSubst :: InScopeSet -> TvSubstEnv -> IdSubstEnv -> Subst
-mkSubst in_scope tvs ids = Subst in_scope ids tvs
-
--- getTvSubst :: Subst -> TvSubst
--- getTvSubst (Subst in_scope _ tv_env) = TvSubst in_scope tv_env
-
--- getTvSubstEnv :: Subst -> TvSubstEnv
--- getTvSubstEnv (Subst _ _ tv_env) = tv_env
--- 
--- setTvSubstEnv :: Subst -> TvSubstEnv -> Subst
--- setTvSubstEnv (Subst in_scope ids _) tvs = 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
-
--- ToDo: add an ASSERT that fvs(subst-result) is already in the in-scope set
-extendIdSubst :: Subst -> Id -> CoreExpr -> Subst
-extendIdSubst (Subst in_scope ids tvs) v r = Subst in_scope (extendVarEnv ids v r) tvs
-
-extendIdSubstList :: Subst -> [(Id, CoreExpr)] -> Subst
-extendIdSubstList (Subst in_scope ids tvs) prs = Subst in_scope (extendVarEnvList ids prs) tvs
-
-extendTvSubst :: Subst -> TyVar -> Type -> Subst
-extendTvSubst (Subst in_scope ids tvs) v r = Subst in_scope ids (extendVarEnv tvs v r) 
-
-extendTvSubstList :: Subst -> [(TyVar,Type)] -> Subst
-extendTvSubstList (Subst in_scope ids tvs) prs = Subst in_scope ids (extendVarEnvList tvs prs)
-
-lookupIdSubst :: Subst -> Id -> CoreExpr
-lookupIdSubst (Subst in_scope ids tvs) v 
-  | not (isLocalId v) = Var v
-  | otherwise
-  = case lookupVarEnv ids v of {
-       Just e  -> e ;
-       Nothing ->      
-    case lookupInScope in_scope v of {
-       -- Watch out!  Must get the Id from the in-scope set,
-       -- because its type there may differ
-       Just v  -> Var v ;
-       Nothing -> WARN( True, ptext SLIT("CoreSubst.lookupIdSubst") <+> ppr v ) 
-                  Var v
-    }}
-
-lookupTvSubst :: Subst -> TyVar -> Type
-lookupTvSubst (Subst _ ids tvs) v = lookupVarEnv tvs v `orElse` mkTyVarTy v
-
-------------------------------
-isInScope :: Var -> Subst -> Bool
-isInScope v (Subst in_scope _ _) = v `elemInScopeSet` in_scope
-
-extendInScope :: Subst -> Var -> Subst
-extendInScope (Subst in_scope ids tvs) v
-  = Subst (in_scope `extendInScopeSet` v) 
-         (ids `delVarEnv` v) (tvs `delVarEnv` v)
-
-extendInScopeIds :: Subst -> [Id] -> Subst
-extendInScopeIds (Subst in_scope ids tvs) vs 
-  = Subst (in_scope `extendInScopeSetList` vs) 
-         (ids `delVarEnvList` vs) tvs
-\end{code}
-
-Pretty printing, for debugging only
-
-\begin{code}
-instance Outputable Subst where
-  ppr (Subst in_scope ids tvs) 
-       =  ptext SLIT("<InScope =") <+> braces (fsep (map ppr (varEnvElts (getInScopeVars in_scope))))
-       $$ ptext SLIT(" IdSubst   =") <+> ppr ids
-       $$ ptext SLIT(" TvSubst   =") <+> ppr tvs
-        <> char '>'
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-       Substituting expressions
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-substExpr :: Subst -> CoreExpr -> CoreExpr
-substExpr subst expr
-  = go expr
-  where
-    go (Var v)        = lookupIdSubst subst v 
-    go (Type ty)       = Type (substTy subst ty)
-    go (Lit lit)       = Lit lit
-    go (App fun arg)   = App (go fun) (go arg)
-    go (Note note e)   = Note (go_note note) (go e)
-    go (Lam bndr body) = Lam bndr' (substExpr subst' body)
-                      where
-                        (subst', bndr') = substBndr subst bndr
-
-    go (Let (NonRec bndr rhs) body) = Let (NonRec bndr' (go rhs)) (substExpr subst' body)
-                                   where
-                                     (subst', bndr') = substBndr subst bndr
-
-    go (Let (Rec pairs) body) = Let (Rec pairs') (substExpr subst' body)
-                             where
-                               (subst', bndrs') = substRecBndrs subst (map fst pairs)
-                               pairs'  = bndrs' `zip` rhss'
-                               rhss'   = map (substExpr subst' . snd) pairs
-
-    go (Case scrut bndr ty alts) = Case (go scrut) bndr' (substTy subst ty) (map (go_alt subst') alts)
-                                where
-                                (subst', bndr') = substBndr subst bndr
-
-    go_alt subst (con, bndrs, rhs) = (con, bndrs', substExpr subst' rhs)
-                                where
-                                  (subst', bndrs') = substBndrs subst bndrs
-
-    go_note (Coerce ty1 ty2) = Coerce (substTy subst ty1) (substTy subst ty2)
-    go_note note            = note
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-       Substituting binders
-%*                                                                     *
-%************************************************************************
-
-Remember that substBndr and friends are used when doing expression
-substitution only.  Their only business is substitution, so they
-preserve all IdInfo (suitably substituted).  For example, we *want* to
-preserve occ info in rules.
-
-\begin{code}
-substBndr :: Subst -> Var -> (Subst, Var)
-substBndr subst bndr
-  | isTyVar bndr  = substTyVarBndr subst bndr
-  | otherwise     = substIdBndr subst subst bndr
-
-substBndrs :: Subst -> [Var] -> (Subst, [Var])
-substBndrs subst bndrs = mapAccumL substBndr subst bndrs
-
-substRecBndrs :: Subst -> [Id] -> (Subst, [Id])
--- Substitute a mutually recursive group
-substRecBndrs subst bndrs 
-  = (new_subst, new_bndrs)
-  where                -- Here's the reason we need to pass rec_subst to subst_id
-    (new_subst, new_bndrs) = mapAccumL (substIdBndr new_subst) subst bndrs
-\end{code}
-
-
-\begin{code}
-substIdBndr :: Subst           -- Substitution to use for the IdInfo
-           -> Subst -> Id      -- Substitition and Id to transform
-           -> (Subst, Id)      -- Transformed pair
-
-substIdBndr rec_subst subst@(Subst in_scope env tvs) old_id
-  = (Subst (in_scope `extendInScopeSet` new_id) new_env tvs, new_id)
-  where
-    id1 = uniqAway in_scope old_id     -- id1 is cloned if necessary
-    id2 = substIdType subst id1                -- id2 has its type zapped
-
-       -- new_id has the right IdInfo
-       -- The lazy-set is because we're in a loop here, with 
-       -- rec_subst, when dealing with a mutually-recursive group
-    new_id = maybeModifyIdInfo (substIdInfo rec_subst) id2
-
-       -- Extend the substitution if the unique has changed
-       -- See the notes with substTyVarBndr for the delVarEnv
-    new_env | new_id /= old_id  = extendVarEnv env old_id (Var new_id)
-           | otherwise         = delVarEnv env old_id
-\end{code}
-
-Now a variant that unconditionally allocates a new unique.
-It also unconditionally zaps the OccInfo.
-
-\begin{code}
-cloneIdBndr :: Subst -> UniqSupply -> Id -> (Subst, Id)
-cloneIdBndr subst us old_id
-  = clone_id subst subst (old_id, uniqFromSupply us)
-
-cloneIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
-cloneIdBndrs subst us ids
-  = mapAccumL (clone_id subst) subst (ids `zip` uniqsFromSupply us)
-
-cloneRecIdBndrs :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
-cloneRecIdBndrs subst us ids
-  = (subst', ids')
-  where
-    (subst', ids') = mapAccumL (clone_id subst') subst
-                              (ids `zip` uniqsFromSupply us)
-
--- Just like substIdBndr, except that it always makes a new unique
--- It is given the unique to use
-clone_id    :: Subst                   -- Substitution for the IdInfo
-           -> Subst -> (Id, Unique)    -- Substitition and Id to transform
-           -> (Subst, Id)              -- Transformed pair
-
-clone_id rec_subst subst@(Subst in_scope env tvs) (old_id, uniq)
-  = (Subst (in_scope `extendInScopeSet` new_id) new_env tvs, new_id)
-  where
-    id1            = setVarUnique old_id uniq
-    id2     = substIdType subst id1
-    new_id  = maybeModifyIdInfo (substIdInfo rec_subst) id2
-    new_env = extendVarEnv env old_id (Var new_id)
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-               Types
-%*                                                                     *
-%************************************************************************
-
-For types we just call the corresponding function in Type, but we have
-to repackage the substitution, from a Subst to a TvSubst
-
-\begin{code}
-substTyVarBndr :: Subst -> TyVar -> (Subst, TyVar)
-substTyVarBndr (Subst in_scope id_env tv_env) tv
-  = case Type.substTyVarBndr (TvSubst in_scope tv_env) tv of
-       (TvSubst in_scope' tv_env', tv') 
-          -> (Subst in_scope' id_env tv_env', tv')
-
-substTy :: Subst -> Type -> Type 
-substTy (Subst in_scope id_env tv_env) ty 
-  = Type.substTy (TvSubst in_scope tv_env) ty
-\end{code}
-
-
-%************************************************************************
-%*                                                                     *
-\section{IdInfo substitution}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-substIdType :: Subst -> Id -> Id
-substIdType subst@(Subst in_scope id_env tv_env) id
-  | isEmptyVarEnv tv_env || isEmptyVarSet (tyVarsOfType old_ty) = id
-  | otherwise  = setIdType id (substTy subst old_ty)
-               -- The tyVarsOfType is cheaper than it looks
-               -- because we cache the free tyvars of the type
-               -- in a Note in the id's type itself
-  where
-    old_ty = idType id
-
-------------------
-substIdInfo :: Subst -> IdInfo -> Maybe IdInfo
--- Always zaps the unfolding, to save substitution work
-substIdInfo  subst info
-  | nothing_to_do = Nothing
-  | otherwise     = Just (info `setSpecInfo`             substSpec  subst old_rules
-                              `setWorkerInfo`    substWorker subst old_wrkr
-                              `setUnfoldingInfo` noUnfolding)
-  where
-    old_rules    = specInfo info
-    old_wrkr     = workerInfo info
-    nothing_to_do = isEmptySpecInfo old_rules &&
-                   not (workerExists old_wrkr) &&
-                   not (hasUnfolding (unfoldingInfo info))
-    
-
-------------------
-substWorker :: Subst -> WorkerInfo -> WorkerInfo
-       -- Seq'ing on the returned WorkerInfo is enough to cause all the 
-       -- substitutions to happen completely
-
-substWorker subst NoWorker
-  = NoWorker
-substWorker subst (HasWorker w a)
-  = case lookupIdSubst subst w of
-       Var w1 -> HasWorker w1 a
-       other  -> WARN( not (exprIsTrivial other), text "CoreSubst.substWorker:" <+> ppr w )
-                 NoWorker      -- Worker has got substituted away altogether
-                               -- (This can happen if it's trivial, 
-                               --  via postInlineUnconditionally, hence warning)
-
-------------------
-substSpec :: Subst -> SpecInfo -> SpecInfo
-
-substSpec subst spec@(SpecInfo rules rhs_fvs)
-  | isEmptySubst subst
-  = spec
-  | otherwise
-  = seqSpecInfo new_rules `seq` new_rules
-  where
-    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',
-                ru_args  = map (substExpr subst') args,
-                ru_rhs   = substExpr subst' rhs }
-       where
-         (subst', bndrs') = substBndrs subst bndrs
-
-------------------
-substVarSet subst fvs 
-  = foldVarSet (unionVarSet . subst_fv subst) emptyVarSet fvs
-  where
-    subst_fv subst fv 
-       | isId fv   = exprFreeVars (lookupIdSubst subst fv)
-       | otherwise = tyVarsOfType (lookupTvSubst subst fv)
-\end{code}