Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : supercompiler

http://hackage.haskell.org/trac/ghc/changeset/4a911d725946061ee7765d78d3e9c43e45695b64

>---------------------------------------------------------------

commit 4a911d725946061ee7765d78d3e9c43e45695b64
Author: Max Bolingbroke <batterseapo...@hotmail.com>
Date:   Tue Oct 23 17:59:27 2012 +0100

    Fix problems with preinit eta expansion: no gc-destroyed free vars, no dead 
var occs

>---------------------------------------------------------------

 .../supercompile/Supercompile/Drive/Process.hs     |   51 ++++++++++++--------
 1 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/compiler/supercompile/Supercompile/Drive/Process.hs 
b/compiler/supercompile/Supercompile/Drive/Process.hs
index e8bcf28..01b0627 100644
--- a/compiler/supercompile/Supercompile/Drive/Process.hs
+++ b/compiler/supercompile/Supercompile/Drive/Process.hs
@@ -48,7 +48,7 @@ import Supercompile.StaticFlags
 import Supercompile.Utilities hiding (Monad(..))
 
 import Var        (isTyVar, isId, tyVarKind, varType, setVarType)
-import Id         (idType, zapFragileIdInfo, localiseId, isDictId, isGlobalId)
+import Id         (idType, zapIdOccInfo, zapFragileIdInfo, localiseId, 
isDictId, isGlobalId)
 import MkId       (voidArgId, realWorldPrimId, mkPrimOpId)
 import Coercion   (Coercion(..), isCoVar, mkCoVarCo, mkUnsafeCo, coVarKind)
 import TyCon      (PrimRep(..))
@@ -402,10 +402,10 @@ prepareTerm unfoldings e = {-# SCC "prepareTerm" #-}
         
         -- FIXME: update other comments about memocache preinit
         -- We can and should do memocache preinit even if we still use 
"let"-bindings in the heap with associated terms
-        letty_preinit_with = [(gc (normalise (maxBound, heap', Loco False, 
anned_e')), accessor_e)
+        letty_preinit_with = [ res
                              | (x', hb) <- M.toList h''_binds_globalid
                              , Just in_e_def <- [heapBindingTerm hb]
-                             , (heap', accessor_e, anned_e') <- eta heap (var 
x') in_e_def (annedTerm (annedTag (snd in_e_def)) (Var x'))]
+                             , res <- eta [] heap (var x') in_e_def (annedTerm 
(annedTag (snd in_e_def)) (Var x'))]
         
         -- When doing memocache preinitialization, we don't want to include in 
the final heap any binding originating
         -- from evaluating the top-level that cannot be proven to be a value, 
or else we risk work duplication
@@ -418,9 +418,9 @@ prepareTerm unfoldings e = {-# SCC "prepareTerm" #-}
         preinit_heap = Heap (preinit_h_avail `M.union` h_fvs) ids'
 
         -- NB: we assume that unfoldings are guaranteed to be cheap and hence 
duplicatiable. I think this is reasonable.
-        preinit_with = [(gc (normalise (maxBound, heap', Loco False, 
anned_e')), accessor_e)
+        preinit_with = [ res
                        | (x', in_e_def) <- h_unfoldings
-                       , (heap', accessor_e, anned_e') <- eta preinit_heap 
(var x') in_e_def (annedTerm (annedTag (snd in_e_def)) (Var x'))]
+                       , res <- eta [] preinit_heap (var x') in_e_def 
(annedTerm (annedTag (snd in_e_def)) (Var x'))]
 
         -- FIXME: instead of adding unfoldings as Let, (in order to sidestep 
the bug where Let stuff will be underspecialised)
         -- we should add it them as normal bindings but pre-initialise the 
memo cache. Of course this will be bad in the case
@@ -455,22 +455,28 @@ prepareTerm unfoldings e = {-# SCC "prepareTerm" #-}
 --
 -- NB: given an unfolding (f = \x y -> e) will return memo entries for all the 
states (\x y -> e), (\y -> e), e, f, (f x) and (f x y).
 -- Because we do not reduce before matching, both are necessary!
-eta :: Heap -> FVedTerm -> In AnnedTerm -> AnnedTerm -> [(Heap, FVedTerm, In 
AnnedTerm)]
-eta heap tieback_e1 in_e_def e_call = (heap, tieback_e1, in_e_def) : (heap, 
tieback_e1, renamedTerm e_call) : case normalise (maxBound, heap, Loco False, 
in_e_def) of
-  (_, Heap h ids, k, anned_qa)
-    | Answer (rn, v) <- extract anned_qa
-    , Just a_cast <- isCastStack_maybe k
-    , let tieback_e2 = case a_cast of
-            Uncast      -> tieback_e1
-            CastBy co _ -> tieback_e1 `cast` mkSymCo ids co
-          mb_res@(~(Just (_, x, _, _))) = case v of
-             Lambda   x e_def_body -> Just (tieback_e2 `app`   x',           
x, e_def_body, annedTerm (annedTag e_def_body) (e_call `App`   x'))
-             TyLambda a e_def_body -> Just (tieback_e2 `tyApp` mkTyVarTy x', 
a, e_def_body, annedTerm (annedTag e_def_body) (e_call `TyApp` mkTyVarTy x'))
-             _                     -> Nothing
-          (ids', rn', x') = renameNonRecBinder ids rn x
-    , Just (tieback_e2, _, e_def_body, e_call_body) <- mb_res
-    -> eta (Heap (M.insert x' lambdaBound h) ids') tieback_e2 (rn', 
e_def_body) e_call_body
-  _ -> []
+eta :: [Var] -> Heap -> FVedTerm -> In AnnedTerm -> AnnedTerm -> [(State, 
FVedTerm)]
+eta xs' heap tieback_e1 in_e_def e_call1 = res in_e_def : res (renamedTerm 
e_call1) : case normalise (maxBound, heap, Loco False, in_e_def) of
+    (_, Heap h ids, k, anned_qa)
+      | Answer (rn, v) <- extract anned_qa
+      , Just a_cast <- isCastStack_maybe k
+      , let (tieback_e2, e_call2) = case a_cast of
+              Uncast       -> (tieback_e1,               e_call1)
+              CastBy co tg -> (tieback_e1 `cast` sym_co, annedTerm tg (e_call1 
`Cast` sym_co))
+                where sym_co = mkSymCo ids co
+            mb_res@(~(Just (_, x, _, _))) = case v of
+               -- NB: must zap binder occ info in case it is marked as dead, 
we can't mark the occurrence site we use for the fulfilment as dead!
+               Lambda   x e_def_body -> Just (tieback_e2 `app`   x',           
zapIdOccInfo x, e_def_body, annedTerm (annedTag e_def_body) (e_call2 `App`   
x'))
+               TyLambda a e_def_body -> Just (tieback_e2 `tyApp` mkTyVarTy x', 
a,              e_def_body, annedTerm (annedTag e_def_body) (e_call2 `TyApp` 
mkTyVarTy x'))
+               _                     -> Nothing
+            (ids', rn', x') = renameNonRecBinder ids rn x
+      , Just (tieback_e2, _, e_def_body, e_call_body) <- mb_res
+      -> eta (x':xs') (Heap (M.insert x' lambdaBound h) ids') tieback_e2 (rn', 
e_def_body) e_call_body
+    _ -> []
+  where res anned_e' = (case gc (normalise (maxBound, heap, Loco False, 
anned_e')) of (steps, Heap h ids, k, in_e') -> (steps, Heap (foldr (\x' -> 
M.insert x' lambdaBound) h xs') ids, k, in_e'), tieback_e1)
+          -- NB: have to add the xs' back into the State after GC because some 
lambdaBounds from eta-expansion
+          -- might not referenced in the body of the expanded lambda, but WILL 
referenced from the
+          -- application to x' that we use to fulfill, in which case gcing 
would leave some variables free in that tieback!
 
 -- FIXME: broken right now because we need to rewrite free variables within 
binders as well (i.e. rules, specialisations etc). Very tedious!
 {-# INLINE rewriteGlobals #-}
@@ -918,6 +924,9 @@ data AbsVar = AbsVar {
     absVarVar :: Var    -- ^ The 'Var' itself
   }
 
+instance Outputable AbsVar where
+    ppr x = ppr (absVarVar x) <+> (if absVarDead x then text "(dead)" else 
empty)
+
 mkLiveAbsVar :: Var -> AbsVar
 mkLiveAbsVar x = AbsVar { absVarDead = False, absVarVar = x }
 



_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to