[project @ 2001-06-25 14:36:04 by simonpj]
[ghc-hetmet.git] / ghc / compiler / stranal / SaAbsInt.lhs
index 3c7dfb5..e413b48 100644 (file)
@@ -17,16 +17,16 @@ module SaAbsInt (
 
 import CmdLineOpts     ( opt_AllStrict, opt_NumbersStrict )
 import CoreSyn
-import CoreUnfold      ( Unfolding, maybeUnfoldingTemplate )
-import Id              ( Id, idType, idArity, idStrictness, idUnfolding, isDataConId_maybe )
+import CoreUnfold      ( maybeUnfoldingTemplate )
+import Id              ( Id, idType, idStrictness, idUnfolding, isDataConId_maybe )
 import DataCon         ( dataConTyCon, splitProductType_maybe, dataConRepArgTys )
 import IdInfo          ( StrictnessInfo(..) )
-import Demand          ( Demand(..), wwPrim, wwStrict, wwEnum, wwUnpackData, wwLazy,
-                         wwUnpackNew )
+import Demand          ( Demand(..), wwPrim, wwStrict, wwUnpack, wwLazy,
+                         mkStrictnessInfo, isLazy
+                       )
 import SaLib
-import TyCon           ( isProductTyCon, isRecursiveTyCon, isEnumerationTyCon, isNewTyCon )
-import BasicTypes      ( Arity, NewOrData(..) )
-import Type            ( splitAlgTyConApp_maybe, 
+import TyCon           ( isProductTyCon, isRecursiveTyCon )
+import Type            ( splitTyConApp_maybe, 
                          isUnLiftedType, Type )
 import TyCon           ( tyConUnique )
 import PrelInfo                ( numericTyKeys )
@@ -284,10 +284,7 @@ evalStrictness (WwLazy _) _   = False
 evalStrictness WwStrict   val = isBot val
 evalStrictness WwEnum    val = isBot val
 
-evalStrictness (WwUnpack NewType _ (demand:_)) val
-  = evalStrictness demand val
-
-evalStrictness (WwUnpack DataType _ demand_info) val
+evalStrictness (WwUnpack _ demand_info) val
   = case val of
       AbsTop      -> False
       AbsBot      -> True
@@ -312,10 +309,7 @@ possibly} hit poison.
 evalAbsence (WwLazy True) _ = False    -- Can't possibly hit poison
                                        -- with Absent demand
 
-evalAbsence (WwUnpack NewType _ (demand:_)) val
-  = evalAbsence demand val
-
-evalAbsence (WwUnpack DataType _ demand_info) val
+evalAbsence (WwUnpack _ demand_info) val
   = case val of
        AbsTop       -> False           -- No poison in here
        AbsBot       -> True            -- Pure poison
@@ -571,7 +565,8 @@ absApply AbsAnal (AbsApproxFun (d:ds) val) arg
                other -> AbsApproxFun ds val
 
 #ifdef DEBUG
-absApply anal f@(AbsProd _)       arg = pprPanic ("absApply: Duff function: AbsProd." ++ show anal) ((ppr f) <+> (ppr arg))
+absApply anal f@(AbsProd _) arg 
+  = pprPanic ("absApply: Duff function: AbsProd." ++ show anal) ((ppr f) <+> (ppr arg))
 #endif
 \end{code}
 
@@ -601,9 +596,11 @@ findStrictness id (AbsApproxFun str_ds str_res) (AbsApproxFun abs_ds _)
        -- HOWEVER, if we make diverging functions appear lazy, they
        -- don't get wrappers, and then we get dreadful reboxing.
        -- See notes with WwLib.worthSplitting
-  = StrictnessInfo (combineDemands id str_ds abs_ds) (isBot str_res)
+  = find_strictness id str_ds str_res abs_ds
 
-findStrictness id str_val abs_val = NoStrictnessInfo
+findStrictness id str_val abs_val 
+  | isBot str_val = mkStrictnessInfo ([], True)
+  | otherwise     = NoStrictnessInfo
 
 -- The list of absence demands passed to combineDemands 
 -- can be shorter than the list of absence demands
@@ -615,16 +612,22 @@ findStrictness id str_val abs_val = NoStrictnessInfo
 -- Here the strictness value takes three args, but the absence value
 -- takes only one, for reasons I don't quite understand (see cheapFixpoint)
 
-combineDemands id orig_str_ds orig_abs_ds
-  = go orig_str_ds orig_abs_ds 
+find_strictness id orig_str_ds orig_str_res orig_abs_ds
+  = mkStrictnessInfo (go orig_str_ds orig_abs_ds, res_bot)
   where
+    res_bot = isBot orig_str_res
+
     go str_ds abs_ds = zipWith mk_dmd str_ds (abs_ds ++ repeat wwLazy)
 
-    mk_dmd str_dmd (WwLazy True) = WARN( case str_dmd of { WwLazy _ -> False; other -> True },
-                                        ppr id <+> ppr orig_str_ds <+> ppr orig_abs_ds )
-                                  WwLazy True  -- Best of all
-    mk_dmd (WwUnpack nd u str_ds) 
-          (WwUnpack _ _ abs_ds) = WwUnpack nd u (go str_ds abs_ds)
+    mk_dmd str_dmd (WwLazy True)
+        = WARN( not (res_bot || isLazy str_dmd),
+                ppr id <+> ppr orig_str_ds <+> ppr orig_abs_ds )
+               -- If the arg isn't used we jolly well don't expect the function
+               -- to be strict in it.  Unless the function diverges.
+          WwLazy True  -- Best of all
+
+    mk_dmd (WwUnpack u str_ds) 
+          (WwUnpack _ abs_ds) = WwUnpack u (go str_ds abs_ds)
 
     mk_dmd str_dmd abs_dmd = str_dmd
 \end{code}
@@ -703,19 +706,15 @@ findRecDemand str_fn abs_fn ty
                                -- we don't exploit it yet, so don't bother
 
         Just (tycon,_,data_con,cmpnt_tys)      -- Single constructor case
-          | isNewTyCon tycon                   -- A newtype!
-          ->   ASSERT( null (tail cmpnt_tys) )
-               let
-                   demand = findRecDemand str_fn abs_fn (head cmpnt_tys)
-               in
-               wwUnpackNew demand
+          | isRecursiveTyCon tycon             -- Recursive data type; don't unpack
+          ->   wwStrict                        --      (this applies to newtypes too:
+                                               --      e.g.  data Void = MkVoid Void)
 
           |  null compt_strict_infos           -- A nullary data type
-          || isRecursiveTyCon tycon            -- Recursive data type; don't unpack
           ->   wwStrict
 
           | otherwise                          -- Some other data type
-          ->   wwUnpackData compt_strict_infos
+          ->   wwUnpack compt_strict_infos
 
           where
              prod_len = length cmpnt_tys
@@ -732,12 +731,9 @@ findRecDemand str_fn abs_fn ty
 
   where
     is_numeric_type ty
-      = case (splitAlgTyConApp_maybe ty) of -- NB: duplicates stuff done above
-         Nothing -> False
-         Just (tycon, _, _)
-           | tyConUnique tycon `is_elem` numericTyKeys
-           -> True
-         _{-something else-} -> False
+      = case (splitTyConApp_maybe ty) of -- NB: duplicates stuff done above
+         Nothing         -> False
+         Just (tycon, _) -> tyConUnique tycon `is_elem` numericTyKeys
       where
        is_elem = isIn "is_numeric_type"
 
@@ -809,19 +805,6 @@ cheapFixpoint anal ids rhss env
          AbsAnal -> AbsBot
 \end{code}
 
-\begin{verbatim}
-mkLookupFun :: (key -> key -> Bool)    -- Equality predicate
-           -> (key -> key -> Bool)     -- Less-than predicate
-           -> [(key,val)]              -- The assoc list
-           -> key                      -- The key
-           -> Maybe val                -- The corresponding value
-
-mkLookupFun eq lt alist s
-  = case [a | (s',a) <- alist, s' `eq` s] of
-      []    -> Nothing
-      (a:_) -> Just a
-\end{verbatim}
-
 \begin{code}
 fixpoint :: AnalysisKind -> [Id] -> [CoreExpr] -> AbsValEnv -> [AbsVal]