Merge remote branch 'origin/master'
[ghc-hetmet.git] / compiler / coreSyn / CoreTidy.lhs
index c4e7ed9..377bfd8 100644 (file)
@@ -8,24 +8,24 @@ The code for *top-level* bindings is in TidyPgm.
 
 \begin{code}
 module CoreTidy (
-       tidyExpr, tidyVarOcc, tidyRule, tidyRules 
+       tidyExpr, tidyVarOcc, tidyRule, tidyRules, tidyUnfolding
     ) where
 
 #include "HsVersions.h"
 
 import CoreSyn
-import CoreUtils
+import CoreArity
 import Id
 import IdInfo
-import Type
+import TcType( tidyType, tidyCo, tidyTyVarBndr )
 import Var
 import VarEnv
 import UniqFM
 import Name hiding (tidyNameOcc)
-import OccName
 import SrcLoc
 import Maybes
-import Util
+import Data.List
+import Outputable
 \end{code}
 
 
@@ -41,11 +41,13 @@ tidyBind :: TidyEnv
         ->  (TidyEnv, CoreBind)
 
 tidyBind env (NonRec bndr rhs)
-  = tidyLetBndr env (bndr,rhs) =: \ (env', bndr') ->
+  = tidyLetBndr env env (bndr,rhs) =: \ (env', bndr') ->
     (env', NonRec bndr' (tidyExpr env' rhs))
 
 tidyBind env (Rec prs)
-  = mapAccumL tidyLetBndr  env prs     =: \ (env', bndrs') ->
+  = let 
+       (env', bndrs') = mapAccumL (tidyLetBndr env') env prs
+    in
     map (tidyExpr env') (map snd prs)  =: \ rhss' ->
     (env', Rec (zip bndrs' rhss'))
 
@@ -53,11 +55,12 @@ tidyBind env (Rec prs)
 ------------  Expressions  --------------
 tidyExpr :: TidyEnv -> CoreExpr -> CoreExpr
 tidyExpr env (Var v)            =  Var (tidyVarOcc env v)
-tidyExpr env (Type ty)          =  Type (tidyType env ty)
-tidyExpr env (Lit lit)          =  Lit lit
+tidyExpr env (Type ty)  =  Type (tidyType env ty)
+tidyExpr env (Coercion co) = Coercion (tidyCo env co)
+tidyExpr _   (Lit lit)   =  Lit lit
 tidyExpr env (App f a)          =  App (tidyExpr env f) (tidyExpr env a)
 tidyExpr env (Note n e)  =  Note (tidyNote env n) (tidyExpr env e)
-tidyExpr env (Cast e co) =  Cast (tidyExpr env e) (tidyType env co)
+tidyExpr env (Cast e co) =  Cast (tidyExpr env e) (tidyCo env co)
 
 tidyExpr env (Let b e) 
   = tidyBind env b     =: \ (env', b') ->
@@ -73,23 +76,25 @@ tidyExpr env (Lam b e)
     Lam b (tidyExpr env' e)
 
 ------------  Case alternatives  --------------
-tidyAlt case_bndr env (con, vs, rhs)
+tidyAlt :: CoreBndr -> TidyEnv -> CoreAlt -> CoreAlt
+tidyAlt _case_bndr env (con, vs, rhs)
   = tidyBndrs env vs   =: \ (env', vs) ->
     (con, vs, tidyExpr env' rhs)
 
 ------------  Notes  --------------
-tidyNote env note            = note
+tidyNote :: TidyEnv -> Note -> Note
+tidyNote _ note            = note
 
 ------------  Rules  --------------
 tidyRules :: TidyEnv -> [CoreRule] -> [CoreRule]
-tidyRules env [] = []
+tidyRules _   [] = []
 tidyRules env (rule : rules)
   = tidyRule env rule                  =: \ rule ->
     tidyRules env rules        =: \ rules ->
     (rule : rules)
 
 tidyRule :: TidyEnv -> CoreRule -> CoreRule
-tidyRule env rule@(BuiltinRule {}) = rule
+tidyRule _   rule@(BuiltinRule {}) = rule
 tidyRule env rule@(Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs,
                          ru_fn = fn, ru_rough = mb_ns })
   = tidyBndrs env bndrs                =: \ (env', bndrs) ->
@@ -127,12 +132,17 @@ tidyBndr env var
 tidyBndrs :: TidyEnv -> [Var] -> (TidyEnv, [Var])
 tidyBndrs env vars = mapAccumL tidyBndr env vars
 
-tidyLetBndr :: TidyEnv -> (Id, CoreExpr) -> (TidyEnv, Var)
+tidyLetBndr :: TidyEnv        -- Knot-tied version for unfoldings
+            -> TidyEnv                -- The one to extend
+            -> (Id, CoreExpr) -> (TidyEnv, Var)
 -- Used for local (non-top-level) let(rec)s
-tidyLetBndr env (id,rhs) 
-  = ((tidy_env,new_var_env), final_id)
+tidyLetBndr rec_tidy_env env (id,rhs) 
+  = ((tidy_occ_env,new_var_env), final_id)
   where
-    ((tidy_env,var_env), new_id) = tidyIdBndr env id
+    ((tidy_occ_env,var_env), new_id) = tidyIdBndr env id
+    new_var_env = extendVarEnv var_env id final_id
+       -- Override the env we get back from tidyId with the 
+       -- new IdInfo so it gets propagated to the usage sites.
 
        -- We need to keep around any interesting strictness and
        -- demand info because later on we may need to use it when
@@ -146,22 +156,26 @@ tidyLetBndr env (id,rhs)
        -- CorePrep to turn the let into a case.
        --
        -- Similarly arity info for eta expansion in CorePrep
-       --
+       -- 
+       -- Set inline-prag info so that we preseve it across 
+       -- separate compilation boundaries
     final_id = new_id `setIdInfo` new_info
     idinfo   = idInfo id
-    new_info = vanillaIdInfo
+    new_info = idInfo new_id
                `setArityInfo`          exprArity rhs
-               `setAllStrictnessInfo`  newStrictnessInfo idinfo
-               `setNewDemandInfo`      newDemandInfo idinfo
+               `setStrictnessInfo`     strictnessInfo idinfo
+               `setDemandInfo`         demandInfo idinfo
+               `setInlinePragInfo`     inlinePragInfo idinfo
+               `setUnfoldingInfo`      new_unf
 
-    -- Override the env we get back from tidyId with the new IdInfo
-    -- so it gets propagated to the usage sites.
-    new_var_env = extendVarEnv var_env id final_id
+    new_unf | isStableUnfolding unf = tidyUnfolding rec_tidy_env unf (panic "tidy_unf")
+            | otherwise                    = noUnfolding
+    unf = unfoldingInfo idinfo
 
 -- Non-top-level variables
 tidyIdBndr :: TidyEnv -> Id -> (TidyEnv, Id)
 tidyIdBndr env@(tidy_env, var_env) id
-  = -- do this pattern match strictly, otherwise we end up holding on to
+  = -- Do this pattern match strictly, otherwise we end up holding on to
     -- stuff in the OccName.
     case tidyOccName tidy_env (getOccName id) of { (tidy_env', occ') -> 
     let 
@@ -169,18 +183,55 @@ tidyIdBndr env@(tidy_env, var_env) id
        -- The SrcLoc isn't important now, 
        -- though we could extract it from the Id
        -- 
-       -- All nested Ids now have the same IdInfo, namely vanillaIdInfo,
-       -- which should save some space.
-       -- But note that tidyLetBndr puts some of it back.
-        ty'              = tidyType env (idType id)
-       id'               = mkUserLocal occ' (idUnique id) ty' noSrcLoc
-                               `setIdInfo` vanillaIdInfo
-       var_env'          = extendVarEnv var_env id id'
+        ty'      = tidyType env (idType id)
+        name'    = mkInternalName (idUnique id) occ' noSrcSpan
+       id'      = mkLocalIdWithInfo name' ty' new_info
+       var_env' = extendVarEnv var_env id id'
+
+       -- Note [Tidy IdInfo]
+        new_info = vanillaIdInfo `setOccInfo` occInfo old_info
+       old_info = idInfo id
     in
-     ((tidy_env', var_env'), id')
+    ((tidy_env', var_env'), id')
    }
+
+------------ Unfolding  --------------
+tidyUnfolding :: TidyEnv -> Unfolding -> Unfolding -> Unfolding
+tidyUnfolding tidy_env (DFunUnfolding ar con ids) _
+  = DFunUnfolding ar con (map (fmap (tidyExpr tidy_env)) ids)
+tidyUnfolding tidy_env 
+              unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src })
+              unf_from_rhs
+  | isStableSource src
+  = unf { uf_tmpl = tidyExpr tidy_env unf_rhs,            -- Preserves OccInfo
+         uf_src  = tidySrc tidy_env src }
+  | otherwise
+  = unf_from_rhs
+tidyUnfolding _ unf _ = unf    -- NoUnfolding or OtherCon
+
+tidySrc :: TidyEnv -> UnfoldingSource -> UnfoldingSource
+tidySrc tidy_env (InlineWrapper w) = InlineWrapper (tidyVarOcc tidy_env w)
+tidySrc _        inl_info          = inl_info
 \end{code}
 
+Note [Tidy IdInfo]
+~~~~~~~~~~~~~~~~~~
+All nested Ids now have the same IdInfo, namely vanillaIdInfo, which
+should save some space; except that we preserve occurrence info for
+two reasons:
+
+  (a) To make printing tidy core nicer
+
+  (b) Because we tidy RULES and InlineRules, which may then propagate
+      via --make into the compilation of the next module, and we want
+      the benefit of that occurrence analysis when we use the rule or
+      or inline the function.  In particular, it's vital not to lose
+      loop-breaker info, else we get an infinite inlining loop
+      
+Note that tidyLetBndr puts more IdInfo back.
+
+
 \begin{code}
+(=:) :: a -> (a -> b) -> b
 m =: k = m `seq` k m
 \end{code}