X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FsimplCore%2FFloatIn.lhs;h=a4002a5c5b9ab1f5d402f357d839105f6fa18ee4;hb=3c502e702db94dce0606b1968f94c9755d4d4aba;hp=4744b33e76b327953e02f395b2dc85ecff5e31dd;hpb=9aa6d18bd696e8861fb8c3e065e49a989d2d67ac;p=ghc-hetmet.git diff --git a/ghc/compiler/simplCore/FloatIn.lhs b/ghc/compiler/simplCore/FloatIn.lhs index 4744b33..a4002a5 100644 --- a/ghc/compiler/simplCore/FloatIn.lhs +++ b/ghc/compiler/simplCore/FloatIn.lhs @@ -16,16 +16,16 @@ module FloatIn ( floatInwards ) where #include "HsVersions.h" -import CmdLineOpts ( DynFlags, DynFlag(..), dopt ) +import CmdLineOpts ( DynFlags, DynFlag(..) ) import CoreSyn import CoreUtils ( exprIsValue, exprIsDupable ) -import CoreLint ( beginPass, endPass ) +import CoreLint ( showPass, endPass ) import CoreFVs ( CoreExprWithFVs, freeVars, freeVarsOf ) -import Id ( isOneShotLambda ) -import Var ( Id, idType, isTyVar ) +import Id ( isOneShotBndr ) +import Var ( Id, idType ) import Type ( isUnLiftedType ) import VarSet -import Util ( zipEqual, zipWithEqual ) +import Util ( zipEqual, zipWithEqual, count ) import Outputable \end{code} @@ -37,12 +37,10 @@ floatInwards :: DynFlags -> [CoreBind] -> IO [CoreBind] floatInwards dflags binds = do { - beginPass dflags "Float inwards"; + showPass dflags "Float inwards"; let { binds' = map fi_top_bind binds }; - endPass dflags "Float inwards" - (dopt Opt_D_verbose_core2core dflags) + endPass dflags "Float inwards" Opt_D_verbose_core2core binds' {- no specific flag for dumping float-in -} - binds' } where @@ -181,16 +179,23 @@ So we treat lambda in groups, using the following rule: Otherwise drop all the bindings outside the group. \begin{code} -fiExpr to_drop (_, AnnLam b body) - = case collect [b] body of - (bndrs, real_body) - | all is_ok bndrs -> mkLams bndrs (fiExpr to_drop real_body) - | otherwise -> mkCoLets' to_drop (mkLams bndrs (fiExpr [] real_body)) - where - collect bs (_, AnnLam b body) = collect (b:bs) body - collect bs body = (reverse bs, body) + -- Hack alert! We only float in through one-shot lambdas, + -- not (as you might guess) through big lambdas. + -- Reason: we float *out* past big lambdas (see the test in the Lam + -- case of FloatOut.floatExpr) and we don't want to float straight + -- back in again. + -- + -- It *is* important to float into one-shot lambdas, however; + -- see the remarks with noFloatIntoRhs. +fiExpr to_drop lam@(_, AnnLam _ _) + | all is_one_shot bndrs -- Float in + = mkLams bndrs (fiExpr to_drop body) + + | otherwise -- Dump it all here + = mkCoLets' to_drop (mkLams bndrs (fiExpr [] body)) - is_ok bndr = isTyVar bndr || isOneShotLambda bndr + where + (bndrs, body) = collectAnnBndrs lam \end{code} We don't float lets inwards past an SCC. @@ -216,10 +221,8 @@ fiExpr to_drop (_, AnnNote note@(Coerce _ _) expr) = -- Just float in past coercion Note note (fiExpr to_drop expr) -fiExpr to_drop (_, AnnNote note@(TermUsg _) expr) - = -- Float in past term usage annotation - -- (for now; not sure if this is correct: KSW 1999-05) - Note note (fiExpr to_drop expr) +fiExpr to_drop (_, AnnNote note@(CoreNote _) expr) + = Note note (fiExpr to_drop expr) \end{code} For @Lets@, the possible ``drop points'' for the \tr{to_drop} @@ -270,7 +273,7 @@ fiExpr to_drop (_,AnnLet (AnnNonRec id rhs@(rhs_fvs, ann_rhs)) body) fiExpr to_drop (_,AnnLet (AnnRec bindings) body) = fiExpr new_to_drop body where - (binders, rhss) = unzip bindings + rhss = map snd bindings rhss_fvs = map freeVarsOf rhss body_fvs = freeVarsOf body @@ -342,7 +345,7 @@ fiExpr to_drop (_, AnnCase scrut case_bndr alts) fi_alt to_drop (con, args, rhs) = (con, args, fiExpr to_drop rhs) noFloatIntoRhs (AnnNote InlineMe _) = True -noFloatIntoRhs (AnnLam b _) = not (isId b && isOneShotLambda 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# @@ -352,7 +355,9 @@ noFloatIntoRhs (AnnLam b _) = not (isId b && isOneShotLambda b) -- boxing constructor into it, else we box it every time which is very bad -- news indeed. -noFloatIntoRhs rhs = exprIsValue (deAnnotate' rhs) -- We'd just float rigt back out again... +noFloatIntoRhs rhs = exprIsValue (deAnnotate' rhs) -- We'd just float right back out again... + +is_one_shot b = isId b && isOneShotBndr b \end{code} @@ -427,7 +432,7 @@ sepBindsByDropPoint is_case drop_pts floaters -- E -> ...not mentioning x... n_alts = length used_in_flags - n_used_alts = length [() | True <- used_in_flags] + n_used_alts = count id used_in_flags -- returns number of Trues in list. can_push = n_used_alts == 1 -- Used in just one branch || (is_case && -- We are looking at case alternatives