#include "HsVersions.h"
-import DynFlags ( DynFlags, DynFlag(..) )
import CoreSyn
import CoreUtils ( exprIsHNF, exprIsDupable )
-import CoreLint ( showPass, endPass )
-import CoreFVs ( CoreExprWithFVs, freeVars, freeVarsOf, idRuleVars )
+import CoreFVs ( CoreExprWithFVs, freeVars, freeVarsOf, idRuleAndUnfoldingVars )
import Id ( isOneShotBndr, idType )
import Var
import Type ( isUnLiftedType )
actually float any bindings downwards from the top-level.
\begin{code}
-floatInwards :: DynFlags -> [CoreBind] -> IO [CoreBind]
-
-floatInwards dflags binds
- = do {
- showPass dflags "Float inwards";
- let { binds' = map fi_top_bind binds };
- endPass dflags "Float inwards" Opt_D_verbose_core2core binds'
- {- no specific flag for dumping float-in -}
- }
-
+floatInwards :: [CoreBind] -> [CoreBind]
+floatInwards = map fi_top_bind
where
fi_top_bind (NonRec binder rhs)
= NonRec binder (fiExpr [] (freeVars rhs))
= -- Wimp out for now
mkCoLets' to_drop (Note note (fiExpr [] expr))
-fiExpr to_drop (_, AnnNote InlineMe expr)
- = -- Ditto... don't float anything into an INLINE expression
- mkCoLets' to_drop (Note InlineMe (fiExpr [] expr))
-
fiExpr to_drop (_, AnnNote note@(CoreNote _) expr)
= Note note (fiExpr to_drop expr)
\end{code}
Note [extra_fvs (s): free variables of rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Consider let x{rule mentioning y} = rhs in body
+Consider
+ let x{rule mentioning y} = rhs in body
Here y is not free in rhs or body; but we still want to dump bindings
that bind y outside the let. So we augment extra_fvs with the
-idRuleVars of x.
+idRuleAndUnfoldingVars of x. No need for type variables, hence not using
+idFreeVars.
\begin{code}
where
body_fvs = freeVarsOf body
- rule_fvs = idRuleVars id -- See Note [extra_fvs (2): free variables of rules]
+ rule_fvs = idRuleAndUnfoldingVars id -- See Note [extra_fvs (2): free variables of rules]
extra_fvs | noFloatIntoRhs ann_rhs
|| isUnLiftedType (idType id) = rule_fvs `unionVarSet` rhs_fvs
| otherwise = rule_fvs
body_fvs = freeVarsOf body
-- See Note [extra_fvs (1,2)]
- rule_fvs = foldr (unionVarSet . idRuleVars) emptyVarSet ids
+ rule_fvs = foldr (unionVarSet . idRuleAndUnfoldingVars) emptyVarSet ids
extra_fvs = rule_fvs `unionVarSet`
unionVarSets [ fvs | (fvs, rhs) <- rhss
, noFloatIntoRhs rhs ]
fi_alt to_drop (con, args, rhs) = (con, args, fiExpr to_drop rhs)
noFloatIntoRhs :: AnnExpr' Var (UniqFM Var) -> Bool
-noFloatIntoRhs (AnnNote InlineMe _) = True
-noFloatIntoRhs (AnnLam b _) = not (is_one_shot b)
+noFloatIntoRhs (AnnLam b _) = not (is_one_shot b)
-- IMPORTANT: don't say 'True' for a RHS with a one-shot lambda at the top.
-- This makes a big difference for things like
-- f x# = let x = I# x#
noFloatIntoRhs rhs = exprIsHNF (deAnnotate' rhs) -- We'd just float right back out again...
is_one_shot :: Var -> Bool
-is_one_shot b = isIdVar b && isOneShotBndr b
+is_one_shot b = isId b && isOneShotBndr b
\end{code}