[project @ 1997-05-19 00:10:59 by sof]
[ghc-hetmet.git] / ghc / compiler / simplCore / BinderInfo.lhs
index 43aa0bd..869bc1a 100644 (file)
@@ -14,9 +14,7 @@ module BinderInfo (
        BinderInfo(..),
        FunOrArg, DuplicationDanger, InsideSCC,  -- NB: all abstract (yay!)
 
-       inlineUnconditionally, okToInline,
-
-       addBinderInfo, orBinderInfo, 
+       addBinderInfo, orBinderInfo, andBinderInfo,
 
        argOccurrence, funOccurrence, dangerousArgOcc, noBinderInfo,
        markMany, markDangerousToDup, markInsideSCC,
@@ -28,9 +26,12 @@ module BinderInfo (
 
 IMP_Ubiq(){-uitous-}
 
-import CoreUnfold      ( FormSummary(..) )
 import Pretty
 import Util            ( panic )
+#if __GLASGOW_HASKELL__ >= 202
+import Outputable 
+#endif
+
 \end{code}
 
 The @BinderInfo@ describes how a variable is used in a given scope.
@@ -101,44 +102,23 @@ noBinderInfo = ManyOcc 0  -- A non-committal value
 \end{code}
 
 
-Predicates
-~~~~~~~~~~
 
 \begin{code}
-okToInline
-       :: FormSummary  -- What the thing to be inlined is like
-       -> BinderInfo   -- How the thing to be inlined occurs
-       -> Bool         -- True => it's small enough to inline
-       -> Bool         -- True => yes, inline it
-
--- Always inline bottoms
-okToInline BottomForm occ_info small_enough
-  = True       -- Unless one of the type args is unboxed??
-               -- This used to be checked for, but I can't
-               -- see why so I've left it out.
-
--- Non-WHNFs can be inlined if they occur once, or are small
-okToInline OtherForm (OneOcc _ _ _ n_alts _) small_enough | n_alts <= 1 = True
-okToInline OtherForm any_occ                small_enough               = small_enough
-
--- A WHNF can be inlined if it doesn't occur inside a lambda,
--- and occurs exactly once or 
---     occurs once in each branch of a case and is small
-okToInline form (OneOcc _ NoDupDanger _ n_alts _) small_enough 
-  = is_whnf_form form && 
-    (n_alts <= 1 || small_enough)
-  where
-    is_whnf_form VarForm   = True
-    is_whnf_form ValueForm = True
-    is_whnf_form other     = False
-
-okToInline form any_occ small_enough = False
+isFun :: FunOrArg -> Bool
+isFun FunOcc = True
+isFun _ = False
+
+isDupDanger :: DuplicationDanger -> Bool
+isDupDanger DupDanger = True
+isDupDanger _ = False
 \end{code}
 
 @inlineUnconditionally@ decides whether a let-bound thing can
 definitely be inlined.
 
 \begin{code}
+{-     NOT USED
+
 inlineUnconditionally :: Bool -> BinderInfo -> Bool
 
 --inlineUnconditionally ok_to_dup DeadCode = True
@@ -149,16 +129,7 @@ inlineUnconditionally ok_to_dup (OneOcc FunOcc NoDupDanger NotInsideSCC n_alt_oc
            -- damage, e.g., limit to M alternatives.
 
 inlineUnconditionally _ _ = False
-\end{code}
-
-\begin{code}
-isFun :: FunOrArg -> Bool
-isFun FunOcc = True
-isFun _ = False
-
-isDupDanger :: DuplicationDanger -> Bool
-isDupDanger DupDanger = True
-isDupDanger _ = False
+-}
 \end{code}
 
 
@@ -192,51 +163,85 @@ addBinderInfo, orBinderInfo
 addBinderInfo DeadCode info2 = info2
 addBinderInfo info1 DeadCode = info1
 addBinderInfo info1 info2
-       = ManyOcc (min (getBinderInfoArity info1) (getBinderInfoArity info2))
+ = case (min (getBinderInfoArity info1) (getBinderInfoArity info2)) of
+     (I# i#) -> ManyOcc (I# i#)
+      -- ManyOcc min (getBinderInfoArity info1) (getBinderInfoArity info2))
 
--- (orBinderInfo orig new) is used in two situations:
--- First, it combines occurrence info from branches of a case
---
--- Second, when a variable whose occurrence
---   info is currently "orig" is bound to a variable whose occurrence info is "new"
---     eg  (\new -> e) orig
---   What we want to do is to *worsen* orig's info to take account of new's
+-- (orBinderInfo orig new) is used when combining occurrence 
+-- info from branches of a case
 
 orBinderInfo DeadCode info2 = info2
 orBinderInfo info1 DeadCode = info1
 orBinderInfo (OneOcc posn1 dup1 scc1 n_alts1 ar_1)
-                     (OneOcc posn2 dup2 scc2 n_alts2 ar_2)
-  = OneOcc (combine_posns posn1 posn2)
-          (combine_dups  dup1  dup2)
-          (combine_sccs  scc1  scc2)
-          (n_alts1 + n_alts2)
-          (min ar_1 ar_2)
-  where
-    combine_dups DupDanger _ = DupDanger       -- Too paranoid?? ToDo
-    combine_dups _ DupDanger = DupDanger
-    combine_dups _ _        = NoDupDanger
-
-    combine_sccs InsideSCC _ = InsideSCC       -- Too paranoid?? ToDo
-    combine_sccs _ InsideSCC = InsideSCC
-    combine_sccs _ _        = NotInsideSCC
-
+            (OneOcc posn2 dup2 scc2 n_alts2 ar_2)
+  = let
+      -- Seriously maligned in order to make it stricter,
+      -- let's hope it is worth it..
+     posn = combine_posns posn1 posn2
+     scc  = combine_sccs  scc1  scc2
+     dup  = combine_dups  dup1  dup2
+     alts = n_alts1 + n_alts2
+     ar   = min ar_1 ar_2
+
+      -- No CSE, please!
+     cont1 = case scc  of { InsideSCC -> cont2; _ -> cont2 }
+     cont2 = case dup  of { DupDanger -> cont3; _ -> cont3 }
+     cont3 = case alts of { (I# 0#)   -> cont4; _ -> cont4 }
+     cont4 = case ar   of { (I# 0#)   -> cont5; _ -> cont5 }
+     cont5 = OneOcc posn dup scc alts ar
+    in
+    case posn of { FunOcc -> cont1; _ -> cont1 }
 orBinderInfo info1 info2
-       = ManyOcc (min (getBinderInfoArity info1) (getBinderInfoArity info2))
+ = case (min (getBinderInfoArity info1) (getBinderInfoArity info2)) of
+     (I# i#) -> ManyOcc (I# i#)
+
+-- (andBinderInfo orig new) is used in two situations:
+-- First, when a variable whose occurrence info
+--   is currently "orig" is bound to a variable whose occurrence info is "new"
+--     eg  (\new -> e) orig
+--   What we want to do is to *worsen* orig's info to take account of new's
+--
+-- second, when completing a let-binding
+--     let new = ...orig...
+-- we compute the way orig occurs in (...orig...), and then use orBinderInfo
+-- to worsen this info by the way new occurs in the let body; then we use
+-- that to worsen orig's currently recorded occurrence info.
+
+andBinderInfo DeadCode info2 = DeadCode
+andBinderInfo info1 DeadCode = DeadCode
+andBinderInfo (OneOcc posn1 dup1 scc1 (I# n_alts1#) (I# ar_1#))
+             (OneOcc posn2 dup2 scc2 (I# n_alts2#) ar_2)
+  = let
+      -- Perversly maligned in order to make it stricter.
+     posn = combine_posns posn1 posn2
+     scc  = combine_sccs  scc1  scc2
+     dup  = combine_dups  dup1  dup2
+     alts = I# (n_alts1# +# n_alts2#)
+
+      -- No CSE, please!
+     cont1 = case scc  of { InsideSCC -> cont2; _ -> cont2 }
+     cont2 = case dup  of { DupDanger -> cont3; _ -> cont3 }
+     cont3 = case alts of { (I# 0#) -> cont4;   _ -> cont4 }
+     cont4 = OneOcc posn dup scc alts (I# ar_1#)
+    in
+    case posn of {FunOcc -> cont1; _ -> cont1}
+
+andBinderInfo info1 info2 = 
+ case getBinderInfoArity info1 of
+   (I# i#) -> ManyOcc (I# i#)
+               --ManyOcc (getBinderInfoArity info1)
+
 
 combine_posns FunOcc FunOcc = FunOcc -- see comment at FunOrArg defn
 combine_posns _         _  = ArgOcc
 
-{-
-multiplyBinderInfo orig@(ManyOcc _) new
-  = ManyOcc (min (getBinderInfoArity orig) (getBinderInfoArity new))
+combine_dups DupDanger _ = DupDanger   -- Too paranoid?? ToDo
+combine_dups _ DupDanger = DupDanger
+combine_dups _ _            = NoDupDanger
 
-multiplyBinderInfo orig new@(ManyOcc _)
-  = ManyOcc (min (getBinderInfoArity orig) (getBinderInfoArity new))
-
-multiplyBinderInfo (OneOcc posn1 dup1 scc1 n_alts1 ar_1)
-                  (OneOcc posn2 dup2 scc2 n_alts2 ar_2)  
-  = OneOcc (combine_posns posn1 posn2) ???
--}
+combine_sccs InsideSCC _ = InsideSCC   -- Too paranoid?? ToDo
+combine_sccs _ InsideSCC = InsideSCC
+combine_sccs _ _            = NotInsideSCC
 
 setBinderInfoArityToZero :: BinderInfo -> BinderInfo
 setBinderInfoArityToZero DeadCode    = DeadCode
@@ -252,20 +257,20 @@ getBinderInfoArity (OneOcc _ _ _ _ i) = i
 
 \begin{code}
 instance Outputable BinderInfo where
-  ppr sty DeadCode     = ppStr "Dead"
-  ppr sty (ManyOcc ar) = ppBesides [ ppStr "Many-", ppInt ar ]
+  ppr sty DeadCode     = ptext SLIT("Dead")
+  ppr sty (ManyOcc ar) = hcat [ ptext SLIT("Many-"), int ar ]
   ppr sty (OneOcc posn dup_danger in_scc n_alts ar)
-    = ppBesides [ ppStr "One-", pp_posn posn, ppChar '-', pp_danger dup_danger,
-                 ppChar '-', pp_scc in_scc,  ppChar '-', ppInt n_alts,
-                 ppChar '-', ppInt ar ]
+    = hcat [ ptext SLIT("One-"), pp_posn posn, char '-', pp_danger dup_danger,
+                 char '-', pp_scc in_scc,  char '-', int n_alts,
+                 char '-', int ar ]
     where
-      pp_posn FunOcc = ppStr "fun"
-      pp_posn ArgOcc = ppStr "arg"
+      pp_posn FunOcc = ptext SLIT("fun")
+      pp_posn ArgOcc = ptext SLIT("arg")
 
-      pp_danger DupDanger   = ppStr "*dup*"
-      pp_danger NoDupDanger = ppStr "nodup"
+      pp_danger DupDanger   = ptext SLIT("*dup*")
+      pp_danger NoDupDanger = ptext SLIT("nodup")
 
-      pp_scc InsideSCC   = ppStr "*SCC*"
-      pp_scc NotInsideSCC = ppStr "noscc"
+      pp_scc InsideSCC   = ptext SLIT("*SCC*")
+      pp_scc NotInsideSCC = ptext SLIT("noscc")
 \end{code}