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

On branch  : supercompiler

http://hackage.haskell.org/trac/ghc/changeset/ab79ca3f1b96863f5a9e8b24c407018c3eaa9a27

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

commit ab79ca3f1b96863f5a9e8b24c407018c3eaa9a27
Author: Max Bolingbroke <batterseapo...@hotmail.com>
Date:   Wed Apr 18 17:10:48 2012 +0100

    Pick up free variables of FV unfoldings correctly when constructing heap

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

 .../supercompile/Supercompile/Drive/Process.hs     |   31 +++++++++++++++++--
 1 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/compiler/supercompile/Supercompile/Drive/Process.hs 
b/compiler/supercompile/Supercompile/Drive/Process.hs
index 0d7cbaa..92cc0ea 100644
--- a/compiler/supercompile/Supercompile/Drive/Process.hs
+++ b/compiler/supercompile/Supercompile/Drive/Process.hs
@@ -306,10 +306,33 @@ prepareTerm unfoldings e = {-# SCC "prepareTerm" #-}
                           anned_e = toAnnedTerm tag_unf_ids e
                           input_fvs'' = input_fvs' `unionVarSet` 
varBndrFreeVars x' `unionVarSet` annedFreeVars anned_e
         
-        -- NB: foldVarSet is a right fold, so this use of fromDistinctAscList 
is justified
-        h_fvs = M.fromDistinctAscList $ snd $ foldToMapAccumL foldVarSet 
add_one_fv tag_ids2 input_fvs
-          where add_one_fv tag_ids2 x' = (tag_ids3, (x', environmentallyBound 
(mkTag (getKey i))))
-                    where !(i, tag_ids3) = takeUniqFromSupply tag_ids2
+        -- A funny thing can happen here. We can have an unfolding like foo:
+        --  foo = Just bar
+        -- Which mentions a variable bar which (when used as a *binder*, not 
an *occurrence*) would
+        -- have free variables, like:
+        --  {-# INLINE bar #-}
+        --  bar = .. bar .. baz
+        -- But we might not necessarily have a bar binding in the unfoldings. 
So we might end up
+        -- adding an environmentallyBound binding for bar to h_fvs which then 
has an unbound free
+        -- variable baz. This would violate our heap invariant!
+        --
+        -- My solution is to make the construction of h_fvs into a fixed point 
where the set of
+        -- variables to make environmentally bound grows until it encompasses 
all the FVs of those
+        -- variables themselves.
+        --
+        -- I think it would also be OK to zap the IdInfo of environmentally 
bound stuff, but that isn't
+        -- optimal because the simplifier won't be able to restore the IdInfo 
of *global* Ids, so we might
+        -- pessimisize all later simplifications.
+        h_fvs = go tag_ids2 emptyVarSet input_fvs
+          where
+            go tag_ids all_input_fvs these_fvs
+              | M.null h_these_binds = M.empty
+              | otherwise            = h_these_binds `M.union` go tag_ids' 
(all_input_fvs `unionVarSet` these_fvs) these_fvs'
+              where -- NB: foldVarSet is a right fold, so this use of 
fromDistinctAscList is justified
+                    ((these_fvs', tag_ids'), h_these_binds) = second 
M.fromDistinctAscList $ foldToMapAccumL foldVarSet add_one_fv (emptyVarSet, 
tag_ids) (these_fvs `minusVarSet` all_input_fvs)
+            add_one_fv (these_fvs, tag_ids) x' = ((these_fvs', tag_ids'), (x', 
environmentallyBound (mkTag (getKey i))))
+              where !(i, tag_ids') = takeUniqFromSupply tag_ids
+                    these_fvs' = these_fvs `unionVarSet` varBndrFreeVars x'
 
         unfolding_bvs = S.fromDistinctAscList (map fst h_unfoldings)
         deeds = Deeds { sizeLimit = (bLOAT_FACTOR - 1) * annedSize anned_e, 
stepLimit = (bLOAT_FACTOR - 1) * annedSize anned_e }



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

Reply via email to