[project @ 1998-06-16 16:44:27 by simonpj]
[ghc-hetmet.git] / ghc / compiler / simplCore / SetLevels.lhs
index 5e9fffc..a99bcfd 100644 (file)
@@ -10,44 +10,44 @@ We also let-ify many applications (notably case scrutinees), so they
 will have a fighting chance of being floated sensible.
 
 \begin{code}
-#include "HsVersions.h"
-
 module SetLevels (
        setLevels,
 
        Level(..), tOP_LEVEL,
 
        incMinorLvl, ltMajLvl, ltLvl, isTopLvl
--- not exported: , incMajorLvl, isTopMajLvl, unTopify
     ) where
 
-import Ubiq{-uitous-}
+#include "HsVersions.h"
 
 import AnnCoreSyn
 import CoreSyn
 
-import CoreUtils       ( coreExprType, manifestlyWHNF, manifestlyBottom )
+import CoreUtils       ( coreExprType, idSpecVars )
+import CoreUnfold      ( FormSummary, whnfOrBottom, mkFormSummary )
 import FreeVars                -- all of it
-import Id              ( idType, mkSysLocal, toplevelishId,
+import MkId            ( mkSysLocal )
+import Id              ( idType,
                          nullIdEnv, addOneToIdEnv, growIdEnvList,
-                         unionManyIdSets, minusIdSet, mkIdSet,
-                         idSetToList,
-                         lookupIdEnv, IdEnv(..)
+                         unionManyIdSets, unionIdSets, minusIdSet, mkIdSet,
+                         idSetToList, Id,
+                         lookupIdEnv, IdEnv
                        )
-import Pretty          ( ppStr, ppBesides, ppChar, ppInt )
-import SrcLoc          ( mkUnknownSrcLoc )
-import Type            ( isPrimType, mkTyVarTys, mkForAllTys )
-import TyVar           ( nullTyVarEnv, addOneToTyVarEnv,
+import SrcLoc          ( noSrcLoc )
+import Type            ( isUnpointedType, mkTyVarTys, mkForAllTys, tyVarsOfTypes, Type )
+import TyVar           ( emptyTyVarEnv, addToTyVarEnv,
                          growTyVarEnvList, lookupTyVarEnv,
-                         tyVarSetToList,
-                         TyVarEnv(..),
-                         unionManyTyVarSets
+                         tyVarSetToList, 
+                         TyVarEnv, TyVar,
+                         unionManyTyVarSets, unionTyVarSets
                        )
 import UniqSupply      ( thenUs, returnUs, mapUs, mapAndUnzipUs,
-                         mapAndUnzip3Us, getUnique, UniqSM(..)
+                         mapAndUnzip3Us, getUnique, UniqSM,
+                         UniqSupply
                        )
-import Usage           ( UVar(..) )
-import Util            ( mapAccumL, zipWithEqual, panic, assertPanic )
+import BasicTypes      ( Unused )
+import Util            ( mapAccumL, zipWithEqual, zipEqual, panic, assertPanic )
+import Outputable
 
 isLeakFreeType x y = False -- safe option; ToDo
 \end{code}
@@ -91,9 +91,9 @@ sub-expression so that it will indeed float. This context level starts
 at @Level 0 0@; it is never @Top@.
 
 \begin{code}
-type LevelledExpr  = GenCoreExpr    (Id, Level) Id TyVar UVar
-type LevelledArg   = GenCoreArg                        Id TyVar UVar
-type LevelledBind  = GenCoreBinding (Id, Level) Id TyVar UVar
+type LevelledExpr  = GenCoreExpr    (Id, Level) Id Unused
+type LevelledArg   = GenCoreArg                        Id Unused
+type LevelledBind  = GenCoreBinding (Id, Level) Id Unused
 
 type LevelEnvs = (IdEnv    Level, -- bind Ids to levels
                  TyVarEnv Level) -- bind type variables to levels
@@ -141,8 +141,8 @@ unTopify Top = Level 0 0
 unTopify lvl = lvl
 
 instance Outputable Level where
-  ppr sty Top            = ppStr "<Top>"
-  ppr sty (Level maj min) = ppBesides [ ppChar '<', ppInt maj, ppChar ',', ppInt min, ppChar '>' ]
+  ppr Top            = ptext SLIT("<Top>")
+  ppr (Level maj min) = hcat [ char '<', int maj, char ',', int min, char '>' ]
 \end{code}
 
 %************************************************************************
@@ -170,7 +170,7 @@ setLevels binds us
        do_them bs       `thenLvl` \ lvld_binds ->
        returnLvl (lvld_bind ++ lvld_binds)
 
-initial_envs = (nullIdEnv, nullTyVarEnv)
+initial_envs = (nullIdEnv, emptyTyVarEnv)
 
 lvlTopBind (NonRec binder rhs)
   = lvlBind (Level 0 0) initial_envs (AnnNonRec binder (freeVars rhs))
@@ -189,7 +189,7 @@ lvlTopBind (Rec pairs)
 The binding stuff works for top level too.
 
 \begin{code}
-type CoreBindingWithFVs = AnnCoreBinding Id Id TyVar UVar FVInfo
+type CoreBindingWithFVs = AnnCoreBinding Id Id Unused FVInfo
 
 lvlBind :: Level
        -> LevelEnvs
@@ -214,7 +214,7 @@ lvlBind ctxt_lvl envs@(venv, tenv) (AnnRec pairs)
        binders_w_lvls = binders `zip` repeat final_lvl
        new_envs       = (growIdEnvList venv binders_w_lvls, tenv)
     in
-    returnLvl (extra_binds ++ [Rec (binders_w_lvls `zip` rhss')], new_envs)
+    returnLvl (extra_binds ++ [Rec (zipEqual "lvlBind" binders_w_lvls rhss')], new_envs)
   where
     (binders,rhss) = unzip pairs
 \end{code}
@@ -259,26 +259,35 @@ lvlExpr ctxt_lvl envs@(venv, tenv) (_, AnnApp fun arg)
   = lvlExpr ctxt_lvl envs fun          `thenLvl` \ fun' ->
     returnLvl (App fun' arg)
 
-lvlExpr ctxt_lvl envs (_, AnnSCC cc expr)
+lvlExpr ctxt_lvl envs (_, AnnNote note expr)
   = lvlExpr ctxt_lvl envs expr                 `thenLvl` \ expr' ->
-    returnLvl (SCC cc expr')
+    returnLvl (Note note expr')
+
+-- We don't split adjacent lambdas.  That is, given
+--     \x y -> (x+1,y)
+-- we don't float to give 
+--     \x -> let v = x+y in \y -> (v,y)
+-- Why not?  Because partial applications are fairly rare, and splitting
+-- lambdas makes them more expensive.
 
 lvlExpr ctxt_lvl envs@(venv, tenv) (_, AnnLam (ValBinder arg) rhs)
-  = lvlMFE incd_lvl (new_venv, tenv) rhs `thenLvl` \ rhs' ->
-    returnLvl (Lam (ValBinder (arg,incd_lvl)) rhs')
+  = lvlMFE incd_lvl (new_venv, tenv) body `thenLvl` \ body' ->
+    returnLvl (foldr (Lam . ValBinder) body' lvld_args)
   where
-    incd_lvl = incMajorLvl ctxt_lvl
-    new_venv = growIdEnvList venv [(arg,incd_lvl)]
+    incd_lvl     = incMajorLvl ctxt_lvl
+    (args, body) = annCollectValBinders rhs
+    lvld_args    = [(a,incd_lvl) | a <- (arg:args)]
+    new_venv     = growIdEnvList venv lvld_args
 
-lvlExpr ctxt_lvl (venv, tenv) (_, AnnLam (TyBinder tyvar) e)
-  = lvlExpr incd_lvl (venv, new_tenv) e        `thenLvl` \ e' ->
-    returnLvl (Lam (TyBinder tyvar) e')
-  where
-    incd_lvl   = incMinorLvl ctxt_lvl
-    new_tenv   = addOneToTyVarEnv tenv tyvar incd_lvl
+-- We don't need to play such tricks for type lambdas, because
+-- they don't get annotated
 
-lvlExpr ctxt_lvl (venv, tenv) (_, AnnLam (UsageBinder u) e)
-  = panic "SetLevels.lvlExpr:AnnLam UsageBinder"
+lvlExpr ctxt_lvl (venv, tenv) (_, AnnLam (TyBinder tyvar) body)
+  = lvlExpr incd_lvl (venv, new_tenv) body     `thenLvl` \ body' ->
+    returnLvl (Lam (TyBinder tyvar) body')
+  where
+    incd_lvl = incMinorLvl ctxt_lvl
+    new_tenv = addToTyVarEnv tenv tyvar incd_lvl
 
 lvlExpr ctxt_lvl envs (_, AnnLet bind body)
   = lvlBind ctxt_lvl envs bind         `thenLvl` \ (binds', new_envs) ->
@@ -335,7 +344,7 @@ lvlMFE ::  Level            -- Level of innermost enclosing lambda/tylam
        -> LvlM LevelledExpr    -- Result expression
 
 lvlMFE ctxt_lvl envs@(venv,_) ann_expr
-  | isPrimType ty      -- Can't let-bind it
+  | isUnpointedType ty -- Can't let-bind it
   = lvlExpr ctxt_lvl envs ann_expr
 
   | otherwise          -- Not primitive type so could be let-bound
@@ -402,7 +411,7 @@ setFloatLevel alreadyLetBound ctxt_lvl envs@(venv, tenv)
 -- any harm, and not floating it may pin something important.  For
 -- example
 --
---     x = let v = Nil
+--     x = let v = []
 --             w = 1:v
 --         in ...
 --
@@ -461,7 +470,7 @@ setFloatLevel alreadyLetBound ctxt_lvl envs@(venv, tenv)
 
     offending tyvar = ids_only_lvl `ltLvl` tyvarLevel tenv tyvar
 
-    manifestly_whnf = manifestlyWHNF de_ann_expr || manifestlyBottom de_ann_expr
+    manifestly_whnf = whnfOrBottom (mkFormSummary de_ann_expr)
 
     maybe_unTopify Top | not (canFloatToTop (ty, expr)) = Level 0 0
     maybe_unTopify lvl                                  = lvl
@@ -564,11 +573,11 @@ type lambdas.
 \begin{code}
 decideRecFloatLevel ctxt_lvl envs@(venv, tenv) ids rhss
   | isTopMajLvl ids_only_lvl   &&              -- Destination = top
-    not (all canFloatToTop (tys `zip` rhss))   -- Some can't float to top
+    not (all canFloatToTop (zipEqual "decideRec" tys rhss)) -- Some can't float to top
   =    -- Pin it here
     let
        ids_w_lvls = ids `zip` repeat ctxt_lvl
-       new_envs       = (growIdEnvList venv ids_w_lvls, tenv)
+       new_envs   = (growIdEnvList venv ids_w_lvls, tenv)
     in
     mapLvl (lvlExpr ctxt_lvl new_envs) rhss    `thenLvl` \ rhss' ->
     returnLvl (ctxt_lvl, [], rhss')
@@ -601,20 +610,21 @@ decideRecFloatLevel ctxt_lvl envs@(venv, tenv) ids rhss
     mapLvl (lvlExpr incd_lvl new_envs) rhss    `thenLvl` \ rhss' ->
     mapLvl newLvlVar poly_tys                  `thenLvl` \ poly_vars ->
     let
-       ids_w_poly_vars = ids `zip` poly_vars
+       ids_w_poly_vars = zipEqual "decideRec2" ids poly_vars
 
                -- The "d_rhss" are the right-hand sides of "D" and "D'"
                -- in the documentation above
        d_rhss = [ mkTyApp (Var poly_var) offending_tyvar_tys | poly_var <- poly_vars]
 
                -- "local_binds" are "D'" in the documentation above
-       local_binds = zipWithEqual NonRec ids_w_incd_lvl d_rhss
+       local_binds = zipWithEqual "SetLevels" NonRec ids_w_incd_lvl d_rhss
 
        poly_var_rhss = [ mkTyLam offending_tyvars (foldr Let rhs' local_binds)
                        | rhs' <- rhss' -- mkCoLet* requires Core...
                        ]
 
-       poly_binds  = [(poly_var, ids_only_lvl) | poly_var <- poly_vars] `zip` poly_var_rhss
+       poly_binds  = zipEqual "poly_binds" [(poly_var, ids_only_lvl) | poly_var <- poly_vars] 
+                                           poly_var_rhss
 
     in
     returnLvl (ctxt_lvl, [Rec poly_binds], d_rhss)
@@ -633,8 +643,24 @@ decideRecFloatLevel ctxt_lvl envs@(venv, tenv) ids rhss
   where
     tys  = map idType ids
 
-    fvs  = unionManyIdSets [freeVarsOf   rhs | rhs <- rhss] `minusIdSet` mkIdSet ids
+    fvs  = (unionManyIdSets [freeVarsOf   rhs | rhs <- rhss] `unionIdSets`
+           mkIdSet (concat (map idSpecVars ids)))
+          `minusIdSet` mkIdSet ids
     tfvs = unionManyTyVarSets [freeTyVarsOf rhs | rhs <- rhss]
+          `unionTyVarSets`
+          tyVarsOfTypes tys
+       -- Why the "tyVarsOfTypes" part?  Consider this:
+       --      /\a -> letrec x::a = x in E
+       -- Now, there are no explicit free type variables in the RHS of x,
+       -- but nevertheless "a" is free in its definition.  So we add in
+       -- the free tyvars of the types of the binders.
+       -- This actually happened in the defn of errorIO in IOBase.lhs:
+       --      errorIO (ST io) = case (errorIO# io) of
+       --                          _ -> bottom
+       --                        where
+       --                          bottom = bottom -- Never evaluated
+       -- I don't think this can every happen for non-recursive bindings.
+
     fv_list = idSetToList fvs
     tv_list = tyVarSetToList tfvs
 
@@ -667,7 +693,7 @@ isWorthFloating alreadyLetBound expr
   | otherwise       =  -- No point in adding a fresh let-binding for a WHNF, because
                        -- floating it isn't beneficial enough.
                      isWorthFloatingExpr expr &&
-                     not (manifestlyWHNF expr || manifestlyBottom expr)
+                     not (whnfOrBottom expr)
 ********** -}
 
 isWorthFloatingExpr :: CoreExpr -> Bool
@@ -685,7 +711,7 @@ canFloatToTop :: (Type, CoreExprWithFVs) -> Bool
 canFloatToTop (ty, (FVInfo _ _ (LeakFree _), expr)) = True
 canFloatToTop (ty, (FVInfo _ _ MightLeak,    expr)) = isLeakFreeType [] ty
 
-valSuggestsLeakFree expr = manifestlyWHNF expr || manifestlyBottom expr
+valSuggestsLeakFree expr = whnfOrBottom expr
 \end{code}
 
 
@@ -701,8 +727,7 @@ idLevel :: IdEnv Level -> Id -> Level
 idLevel venv v
   = case lookupIdEnv venv v of
       Just level -> level
-      Nothing    -> ASSERT(toplevelishId v)
-                   tOP_LEVEL
+      Nothing    -> tOP_LEVEL
 
 tyvarLevel :: TyVarEnv Level -> TyVar -> Level
 tyvarLevel tenv tyvar
@@ -711,6 +736,16 @@ tyvarLevel tenv tyvar
       Nothing    -> tOP_LEVEL
 \end{code}
 
+\begin{code}
+annCollectValBinders (_, (AnnLam (ValBinder arg) rhs))
+  = (arg:args, body) 
+  where
+    (args, body) = annCollectValBinders rhs
+
+annCollectValBinders body
+  = ([], body)
+\end{code}
+
 %************************************************************************
 %*                                                                     *
 \subsection{Free-To-Level Monad}
@@ -734,5 +769,5 @@ applications, to give them a fighting chance of being floated.
 newLvlVar :: Type -> LvlM Id
 
 newLvlVar ty us
-  = mkSysLocal SLIT("lvl") (getUnique us) ty mkUnknownSrcLoc
+  = mkSysLocal SLIT("lvl") (getUnique us) ty noSrcLoc
 \end{code}