Use OPTIONS rather than OPTIONS_GHC for pragmas
[ghc-hetmet.git] / compiler / simplCore / SimplEnv.lhs
index fca0d61..649dd1b 100644 (file)
@@ -4,9 +4,16 @@
 \section[SimplMonad]{The simplifier Monad}
 
 \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/CodingStyle#Warnings
+-- for details
+
 module SimplEnv (
-       InId, InBind, InExpr, InAlt, InArg, InType, InBinder,
-       OutId, OutTyVar, OutBind, OutExpr, OutAlt, OutArg, OutType, OutBinder,
+       InId, InBind, InExpr, InAlt, InArg, InType, InBndr,
+       OutId, OutTyVar, OutBind, OutExpr, OutAlt, OutArg, OutType, OutBndr,
         InCoercion, OutCoercion,
 
        -- The simplifier mode
@@ -19,52 +26,47 @@ module SimplEnv (
        setEnclosingCC, getEnclosingCC,
 
        -- Environments
-       SimplEnv, mkSimplEnv, extendIdSubst, extendTvSubst, 
+       SimplEnv(..), pprSimplEnv,      -- Temp not abstract
+       mkSimplEnv, extendIdSubst, SimplEnv.extendTvSubst, 
        zapSubstEnv, setSubstEnv, 
        getInScope, setInScope, setInScopeSet, modifyInScope, addNewInScopeIds,
        getRules, 
 
-       SimplSR(..), mkContEx, substId, 
+       SimplSR(..), mkContEx, substId, lookupRecBndr,
 
        simplNonRecBndr, simplRecBndrs, simplLamBndr, simplLamBndrs, 
        simplBinder, simplBinders, addLetIdInfo,
-       substExpr, substTy,
+       substExpr, substTy, 
 
        -- Floats
-       FloatsWith, FloatsWithExpr,
-       Floats, emptyFloats, isEmptyFloats, unitFloat, addFloats, flattenFloats,
-       allLifted, wrapFloats, floatBinds,
-       addAuxiliaryBind,
+       Floats, emptyFloats, isEmptyFloats, addNonRec, addFloats, extendFloats,
+       wrapFloats, floatBinds, setFloats, zapFloats, addRecFloats,
+       doFloatFromRhs, getFloats
     ) where
 
 #include "HsVersions.h"
 
 import SimplMonad      
-import Id              ( Id, idType, idOccInfo, idUnfolding, setIdUnfolding )
-import IdInfo          ( IdInfo, vanillaIdInfo, occInfo, setOccInfo, specInfo, setSpecInfo,
-                         arityInfo, workerInfo, setWorkerInfo, 
-                         unfoldingInfo, setUnfoldingInfo, isEmptySpecInfo,
-                         workerExists
-                           )
+import IdInfo
 import CoreSyn
-import Rules           ( RuleBase )
-import CoreUtils       ( needsCaseBinding )
-import CostCentre      ( CostCentreStack, subsumedCCS )
-import Var     
+import Rules
+import CoreUtils
+import CostCentre
+import Var
 import VarEnv
-import VarSet          ( isEmptyVarSet )
+import VarSet
 import OrdList
-
+import Id
 import qualified CoreSubst     ( Subst, mkSubst, substExpr, substSpec, substWorker )
 import qualified Type          ( substTy, substTyVarBndr )
-
-import Type             ( Type, TvSubst(..), TvSubstEnv,
-                         isUnLiftedType, seqType, tyVarsOfType )
-import Coercion         ( Coercion )
-import BasicTypes      ( OccInfo(..), isFragileOcc )
-import DynFlags                ( SimplifierMode(..) )
-import Util            ( mapAccumL )
+import Type hiding             ( substTy, substTyVarBndr )
+import Coercion
+import BasicTypes      
+import DynFlags
+import Util
 import Outputable
+
+import Data.List
 \end{code}
 
 %************************************************************************
@@ -74,7 +76,7 @@ import Outputable
 %************************************************************************
 
 \begin{code}
-type InBinder   = CoreBndr
+type InBndr     = CoreBndr
 type InId       = Id                   -- Not yet cloned
 type InType     = Type                 -- Ditto
 type InBind     = CoreBind
@@ -83,7 +85,7 @@ type InAlt      = CoreAlt
 type InArg      = CoreArg
 type InCoercion = Coercion
 
-type OutBinder   = CoreBndr
+type OutBndr     = CoreBndr
 type OutId      = Id                   -- Cloned
 type OutTyVar   = TyVar                -- Cloned
 type OutType    = Type                 -- Cloned
@@ -108,19 +110,27 @@ data SimplEnv
        seChkr      :: SwitchChecker,
        seCC        :: CostCentreStack, -- The enclosing CCS (when profiling)
 
-       -- Rules from other modules
-       seExtRules  :: RuleBase,
-
        -- The current set of in-scope variables
        -- They are all OutVars, and all bound in this module
        seInScope   :: InScopeSet,      -- OutVars only
+               -- Includes all variables bound by seFloats
+       seFloats    :: Floats,
+               -- See Note [Simplifier floats]
 
        -- The current substitution
        seTvSubst   :: TvSubstEnv,      -- InTyVar |--> OutType
        seIdSubst   :: SimplIdSubst     -- InId    |--> OutExpr
+
     }
 
+pprSimplEnv :: SimplEnv -> SDoc
+-- Used for debugging; selective
+pprSimplEnv env
+  = vcat [ptext SLIT("TvSubst:") <+> ppr (seTvSubst env),
+         ptext SLIT("IdSubst:") <+> ppr (seIdSubst env) ]
+
 type SimplIdSubst = IdEnv SimplSR      -- IdId |--> OutExpr
+       -- See Note [Extending the Subst] in CoreSubst
 
 data SimplSR
   = DoneEx OutExpr             -- Completed term
@@ -128,6 +138,16 @@ data SimplSR
   | ContEx TvSubstEnv          -- A suspended substitution
           SimplIdSubst
           InExpr        
+
+instance Outputable SimplSR where
+  ppr (DoneEx e) = ptext SLIT("DoneEx") <+> ppr e
+  ppr (DoneId v) = ptext SLIT("DoneId") <+> ppr v
+  ppr (ContEx tv id e) = vcat [ptext SLIT("ContEx") <+> ppr e {-,
+                               ppr (filter_env tv), ppr (filter_env id) -}]
+       -- where
+       -- fvs = exprFreeVars e
+       -- filter_env env = filterVarEnv_Directly keep env
+       -- keep uniq _ = uniq `elemUFM_Directly` fvs
 \end{code}
 
 
@@ -193,11 +213,11 @@ seIdSubst:
 
 
 \begin{code}
-mkSimplEnv :: SimplifierMode -> SwitchChecker -> RuleBase -> SimplEnv
-mkSimplEnv mode switches rules
+mkSimplEnv :: SimplifierMode -> SwitchChecker -> SimplEnv
+mkSimplEnv mode switches
   = SimplEnv { seChkr = switches, seCC = subsumedCCS, 
               seMode = mode, seInScope = emptyInScopeSet, 
-              seExtRules = rules,
+              seFloats = emptyFloats,
               seTvSubst = emptyVarEnv, seIdSubst = emptyVarEnv }
        -- The top level "enclosing CC" is "SUBSUMED".
 
@@ -236,7 +256,16 @@ setInScopeSet :: SimplEnv -> InScopeSet -> SimplEnv
 setInScopeSet env in_scope = env {seInScope = in_scope}
 
 setInScope :: SimplEnv -> SimplEnv -> SimplEnv
-setInScope env env_with_in_scope = setInScopeSet env (getInScope env_with_in_scope)
+-- Set the in-scope set, and *zap* the floats
+setInScope env env_with_scope
+  = env { seInScope = seInScope env_with_scope,
+         seFloats = emptyFloats }
+
+setFloats :: SimplEnv -> SimplEnv -> SimplEnv
+-- Set the in-scope set *and* the floats
+setFloats env env_with_floats
+  = env { seInScope = seInScope env_with_floats,
+         seFloats  = seFloats  env_with_floats }
 
 addNewInScopeIds :: SimplEnv -> [CoreBndr] -> SimplEnv
        -- The new Ids are guaranteed to be freshly allocated
@@ -266,10 +295,155 @@ mkContEx (SimplEnv { seTvSubst = tvs, seIdSubst = ids }) e = ContEx tvs ids e
 isEmptySimplSubst :: SimplEnv -> Bool
 isEmptySimplSubst (SimplEnv { seTvSubst = tvs, seIdSubst = ids })
   = isEmptyVarEnv tvs && isEmptyVarEnv ids
+\end{code}
 
----------------------
-getRules :: SimplEnv -> RuleBase
-getRules = seExtRules
+
+
+%************************************************************************
+%*                                                                     *
+\subsection{Floats}
+%*                                                                     *
+%************************************************************************
+
+Note [Simplifier floats]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+The Floats is a bunch of bindings, classified by a FloatFlag.
+
+  NonRec x (y:ys)      FltLifted
+  Rec [(x,rhs)]                FltLifted
+
+  NonRec x# (y +# 3)   FltOkSpec       -- Unboxed, but ok-for-spec'n
+
+  NonRec x# (a /# b)   FltCareful
+  NonRec x* (f y)      FltCareful      -- Strict binding; might fail or diverge
+  NonRec x# (f y)      FltCareful      -- Unboxed binding: might fail or diverge
+                                       --        (where f :: Int -> Int#)
+
+\begin{code}
+data Floats = Floats (OrdList OutBind) FloatFlag
+       -- See Note [Simplifier floats]
+
+data FloatFlag
+  = FltLifted  -- All bindings are lifted and lazy
+               --  Hence ok to float to top level, or recursive
+
+  | FltOkSpec  -- All bindings are FltLifted *or* 
+               --      strict (perhaps because unlifted, 
+               --      perhaps because of a strict binder),
+               --        *and* ok-for-speculation
+               --  Hence ok to float out of the RHS 
+               --  of a lazy non-recursive let binding
+               --  (but not to top level, or into a rec group)
+
+  | FltCareful -- At least one binding is strict (or unlifted)
+               --      and not guaranteed cheap
+               --      Do not float these bindings out of a lazy let
+
+instance Outputable Floats where
+  ppr (Floats binds ff) = ppr ff $$ ppr (fromOL binds)
+
+instance Outputable FloatFlag where
+  ppr FltLifted = ptext SLIT("FltLifted")
+  ppr FltOkSpec = ptext SLIT("FltOkSpec")
+  ppr FltCareful = ptext SLIT("FltCareful")
+   
+andFF :: FloatFlag -> FloatFlag -> FloatFlag
+andFF FltCareful _         = FltCareful
+andFF FltOkSpec  FltCareful = FltCareful
+andFF FltOkSpec  flt       = FltOkSpec
+andFF FltLifted  flt       = flt
+
+classifyFF :: CoreBind -> FloatFlag
+classifyFF (Rec _) = FltLifted
+classifyFF (NonRec bndr rhs) 
+  | not (isStrictId bndr)    = FltLifted
+  | exprOkForSpeculation rhs = FltOkSpec
+  | otherwise               = FltCareful
+
+doFloatFromRhs :: TopLevelFlag -> RecFlag -> Bool -> OutExpr -> SimplEnv -> Bool
+doFloatFromRhs lvl rec str rhs (SimplEnv {seFloats = Floats fs ff}) 
+  =  not (isNilOL fs) && want_to_float && can_float
+  where
+     want_to_float = isTopLevel lvl || exprIsCheap rhs
+     can_float = case ff of
+                  FltLifted  -> True
+                  FltOkSpec  -> isNotTopLevel lvl && isNonRec rec
+                  FltCareful -> isNotTopLevel lvl && isNonRec rec && str
+\end{code}
+
+
+\begin{code}
+emptyFloats :: Floats
+emptyFloats = Floats nilOL FltLifted
+
+unitFloat :: OutBind -> Floats
+-- A single-binding float
+unitFloat bind = Floats (unitOL bind) (classifyFF bind)
+
+addNonRec :: SimplEnv -> OutId -> OutExpr -> SimplEnv
+-- Add a non-recursive binding and extend the in-scope set
+-- The latter is important; the binder may already be in the
+-- in-scope set (although it might also have been created with newId)
+-- but it may now have more IdInfo
+addNonRec env id rhs
+  = env { seFloats = seFloats env `addFlts` unitFloat (NonRec id rhs),
+         seInScope = extendInScopeSet (seInScope env) id }
+
+extendFloats :: SimplEnv -> [OutBind] -> SimplEnv
+-- Add these bindings to the floats, and extend the in-scope env too
+extendFloats env binds
+  = env { seFloats  = seFloats env `addFlts` new_floats,
+         seInScope = extendInScopeSetList (seInScope env) bndrs }
+  where
+    bndrs = bindersOfBinds binds
+    new_floats = Floats (toOL binds) 
+                       (foldr (andFF . classifyFF) FltLifted binds)
+
+addFloats :: SimplEnv -> SimplEnv -> SimplEnv
+-- Add the floats for env2 to env1; 
+-- *plus* the in-scope set for env2, which is bigger 
+-- than that for env1
+addFloats env1 env2 
+  = env1 {seFloats = seFloats env1 `addFlts` seFloats env2,
+         seInScope = seInScope env2 }
+
+addFlts :: Floats -> Floats -> Floats
+addFlts (Floats bs1 l1) (Floats bs2 l2)
+  = Floats (bs1 `appOL` bs2) (l1 `andFF` l2)
+
+zapFloats :: SimplEnv -> SimplEnv
+zapFloats env = env { seFloats = emptyFloats }
+
+addRecFloats :: SimplEnv -> SimplEnv -> SimplEnv
+-- Flattens the floats from env2 into a single Rec group,
+-- prepends the floats from env1, and puts the result back in env2
+-- This is all very specific to the way recursive bindings are
+-- handled; see Simplify.simplRecBind
+addRecFloats env1 env2@(SimplEnv {seFloats = Floats bs ff})
+  = ASSERT2( case ff of { FltLifted -> True; other -> False }, ppr (fromOL bs) )
+    env2 {seFloats = seFloats env1 `addFlts` unitFloat (Rec (flattenBinds (fromOL bs)))}
+
+wrapFloats :: SimplEnv -> OutExpr -> OutExpr
+wrapFloats env expr = wrapFlts (seFloats env) expr
+
+wrapFlts :: Floats -> OutExpr -> OutExpr
+-- Wrap the floats around the expression, using case-binding where necessary
+wrapFlts (Floats bs _) body = foldrOL wrap body bs
+  where
+    wrap (Rec prs)    body = Let (Rec prs) body
+    wrap (NonRec b r) body = bindNonRec b r body
+
+getFloats :: SimplEnv -> [CoreBind]
+getFloats (SimplEnv {seFloats = Floats bs _}) = fromOL bs
+
+isEmptyFloats :: SimplEnv -> Bool
+isEmptyFloats env = isEmptyFlts (seFloats env)
+
+isEmptyFlts :: Floats -> Bool
+isEmptyFlts (Floats bs _) = isNilOL bs 
+
+floatBinds :: Floats -> [OutBind]
+floatBinds (Floats bs _) = fromOL bs
 \end{code}
 
 
@@ -287,16 +461,26 @@ substId (SimplEnv { seInScope = in_scope, seIdSubst = ids }) v
   = DoneId v
   | otherwise  -- A local Id
   = case lookupVarEnv ids v of
-       Just (DoneId v) -> DoneId (refine v)
+       Just (DoneId v) -> DoneId (refine in_scope v)
        Just res        -> res
-       Nothing         -> DoneId (refine v)
+       Nothing         -> DoneId (refine in_scope v)
   where
+
        -- Get the most up-to-date thing from the in-scope set
        -- Even though it isn't in the substitution, it may be in
        -- the in-scope set with better IdInfo
-    refine v = case lookupInScope in_scope v of
-                Just v' -> v'
-                Nothing -> WARN( True, ppr v ) v       -- This is an error!
+refine in_scope v = case lookupInScope in_scope v of
+                        Just v' -> v'
+                        Nothing -> WARN( True, ppr v ) v       -- This is an error!
+
+lookupRecBndr :: SimplEnv -> Id -> Id
+-- Look up an Id which has been put into the envt by simplRecBndrs,
+-- but where we have not yet done its RHS
+lookupRecBndr (SimplEnv { seInScope = in_scope, seIdSubst = ids }) v
+  = case lookupVarEnv ids v of
+       Just (DoneId v) -> v
+       Just res        -> pprPanic "lookupRecBndr" (ppr v)
+       Nothing         -> refine in_scope v
 \end{code}
 
 
@@ -311,12 +495,12 @@ These functions are in the monad only so that they can be made strict via seq.
 
 \begin{code}
 simplBinders, simplLamBndrs
-       :: SimplEnv -> [InBinder] -> SimplM (SimplEnv, [OutBinder])
+       :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])
 simplBinders  env bndrs = mapAccumLSmpl simplBinder  env bndrs
 simplLamBndrs env bndrs = mapAccumLSmpl simplLamBndr env bndrs
 
 -------------
-simplBinder :: SimplEnv -> InBinder -> SimplM (SimplEnv, OutBinder)
+simplBinder :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
 -- Used for lambda and case-bound variables
 -- Clone Id if necessary, substitute type
 -- Return with IdInfo already substituted, but (fragile) occurrence info zapped
@@ -358,6 +542,8 @@ substIdBndr :: SimplEnv -> Id       -- Substitition and Id to transform
 --     * The substitution extended with a DoneId if unique changed
 --       In this case, the var in the DoneId is the same as the
 --       var returned
+--
+-- Exactly like CoreSubst.substIdBndr, except that the type of id_subst differs
 
 substIdBndr env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst})
            old_id
@@ -376,14 +562,15 @@ substIdBndr env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst})
 
        -- Extend the substitution if the unique has changed
        -- See the notes with substTyVarBndr for the delSubstEnv
+       -- Also see Note [Extending the Subst] in CoreSubst
     new_subst | new_id /= old_id
              = extendVarEnv id_subst old_id (DoneId new_id)
              | otherwise 
              = delVarEnv id_subst old_id
 \end{code}
 
-
 \begin{code}
+------------------------------------
 seqTyVar :: TyVar -> ()
 seqTyVar b = b `seq` ()
 
@@ -397,7 +584,6 @@ seqIds []       = ()
 seqIds (id:ids) = seqId id `seq` seqIds ids
 \end{code}
 
-
 %************************************************************************
 %*                                                                     *
                Let bindings
@@ -409,24 +595,28 @@ Simplifying let binders
 Rename the binders if necessary, 
 
 \begin{code}
-simplNonRecBndr :: SimplEnv -> InBinder -> SimplM (SimplEnv, OutBinder)
+simplNonRecBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
 simplNonRecBndr env id
   = do { let (env1, id1) = substLetIdBndr env id
        ; seqId id1 `seq` return (env1, id1) }
 
 ---------------
-simplRecBndrs :: SimplEnv -> [InBinder] -> SimplM (SimplEnv, [OutBinder])
+simplRecBndrs :: SimplEnv -> [InBndr] -> SimplM SimplEnv
 simplRecBndrs env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst }) ids
   = do { let (env1, ids1) = mapAccumL substLetIdBndr env ids
-       ; seqIds ids1 `seq` return (env1, ids1) }
+       ; seqIds ids1 `seq` return env1 }
 
 ---------------
-substLetIdBndr :: SimplEnv -> InBinder         -- Env and binder to transform
-              -> (SimplEnv, OutBinder)
--- C.f. CoreSubst.substIdBndr
+substLetIdBndr :: SimplEnv -> InBndr   -- Env and binder to transform
+              -> (SimplEnv, OutBndr)
+-- C.f. substIdBndr above
 -- Clone Id if necessary, substitute its type
--- Return an Id with completely zapped IdInfo
+-- Return an Id with its fragile info zapped
+--     namely, any info that depends on free variables
 --     [addLetIdInfo, below, will restore its IdInfo]
+--     We want to retain robust info, especially arity and demand info,
+--     so that they are available to occurrences that occur in an
+--     earlier binding of a letrec
 -- Augment the subtitution 
 --     if the unique changed, *or* 
 --     if there's interesting occurrence info
@@ -437,20 +627,22 @@ substLetIdBndr env@(SimplEnv { seInScope = in_scope, seIdSubst = id_subst }) old
   where
     id1           = uniqAway in_scope old_id
     id2    = substIdType env id1
-    new_id = setIdInfo id2 vanillaIdInfo
+
+    -- We want to get rid of any info that's dependent on free variables,
+    -- but keep other info (like the arity).
+    new_id = zapFragileIdInfo id2
 
        -- Extend the substitution if the unique has changed,
        -- or there's some useful occurrence information
        -- See the notes with substTyVarBndr for the delSubstEnv
-    occ_info = occInfo (idInfo old_id)
     new_subst | new_id /= old_id
              = extendVarEnv id_subst old_id (DoneId new_id)
              | otherwise 
              = delVarEnv id_subst old_id
 \end{code}
 
-Add IdInfo back onto a let-bound Id
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [Add IdInfo back onto a let-bound Id]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 We must transfer the IdInfo of the original binder to the new binder.
 This is crucial, to preserve
        strictness
@@ -505,7 +697,7 @@ Here, we'll do postInlineUnconditionally on f, and we must "see" that
 when substituting in h's RULE.  
 
 \begin{code}
-addLetIdInfo :: SimplEnv -> InBinder -> OutBinder -> (SimplEnv, OutBinder)
+addLetIdInfo :: SimplEnv -> InBndr -> OutBndr -> (SimplEnv, OutBndr)
 addLetIdInfo env in_id out_id
   = (modifyInScope env out_id final_id, final_id)
   where
@@ -550,7 +742,7 @@ substIdInfo subst info
 substIdType :: SimplEnv -> Id -> Id
 substIdType env@(SimplEnv { seInScope = in_scope,  seTvSubst = tv_env}) id
   | isEmptyVarEnv tv_env || isEmptyVarSet (tyVarsOfType old_ty) = id
-  | otherwise  = setIdType id (Type.substTy (TvSubst in_scope tv_env) old_ty)
+  | otherwise  = Id.setIdType id (Type.substTy (TvSubst in_scope tv_env) 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
@@ -603,81 +795,3 @@ substExpr env expr
   | otherwise            = CoreSubst.substExpr (mkCoreSubst env) expr
 \end{code}
 
-
-%************************************************************************
-%*                                                                     *
-\subsection{Floats}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-type FloatsWithExpr = FloatsWith OutExpr
-type FloatsWith a   = (Floats, a)
-       -- We return something equivalent to (let b in e), but
-       -- in pieces to avoid the quadratic blowup when floating 
-       -- incrementally.  Comments just before simplExprB in Simplify.lhs
-
-data Floats = Floats (OrdList OutBind) 
-                    InScopeSet         -- Environment "inside" all the floats
-                    Bool               -- True <=> All bindings are lifted
-
-allLifted :: Floats -> Bool
-allLifted (Floats _ _ is_lifted) = is_lifted
-
-wrapFloats :: Floats -> OutExpr -> OutExpr
-wrapFloats (Floats bs _ _) body = foldrOL Let body bs
-
-isEmptyFloats :: Floats -> Bool
-isEmptyFloats (Floats bs _ _) = isNilOL bs 
-
-floatBinds :: Floats -> [OutBind]
-floatBinds (Floats bs _ _) = fromOL bs
-
-flattenFloats :: Floats -> Floats
--- Flattens into a single Rec group
-flattenFloats (Floats bs is is_lifted) 
-  = ASSERT2( is_lifted, ppr (fromOL bs) )
-    Floats (unitOL (Rec (flattenBinds (fromOL bs)))) is is_lifted
-\end{code}
-
-\begin{code}
-emptyFloats :: SimplEnv -> Floats
-emptyFloats env = Floats nilOL (getInScope env) True
-
-unitFloat :: SimplEnv -> OutId -> OutExpr -> Floats
--- A single non-rec float; extend the in-scope set
-unitFloat env var rhs = Floats (unitOL (NonRec var rhs))
-                              (extendInScopeSet (getInScope env) var)
-                              (not (isUnLiftedType (idType var)))
-
-addFloats :: SimplEnv -> Floats 
-         -> (SimplEnv -> SimplM (FloatsWith a))
-         -> SimplM (FloatsWith a)
-addFloats env (Floats b1 is1 l1) thing_inside
-  | isNilOL b1 
-  = thing_inside env
-  | otherwise
-  = thing_inside (setInScopeSet env is1)       `thenSmpl` \ (Floats b2 is2 l2, res) ->
-    returnSmpl (Floats (b1 `appOL` b2) is2 (l1 && l2), res)
-
-addLetBind :: OutBind -> Floats -> Floats
-addLetBind bind (Floats binds in_scope lifted) 
-  = Floats (bind `consOL` binds) in_scope (lifted && is_lifted_bind bind)
-
-is_lifted_bind (Rec _)      = True
-is_lifted_bind (NonRec b r) = not (isUnLiftedType (idType b))
-
--- addAuxiliaryBind    * takes already-simplified things (bndr and rhs)
---                     * extends the in-scope env
---                     * assumes it's a let-bindable thing
-addAuxiliaryBind :: SimplEnv -> OutBind
-                -> (SimplEnv -> SimplM (FloatsWith a))
-                -> SimplM (FloatsWith a)
-       -- Extends the in-scope environment as well as wrapping the bindings
-addAuxiliaryBind env bind thing_inside
-  = ASSERT( case bind of { NonRec b r -> not (needsCaseBinding (idType b) r) ; Rec _ -> True } )
-    thing_inside (addNewInScopeIds env (bindersOf bind))       `thenSmpl` \ (floats, x) ->
-    returnSmpl (addLetBind bind floats, x)
-\end{code}
-
-