X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FbasicTypes%2FNewDemand.lhs;h=f69d2a457b27f8203628b8c32a644866cf772431;hb=be5c095aa51d360f4257b6eae1ebe23a7992a7c9;hp=6da4c470097cec8fb1b27deff33c3fd668ac3cc7;hpb=49c98d143c382a1341e1046f5ca00819a25691ba;p=ghc-hetmet.git diff --git a/compiler/basicTypes/NewDemand.lhs b/compiler/basicTypes/NewDemand.lhs index 6da4c47..f69d2a4 100644 --- a/compiler/basicTypes/NewDemand.lhs +++ b/compiler/basicTypes/NewDemand.lhs @@ -23,6 +23,8 @@ module NewDemand( pprIfaceStrictSig, appIsBottom, isBottomingSig, seqStrictSig, ) where +-- XXX This define is a bit of a hack, and should be done more nicely +#define FAST_STRING_NOT_NEEDED 1 #include "HsVersions.h" import StaticFlags @@ -62,14 +64,17 @@ data Demands = Poly Demand -- Polymorphic case | Prod [Demand] -- Product case deriving( Eq ) +allTop :: Demands -> Bool allTop (Poly d) = isTop d allTop (Prod ds) = all isTop ds +isTop :: Demand -> Bool isTop Top = True -isTop d = False +isTop _ = False +isAbsent :: Demand -> Bool isAbsent Abs = True -isAbsent d = False +isAbsent _ = False mapDmds :: (Demand -> Demand) -> Demands -> Demands mapDmds f (Poly d) = Poly (f d) @@ -80,9 +85,15 @@ zipWithDmds :: (Demand -> Demand -> Demand) zipWithDmds f (Poly d1) (Poly d2) = Poly (d1 `f` d2) zipWithDmds f (Prod ds1) (Poly d2) = Prod [d1 `f` d2 | d1 <- ds1] zipWithDmds f (Poly d1) (Prod ds2) = Prod [d1 `f` d2 | d2 <- ds2] -zipWithDmds f (Prod ds1) (Prod ds2) = Prod (zipWithEqual "zipWithDmds" f ds1 ds2) - -topDmd, lazyDmd, seqDmd :: Demand +zipWithDmds f (Prod ds1) (Prod ds2) + | length ds1 == length ds2 = Prod (zipWithEqual "zipWithDmds" f ds1 ds2) + | otherwise = Poly topDmd + -- This really can happen with polymorphism + -- \f. case f x of (a,b) -> ... + -- case f y of (a,b,c) -> ... + -- Here the two demands on f are C(LL) and C(LLL)! + +topDmd, lazyDmd, seqDmd, evalDmd, errDmd :: Demand topDmd = Top -- The most uninformative demand lazyDmd = Box Abs seqDmd = Eval (Poly Abs) -- Polymorphic seq demand @@ -94,7 +105,7 @@ isStrictDmd Bot = True isStrictDmd (Eval _) = True isStrictDmd (Call _) = True isStrictDmd (Box d) = isStrictDmd d -isStrictDmd other = False +isStrictDmd _ = False seqDemand :: Demand -> () seqDemand (Call d) = seqDemand d @@ -122,6 +133,7 @@ instance Outputable Demand where ppr (Box (Eval ds)) = char 'S' <> ppr ds ppr (Box Abs) = char 'L' ppr (Box Bot) = char 'X' + ppr d@(Box _) = pprPanic "ppr: Bad boxed demand" (ppr d) ppr (Call d) = char 'C' <> parens (ppr d) @@ -167,10 +179,12 @@ data DmdType = DmdType -- by making sure that everything uses TopRes instead of RetCPR -- Assuming, of course, that they don't mention RetCPR by name. -- They should onlyu use retCPR +retCPR :: DmdResult retCPR | opt_CprOff = TopRes | otherwise = RetCPR -seqDmdType (DmdType env ds res) = +seqDmdType :: DmdType -> () +seqDmdType (DmdType _env ds res) = {- ??? env `seq` -} seqDemandList ds `seq` res `seq` () type DmdEnv = VarEnv Demand @@ -204,8 +218,10 @@ instance Outputable DmdResult where ppr BotRes = char 'b' -- dddr -- without ambiguity +emptyDmdEnv :: VarEnv Demand emptyDmdEnv = emptyVarEnv +topDmdType, botDmdType, cprDmdType :: DmdType topDmdType = DmdType emptyDmdEnv [] TopRes botDmdType = DmdType emptyDmdEnv [] BotRes cprDmdType = DmdType emptyVarEnv [] retCPR @@ -213,11 +229,11 @@ cprDmdType = DmdType emptyVarEnv [] retCPR isTopDmdType :: DmdType -> Bool -- Only used on top-level types, hence the assert isTopDmdType (DmdType env [] TopRes) = ASSERT( isEmptyVarEnv env) True -isTopDmdType other = False +isTopDmdType _ = False isBotRes :: DmdResult -> Bool isBotRes BotRes = True -isBotRes other = False +isBotRes _ = False resTypeArgDmd :: DmdResult -> Demand -- TopRes and BotRes are polymorphic, so that @@ -233,7 +249,7 @@ resTypeArgDmd BotRes = Bot returnsCPR :: DmdResult -> Bool returnsCPR RetCPR = True -returnsCPR other = False +returnsCPR _ = False mkDmdType :: DmdEnv -> [Demand] -> DmdResult -> DmdType mkDmdType fv ds res = DmdType fv ds res @@ -293,6 +309,7 @@ mkStrictSig dmd_ty = StrictSig dmd_ty splitStrictSig :: StrictSig -> ([Demand], DmdResult) splitStrictSig (StrictSig (DmdType _ dmds res)) = (dmds, res) +isTopSig :: StrictSig -> Bool isTopSig (StrictSig ty) = isTopDmdType ty topSig, botSig, cprSig :: StrictSig @@ -302,12 +319,15 @@ cprSig = StrictSig cprDmdType -- appIsBottom returns true if an application to n args would diverge +appIsBottom :: StrictSig -> Int -> Bool appIsBottom (StrictSig (DmdType _ ds BotRes)) n = listLengthCmp ds n /= GT appIsBottom _ _ = False +isBottomingSig :: StrictSig -> Bool isBottomingSig (StrictSig (DmdType _ _ BotRes)) = True isBottomingSig _ = False +seqStrictSig :: StrictSig -> () seqStrictSig (StrictSig ty) = seqDmdType ty pprIfaceStrictSig :: StrictSig -> SDoc