X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fstranal%2FDmdAnal.lhs;h=84c189e56bb74e2c9d2d85860253eca99f9c7f31;hb=262c142b90c94ca1aa577c950a6ceae1f255e2d6;hp=6adda66ed5ae6ed5e053454ac29684e2778685b3;hpb=c94408e522e5af3b79a5beadc7e6d15cee553ee7;p=ghc-hetmet.git diff --git a/compiler/stranal/DmdAnal.lhs b/compiler/stranal/DmdAnal.lhs index 6adda66..84c189e 100644 --- a/compiler/stranal/DmdAnal.lhs +++ b/compiler/stranal/DmdAnal.lhs @@ -43,11 +43,13 @@ import UniqFM ( plusUFM_C, addToUFM_Directly, lookupUFM_Directly, import Type ( isUnLiftedType, coreEqType, splitTyConApp_maybe ) import Coercion ( coercionKind ) import CoreLint ( showPass, endPass ) -import Util ( mapAndUnzip, mapAccumL, mapAccumR, lengthIs ) +import Util ( mapAndUnzip, lengthIs ) import BasicTypes ( Arity, TopLevelFlag(..), isTopLevel, isNeverActive, RecFlag(..), isRec ) import Maybes ( orElse, expectJust ) import Outputable + +import Data.List \end{code} To think about @@ -171,10 +173,9 @@ dmdAnal sigs dmd (Cast e co) (dmd_ty, e') = dmdAnal sigs dmd' e to_co = snd (coercionKind co) dmd' --- | Just (tc, args) <- splitTyConApp_maybe to_co - = evalDmd --- , isRecursiveTyCon tc = evalDmd --- | otherwise = dmd + | Just (tc, args) <- splitTyConApp_maybe to_co + , isRecursiveTyCon tc = evalDmd + | otherwise = dmd -- This coerce usually arises from a recursive -- newtype, and we don't want to look inside them -- for exactly the same reason that we don't look @@ -263,8 +264,8 @@ dmdAnal sigs dmd (Case scrut case_bndr ty [alt@(DataAlt dc,bndrs,rhs)]) -- The insight is, of course, that a demand on y is a demand on the -- scrutinee, so we need to `both` it with the scrut demand - scrut_dmd = Eval (Prod [idNewDemandInfo b | b <- bndrs', isId b]) - `both` + alt_dmd = Eval (Prod [idNewDemandInfo b | b <- bndrs', isId b]) + scrut_dmd = alt_dmd `both` idNewDemandInfo case_bndr' (scrut_ty, scrut') = dmdAnal sigs scrut_dmd scrut @@ -475,7 +476,27 @@ The thunk_cpr_ok stuff [CPR-AND-STRICTNESS] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the rhs is a thunk, we usually forget the CPR info, because it is presumably shared (else it would have been inlined, and -so we'd lose sharing if w/w'd it into a function. +so we'd lose sharing if w/w'd it into a function). E.g. + + let r = case expensive of + (a,b) -> (b,a) + in ... + +If we marked r as having the CPR property, then we'd w/w into + + let $wr = \() -> case expensive of + (a,b) -> (# b, a #) + r = case $wr () of + (# b,a #) -> (b,a) + in ... + +But now r is a thunk, which won't be inlined, so we are no further ahead. +But consider + + f x = let r = case expensive of (a,b) -> (b,a) + in if foo r then r else (x,x) + +Does f have the CPR property? Well, no. However, if the strictness analyser has figured out (in a previous iteration) that it's strict, then we DON'T need to forget the CPR info. @@ -972,7 +993,7 @@ lub d1@(Eval _) d2 = d2 `lub` d1 -- Bot,Abs,Top,Call,Defer lub (Box d1) (Box d2) = box (d1 `lub` d2) lub d1@(Box _) d2 = d2 `lub` d1 -lubs = zipWithDmds lub +lubs ds1 ds2 = zipWithDmds lub ds1 ds2 --------------------- -- box is the smart constructor for Box @@ -1079,7 +1100,7 @@ both d1@(Eval ds1) d2 = d2 `both` d1 both (Defer ds1) (Defer ds2) = deferEval (ds1 `boths` ds2) both d1@(Defer ds1) d2 = d2 `both` d1 -boths = zipWithDmds both +boths ds1 ds2 = zipWithDmds both ds1 ds2 \end{code}