#include "HsVersions.h"
import CoreSyn
+import CoreUtils ( mkSCC )
-import CmdLineOpts ( opt_D_verbose_core2core, opt_D_dump_simpl_stats )
-import ErrUtils ( dumpIfSet )
+import CmdLineOpts ( DynFlags, DynFlag(..) )
+import ErrUtils ( dumpIfSet_dyn )
import CostCentre ( dupifyCC, CostCentre )
-import Id ( Id, idType )
-import Const ( isWHNFCon )
+import Id ( Id )
import VarEnv
-import CoreLint ( beginPass, endPass )
-import PprCore
+import CoreLint ( showPass, endPass )
import SetLevels ( setLevels,
Level(..), tOP_LEVEL, ltMajLvl, ltLvl, isTopLvl
)
-import BasicTypes ( Unused )
-import Type ( isUnLiftedType )
-import Var ( TyVar )
import UniqSupply ( UniqSupply )
import List ( partition )
import Outputable
%************************************************************************
\begin{code}
-floatOutwards :: UniqSupply -> [CoreBind] -> IO [CoreBind]
+floatOutwards :: DynFlags
+ -> Bool -- True <=> float lambdas to top level
+ -> UniqSupply
+ -> [CoreBind] -> IO [CoreBind]
-floatOutwards us pgm
+floatOutwards dflags float_lams us pgm
= do {
- beginPass "Float out";
+ showPass dflags float_msg ;
- let { annotated_w_levels = setLevels pgm us ;
+ let { annotated_w_levels = setLevels float_lams pgm us ;
(fss, binds_s') = unzip (map floatTopBind annotated_w_levels)
} ;
- dumpIfSet opt_D_verbose_core2core "Levels added:"
+ dumpIfSet_dyn dflags Opt_D_verbose_core2core "Levels added:"
(vcat (map ppr annotated_w_levels));
let { (tlets, ntlets, lams) = get_stats (sum_stats fss) };
- dumpIfSet opt_D_dump_simpl_stats "FloatOut stats:"
+ dumpIfSet_dyn dflags Opt_D_dump_simpl_stats "FloatOut stats:"
(hcat [ int tlets, ptext SLIT(" Lets floated to top level; "),
int ntlets, ptext SLIT(" Lets floated elsewhere; from "),
int lams, ptext SLIT(" Lambda groups")]);
- endPass "Float out"
- opt_D_verbose_core2core {- no specific flag for dumping float-out -}
- (concat binds_s')
+ endPass dflags float_msg Opt_D_verbose_core2core (concat binds_s')
+ {- no specific flag for dumping float-out -}
}
+ where
+ float_msg | float_lams = "Float out (floating lambdas too)"
+ | otherwise = "Float out (not floating lambdas)"
floatTopBind bind@(NonRec _ _)
= case (floatBind emptyVarEnv tOP_LEVEL bind) of { (fs, floats, bind', _) ->
floatExpr env _ (Var v) = (zeroStats, [], Var v)
floatExpr env _ (Type ty) = (zeroStats, [], Type ty)
-floatExpr env lvl (Con con as)
- = case floatList (floatRhs env lvl) as of { (stats, floats, as') ->
- (stats, floats, Con con as') }
+floatExpr env _ (Lit lit) = (zeroStats, [], Lit lit)
floatExpr env lvl (App e a)
= case (floatExpr env lvl e) of { (fse, floats_e, e') ->
= [ (level, ann_bind floater) | (level, floater) <- defn_groups ]
where
ann_bind (NonRec binder rhs)
- = NonRec binder (ann_rhs rhs)
+ = NonRec binder (mkSCC dupd_cc rhs)
ann_bind (Rec pairs)
- = Rec [(binder, ann_rhs rhs) | (binder, rhs) <- pairs]
-
- ann_rhs (Lam arg e) = Lam arg (ann_rhs e)
- ann_rhs rhs@(Con con _) | isWHNFCon con = rhs -- no point in scc'ing WHNF data
- ann_rhs rhs = Note (SCC dupd_cc) rhs
-
- -- Note: Nested SCC's are preserved for the benefit of
- -- cost centre stack profiling (Durham)
+ = Rec [(binder, mkSCC dupd_cc rhs) | (binder, rhs) <- pairs]
-- At one time I tried the effect of not float anything out of an InlineMe,
-- but it sometimes works badly. For example, consider PrelArr.done. It