[project @ 1998-02-10 14:15:51 by simonpj]
[ghc-hetmet.git] / ghc / compiler / simplCore / SimplMonad.lhs
index 4855ede..f0645c9 100644 (file)
@@ -4,36 +4,37 @@
 \section[SimplMonad]{The simplifier Monad}
 
 \begin{code}
-#include "HsVersions.h"
-
 module SimplMonad (
-       SmplM(..),
+       SmplM,
        initSmpl, returnSmpl, thenSmpl, thenSmpl_,
        mapSmpl, mapAndUnzipSmpl,
 
        -- Counting
-       SimplCount{-abstract-}, TickType(..), tick, tickN,
+       SimplCount{-abstract-}, TickType(..), tick, tickN, tickUnfold,
        simplCount, detailedSimplCount,
        zeroSimplCount, showSimplCount, combineSimplCounts,
 
        -- Cloning
        cloneId, cloneIds, cloneTyVarSmpl, newIds, newId
-
-       -- and to make the interface self-sufficient...
     ) where
 
-import Ubiq{-uitous-}
+#include "HsVersions.h"
 
-import SmplLoop                -- well, cheating sort of
+-- import {-# SOURCE #-} Simplify
+-- import {-# SOURCE #-} MagicUFs
 
-import Id              ( mkSysLocal, mkIdWithNewUniq )
+import Id              ( GenId, mkSysLocal, mkIdWithNewUniq, Id )
+import CoreUnfold      ( SimpleUnfolding )
 import SimplEnv
-import SrcLoc          ( mkUnknownSrcLoc )
-import TyVar           ( cloneTyVar )
+import SrcLoc          ( noSrcLoc )
+import TyVar           ( cloneTyVar, TyVar )
+import Type             ( Type )
 import UniqSupply      ( getUnique, getUniques, splitUniqSupply,
                          UniqSupply
                        )
-import Util            ( zipWithEqual, panic )
+import Util            ( zipWithEqual, Eager, appEager )
+import Outputable
+import Ix
 
 infixr 9  `thenSmpl`, `thenSmpl_`
 \end{code}
@@ -114,6 +115,11 @@ a mutable array through @SimplM@.
 data SimplCount
   = SimplCount FAST_INT            -- number of ticks
                [(TickType, Int)]   -- assoc list of all diff kinds of ticks
+               UnfoldingHistory
+
+type UnfoldingHistory = (Int,          -- N
+                        [(Id,Int)],    -- Last N unfoldings
+                        [(Id,Int)])    -- The MaxUnfoldHistory unfoldings before that
 
 data TickType
   = UnfoldingDone    | MagicUnfold     | ConReused
@@ -127,6 +133,7 @@ data TickType
   | CaseOfError
   | TyBetaReduction
   | BetaReduction
+  | SpecialisationDone
   {- BEGIN F/B ENTRIES -}
   -- the 8 rules
   | FoldrBuild         -- foldr f z (build g) ==>
@@ -142,9 +149,9 @@ data TickType
   | Foldr_Cons_Nil     -- foldr (:) [] => id
   | Foldr_Cons         -- foldr (:) => flip (++)
 
-  | Str_FoldrStr       -- foldr f z "hello" => unpackFoldrPS# f z "hello"
-  | Str_UnpackCons     -- unpackFoldrPS# (:) z "hello" => unpackAppendPS# z "hello"
-  | Str_UnpackNil      -- unpackAppendPS# [] "hello" => "hello"
+  | Str_FoldrStr       -- foldr f z "hello" => unpackFoldrPS__ f z "hello"
+  | Str_UnpackCons     -- unpackFoldrPS# (:) z "hello" => unpackAppendPS__ z "hello"
+  | Str_UnpackNil      -- unpackAppendPS__ [] "hello" => "hello"
   {- END F/B ENTRIES -}
   deriving (Eq, Ord, Ix)
 
@@ -166,6 +173,9 @@ instance Text TickType where
     showsPrec p CaseOfError    = showString "CaseOfError      "
     showsPrec p TyBetaReduction        = showString "TyBetaReduction  "
     showsPrec p BetaReduction  = showString "BetaReduction    "
+    showsPrec p SpecialisationDone 
+                               = showString "Specialisation   "
+
        -- Foldr/Build Stuff:
     showsPrec p FoldrBuild     = showString "FoldrBuild       "
     showsPrec p FoldrAugment   = showString "FoldrAugment     "
@@ -186,8 +196,8 @@ instance Text TickType where
 
 showSimplCount :: SimplCount -> String
 
-showSimplCount (SimplCount _ stuff)
-  = shw stuff
+showSimplCount (SimplCount _ stuff (_, unf1, unf2))
+  = shw stuff ++ "\nMost recent unfoldings: " ++ showSDoc (ppr (reverse unf2 ++ reverse unf1))
   where
     shw []         = ""
     shw ((t,n):tns) | n /= 0   = show t ++ ('\t' : show n) ++ ('\n' : shw tns)
@@ -195,7 +205,9 @@ showSimplCount (SimplCount _ stuff)
 
 zeroSimplCount :: SimplCount
 zeroSimplCount
-  = SimplCount ILIT(0)
+  = SimplCount ILIT(0) stuff (0, [], [])
+  where
+    stuff =
       [ (UnfoldingDone, 0),
        (MagicUnfold, 0),
        (ConReused, 0),
@@ -213,6 +225,7 @@ zeroSimplCount
        (CaseOfError, 0),
        (TyBetaReduction,0),
        (BetaReduction,0),
+       (SpecialisationDone,0),
        -- Foldr/Build Stuff:
        (FoldrBuild, 0),
        (FoldrAugment, 0),
@@ -237,48 +250,68 @@ Counting-related monad functions:
 \begin{code}
 tick :: TickType -> SmplM ()
 
-tick tick_type us (SimplCount n stuff)
-  = ((), SimplCount (n _ADD_ ILIT(1))
+tick tick_type us (SimplCount n stuff unf)
+  = -- pprTrace "Tick: " (text (show tick_type)) $
 #ifdef OMIT_SIMPL_COUNTS
-                   stuff -- don't change anything
+    ((), SimplCount (n _ADD_ ILIT(1) stuff unf))                   stuff -- don't change anything
 #else
-                   (inc_tick stuff)
+    new_stuff `seqL`
+    ((), SimplCount (n _ADD_ ILIT(1)) new_stuff unf)
+  where
+    new_stuff = inc_tick tick_type ILIT(1) stuff
 #endif
-    )
+
+maxUnfoldHistory :: Int
+maxUnfoldHistory = 20
+
+tickUnfold :: Id -> SmplM ()
+tickUnfold id us (SimplCount n stuff (n_unf, unf1, unf2))
+  = -- pprTrace "Unfolding: " (ppr id) $
+    new_stuff `seqL`
+    new_unf   `seqTriple`
+    ((), SimplCount (n _ADD_ ILIT(1)) new_stuff new_unf)
   where
-    inc_tick [] = panic "couldn't inc_tick!"
-    inc_tick (x@(ttype, cnt) : xs)
-      = if ttype == tick_type then
-           let
-               incd = cnt + 1
-           in
-           (ttype, incd) : xs
-       else
-           x : inc_tick xs
+     new_stuff = inc_tick UnfoldingDone ILIT(1) stuff
+
+     new_unf | n_unf >= maxUnfoldHistory = (1, [unf_item], unf1)
+            | otherwise                 = (n_unf+1, unf_item:unf1, unf2)
+            
+     unf_item = (id, IBOX(n))
+
+
+    -- force list to avoid getting a chain of @inc_tick@ applications
+    -- building up on the heap. (Only true when not dumping stats).
+seqL []    y = y
+seqL (_:_) y = y
+
+seqTriple (_,_,_) y = y
 
 tickN :: TickType -> Int -> SmplM ()
 
-tickN tick_type IBOX(increment) us (SimplCount n stuff)
-  = ((), SimplCount (n _ADD_ increment)
+tickN tick_type 0 us counts 
+  = ((), counts)
+tickN tick_type IBOX(increment) us (SimplCount n stuff unf)
+  = -- pprTrace "Tick: " (text (show tick_type)) $
 #ifdef OMIT_SIMPL_COUNTS
-                   stuff -- don't change anything
+    ((), SimplCount (n _ADD_ increment) stuff) -- don't change anything
 #else
-                   (inc_tick stuff)
+    new_stuff  `seqL`
+    ((), SimplCount (n _ADD_ increment) new_stuff unf)
+  where   
+    new_stuff = inc_tick tick_type increment stuff
+
+
+inc_tick tick_type n [] = panic "couldn't inc_tick!"
+
+inc_tick tick_type n (x@(ttype, I# cnt#) : xs)
+  | ttype == tick_type = case cnt# +# n of
+                             incd -> (ttype,IBOX(incd)) : xs
+
+  | otherwise         = case inc_tick tick_type n xs of { [] -> [x]; ls -> x:ls }
 #endif
-    )
-  where
-    inc_tick [] = panic "couldn't inc_tick!"
-    inc_tick (x@(ttype, cnt) : xs)
-      = if ttype == tick_type then
-           let
-               incd = cnt + IBOX(increment)
-           in
-           (ttype, incd) : xs
-       else
-           x : inc_tick xs
 
 simplCount :: SmplM Int
-simplCount us sc@(SimplCount n _) = (IBOX(n), sc)
+simplCount us sc@(SimplCount n _ _) = (IBOX(n), sc)
 
 detailedSimplCount :: SmplM SimplCount
 detailedSimplCount us sc = (sc, sc)
@@ -286,13 +319,16 @@ detailedSimplCount us sc = (sc, sc)
 combineSimplCounts :: SimplCount -> SimplCount -> SimplCount
 
 #ifdef OMIT_SIMPL_COUNTS
-combineSimplCounts (SimplCount n1 stuff1) (SimplCount n2 stuff2)
+combineSimplCounts (SimplCount n1 stuff1 unf1) (SimplCount n2 stuff2 unf2)
   = SimplCount (n1 _ADD_ n2)
-              stuff1 -- just pick one
+              stuff2 -- just pick one
+              unf2
 #else
-combineSimplCounts (SimplCount n1 stuff1) (SimplCount n2 stuff2)
-  = SimplCount (n1 _ADD_ n2)
-              (zipWithEqual "combineSimplCounts" (\ (t1,c1) (t2,c2) -> (t1,c1+c2)) stuff1 stuff2)
+combineSimplCounts (SimplCount n1 stuff1 unf1) (SimplCount n2 stuff2 unf2)
+  = new_stuff `seqL`
+    SimplCount (n1 _ADD_ n2) new_stuff unf2    -- Just pick the second for unfold history
+  where
+    new_stuff = zipWithEqual "combineSimplCounts" (\ (t1,c1) (t2,c2) -> (t1,c1+c2)) stuff1 stuff2
 #endif
 \end{code}
 
@@ -305,7 +341,7 @@ combineSimplCounts (SimplCount n1 stuff1) (SimplCount n2 stuff2)
 \begin{code}
 newId :: Type -> SmplM Id
 newId ty us sc
-  = (mkSysLocal SLIT("s") uniq ty mkUnknownSrcLoc, sc)
+  = (mkSysLocal SLIT("s") uniq ty noSrcLoc, sc)
   where
     uniq = getUnique us
 
@@ -314,7 +350,7 @@ newIds tys us sc
   = (zipWithEqual "newIds" mk_id tys uniqs, sc)
   where
     uniqs  = getUniques (length tys) us
-    mk_id ty uniq = mkSysLocal SLIT("s") uniq ty mkUnknownSrcLoc
+    mk_id ty uniq = mkSysLocal SLIT("s") uniq ty noSrcLoc
 
 cloneTyVarSmpl :: TyVar -> SmplM TyVar
 
@@ -326,9 +362,9 @@ cloneTyVarSmpl tyvar us sc
 
 cloneId :: SimplEnv -> InBinder -> SmplM OutId
 cloneId env (id,_) us sc
-  = (mkIdWithNewUniq id_with_new_ty uniq, sc)
+  = simplTyInId env id `appEager` \ id_with_new_ty ->
+    (mkIdWithNewUniq id_with_new_ty uniq, sc)
   where
-    id_with_new_ty = simplTyInId env id
     uniq = getUnique us
 
 cloneIds :: SimplEnv -> [InBinder] -> SmplM [OutId]