X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FDemand.lhs;h=a038a23f6ac944046e361a56fa8344f19b223595;hb=52bd2cc7a9f328e6a7f3f50ac0055a5361f457c1;hp=cb45ddcd4ae558dd67b8ed90783a2d97bee03b58;hpb=4e7d56fde0f44d38bbb9a6fc72cf9c603264899d;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/Demand.lhs b/ghc/compiler/basicTypes/Demand.lhs index cb45ddc..a038a23 100644 --- a/ghc/compiler/basicTypes/Demand.lhs +++ b/ghc/compiler/basicTypes/Demand.lhs @@ -4,19 +4,30 @@ \section[Demand]{@Demand@: the amount of demand on a value} \begin{code} +#ifndef OLD_STRICTNESS +module Demand () where +#else + module Demand( Demand(..), - wwLazy, wwStrict, wwUnpackData, wwUnpackNew, wwPrim, wwEnum, + wwLazy, wwStrict, wwUnpack, wwPrim, wwEnum, isStrict, isLazy, isPrim, - pprDemands, seqDemand, seqDemands + pprDemands, seqDemand, seqDemands, + + StrictnessInfo(..), + mkStrictnessInfo, + noStrictnessInfo, + ppStrictnessInfo, seqStrictnessInfo, + isBottomingStrictness, appIsBottom, + ) where #include "HsVersions.h" -import BasicTypes ( NewOrData(..) ) import Outputable +import Util ( listLengthCmp ) \end{code} @@ -39,7 +50,6 @@ data Demand -- calling-convention magic) | WwUnpack -- Argument is strict & a single-constructor type - NewOrData Bool -- True <=> wrapper unpacks it; False <=> doesn't [Demand] -- Its constituent parts (whose StrictInfos -- are in the list) should be passed @@ -59,15 +69,14 @@ type MaybeAbsent = Bool -- True <=> not even used -- versions that don't worry about Absence: wwLazy = WwLazy False wwStrict = WwStrict -wwUnpackData xs = WwUnpack DataType False xs -wwUnpackNew x = WwUnpack NewType False [x] +wwUnpack xs = WwUnpack False xs wwPrim = WwPrim wwEnum = WwEnum seqDemand :: Demand -> () -seqDemand (WwLazy a) = a `seq` () -seqDemand (WwUnpack nd b ds) = nd `seq` b `seq` seqDemands ds -seqDemand other = () +seqDemand (WwLazy a) = a `seq` () +seqDemand (WwUnpack b ds) = b `seq` seqDemands ds +seqDemand other = () seqDemands [] = () seqDemands (d:ds) = seqDemand d `seq` seqDemands ds @@ -81,25 +90,18 @@ seqDemands (d:ds) = seqDemand d `seq` seqDemands ds %************************************************************************ \begin{code} +isLazy :: Demand -> Bool +isLazy (WwLazy _) = True +isLazy _ = False + isStrict :: Demand -> Bool -isStrict (WwUnpack NewType _ ds) = isStrict (head ds) -isStrict (WwUnpack other _ _) = True -isStrict WwStrict = True -isStrict WwEnum = True -isStrict WwPrim = True -isStrict _ = False +isStrict d = not (isLazy d) isPrim :: Demand -> Bool isPrim WwPrim = True isPrim other = False \end{code} -\begin{code} -isLazy :: Demand -> Bool -isLazy (WwLazy False) = True -- NB "Absent" args do *not* count! -isLazy _ = False -- (as they imply a worker) -\end{code} - %************************************************************************ %* * @@ -120,13 +122,9 @@ pprDemand (WwLazy True) = char 'A' pprDemand WwStrict = char 'S' pprDemand WwPrim = char 'P' pprDemand WwEnum = char 'E' -pprDemand (WwUnpack nd wu args) = char ch <> parens (hcat (map pprDemand args)) +pprDemand (WwUnpack wu args) = char ch <> parens (hcat (map pprDemand args)) where - ch = case nd of - DataType | wu -> 'U' - | otherwise -> 'u' - NewType | wu -> 'N' - | otherwise -> 'n' + ch = if wu then 'U' else 'u' instance Outputable Demand where ppr (WwLazy False) = empty @@ -134,49 +132,77 @@ instance Outputable Demand where instance Show Demand where showsPrec p d = showsPrecSDoc p (ppr d) + +-- Reading demands is done in Lex.lhs \end{code} +%************************************************************************ +%* * +\subsection[strictness-IdInfo]{Strictness info about an @Id@} +%* * +%************************************************************************ + +We specify the strictness of a function by giving information about +each of the ``wrapper's'' arguments (see the description about +worker/wrapper-style transformations in the PJ/Launchbury paper on +unboxed types). + +The list of @Demands@ specifies: (a)~the strictness properties of a +function's arguments; and (b)~the type signature of that worker (if it +exists); i.e. its calling convention. + +Note that the existence of a worker function is now denoted by the Id's +workerInfo field. + \begin{code} -{- ------------------- OMITTED NOW ------------------------------- - -- Reading demands is done in Lex.lhs - -- Also note that the (old) code here doesn't take proper - -- account of the 'B' suffix for bottoming functions +data StrictnessInfo + = NoStrictnessInfo -#ifdef REALLY_HASKELL_1_3 + | StrictnessInfo [Demand] -- Demands on the arguments. -instance Read Demand where - readList str = read_em [] str + Bool -- True <=> the function diverges regardless of its arguments + -- Useful for "error" and other disguised variants thereof. + -- BUT NB: f = \x y. error "urk" + -- will have info SI [SS] True + -- but still (f) and (f 2) are not bot; only (f 3 2) is bot + deriving( Eq ) -instance Show Demand where - showsPrec p d = showsPrecSDoc p (ppr d) + -- NOTA BENE: if the arg demands are, say, [S,L], this means that + -- (f bot) is not necy bot, only (f bot x) is bot + -- We simply cannot express accurately the strictness of a function + -- like f = \x -> case x of (a,b) -> \y -> ... + -- The up-side is that we don't need to restrict the strictness info + -- to the visible arity of the function. -#else +seqStrictnessInfo :: StrictnessInfo -> () +seqStrictnessInfo (StrictnessInfo ds b) = b `seq` seqDemands ds +seqStrictnessInfo other = () +\end{code} -instance Text Demand where - readList str = read_em [] str - showsPrec p d = showsPrecSDoc p (ppr d) -#endif - -readDemands :: String -> - -read_em acc ('L' : xs) = read_em (WwLazy False : acc) xs -read_em acc ('A' : xs) = read_em (WwLazy True : acc) xs -read_em acc ('S' : xs) = read_em (WwStrict : acc) xs -read_em acc ('P' : xs) = read_em (WwPrim : acc) xs -read_em acc ('E' : xs) = read_em (WwEnum : acc) xs -read_em acc (')' : xs) = [(reverse acc, xs)] -read_em acc ( 'U' : '(' : xs) = do_unpack DataType True acc xs -read_em acc ( 'u' : '(' : xs) = do_unpack DataType False acc xs -read_em acc ( 'N' : '(' : xs) = do_unpack NewType True acc xs -read_em acc ( 'n' : '(' : xs) = do_unpack NewType False acc xs -read_em acc rest = [(reverse acc, rest)] - -do_unpack new_or_data wrapper_unpacks acc xs - = case (read_em [] xs) of - [(stuff, rest)] -> read_em (WwUnpack new_or_data wrapper_unpacks stuff : acc) rest - _ -> pprPanic "Demand.do_unpack:" (ppr acc <+> dcolon <> text xs) - --------------------- END OF OMISSION ------------------------------ -} +\begin{code} +mkStrictnessInfo :: ([Demand], Bool) -> StrictnessInfo + +mkStrictnessInfo (xs, is_bot) + | all totally_boring xs && not is_bot = NoStrictnessInfo -- Uninteresting + | otherwise = StrictnessInfo xs is_bot + where + totally_boring (WwLazy False) = True + totally_boring other = False + +noStrictnessInfo = NoStrictnessInfo + +isBottomingStrictness (StrictnessInfo _ bot) = bot +isBottomingStrictness NoStrictnessInfo = False + +-- appIsBottom returns true if an application to n args would diverge +appIsBottom (StrictnessInfo ds bot) n = bot && (listLengthCmp ds n /=GT) -- not more than 'n' elts in 'ds'. +appIsBottom NoStrictnessInfo n = False + +ppStrictnessInfo NoStrictnessInfo = empty +ppStrictnessInfo (StrictnessInfo wrapper_args bot) = hsep [pprDemands wrapper_args bot] \end{code} +\begin{code} +#endif /* OLD_STRICTNESS */ +\end{code}