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

On branch  : supercompiler

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

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

commit f5ead43ce99038135a5730784d155e411b126713
Author: Max Bolingbroke <batterseapo...@hotmail.com>
Date:   Mon Mar 12 13:14:10 2012 +0000

    Fix selective supercompilation: suck in all things *referred to*, not 
*referring to us*

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

 compiler/supercompile/Supercompile.hs |   41 +++++++++++++++++---------------
 1 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/compiler/supercompile/Supercompile.hs 
b/compiler/supercompile/Supercompile.hs
index 41a4153..decf6e3 100644
--- a/compiler/supercompile/Supercompile.hs
+++ b/compiler/supercompile/Supercompile.hs
@@ -50,23 +50,24 @@ import qualified Data.Map as M
 --  2) The remaining CoreBinds. These may refer to those CoreBinds but are not 
referred
 --     to *by* them
 --
--- As a bonus, it returns the free variables of the bindings in the second 
list.

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

 -- NB: assumes no-shadowing at the top level. I don't want to have to rename 
stuff to
 -- commute CoreBinds...
-partitionBinds :: (Id -> Bool) -> [CoreBind] -> ([CoreBind], [CoreBind], 
S.FreeVars)
-partitionBinds should_sc initial_binds = go initial_inside [(b, unionVarSets 
(map S.idFreeVars (bindersOf b) ++ map exprFreeVars (rhssOfBind b))) | b <- 
initial_undecided]
+partitionBinds :: (Id -> Bool) -> [CoreBind] -> ([CoreBind], [CoreBind])
+partitionBinds should_sc initial_binds = go initial_inside initial_undecided
   where
     (initial_inside, initial_undecided) = partition (any should_sc . 
bindersOf) initial_binds
     
-    go :: [CoreBind] -> [(CoreBind, S.FreeVars)] -> ([CoreBind], [CoreBind], 
S.FreeVars)
+    go :: [CoreBind] -> [CoreBind] -> ([CoreBind], [CoreBind])
     go inside undecided
-        | null inside' = (inside, map fst undecided, unionVarSets (map snd 
undecided))
-        | otherwise    = first3 (inside ++) $ go (map fst inside') undecided'
+        | null inside' = (inside, undecided)
+        | otherwise    = first (inside ++) $ go inside' undecided'
       where
-        -- Move anything inside that refers to a binding that was moved inside 
last round
-        (inside', undecided') = partition (\(_, fvs) -> inside_bs 
`intersectsVarSet` fvs) undecided
-        inside_bs = mkVarSet [x | b <- inside, x <- bindersOf b]
+        -- Move anything inside that is referred to by a binding that was 
moved inside last round
+        inside_fvs = coreBindsFVs inside
+        (inside', undecided') = partition (\b -> any (`elemVarSet` inside_fvs) 
(bindersOf b)) undecided
+
+coreBindsFVs :: [CoreBind] -> S.FreeVars
+coreBindsFVs bs = unionVarSets [fvs | b <- bs, fvs <- map S.idFreeVars 
(bindersOf b) ++ map exprFreeVars (rhssOfBind b)]
 
 coreBindsToCoreTerm :: (Id -> Bool) -> [CoreBind] -> (CoreExpr, Var -> 
[CoreBind])
 coreBindsToCoreTerm should_sc binds
@@ -79,21 +80,23 @@ coreBindsToCoreTerm should_sc binds
     --
     -- We used to use a standard "big tuple" to do the binding-back, but this 
breaks down if we need to include
     -- some variables of unlifted type (of kind #) or a dictionary (of kind 
Constraint) since the type arguments of
-    -- the (,..,) tycon must be of kind *.
+    -- the (,..,) tycon must be of kind *. The unlifted case isn't important 
(they can't occur at top level), but
+    -- the Constraint case is a killer.
     --
     -- Then I tried to use a church-encoded tuple to do that, where the tuple 
(x, y, z) is encoded as
     -- /\(a :: ArgTypeKind). \(k :: x_ty -> y_ty -> z_ty -> a). k x y z
     -- And selected from by applying an appropriate type argument and 
continuation. Unfortunately, this type polymorphism,
     -- while permitted by the type system, is an illusion: abstraction over 
types of kinds other than * only works
     -- if the type abstractions all are beta-reduced away before code 
generation.
-      --
-      -- Another problem with this second approach is that GHC's inlining 
heuristics didn't tend to inline very
-      -- large encoded tuples even with explicit continutaion args, because 
the contination binder didn't get a
-      -- large enough discount.
-      --
-      -- My third attempt just encodes it as an unboxed tuple, which we 
contrive to buind at the top level by abstracting
-      -- it over a useless arg of void representation.
-    (sc_binds, dont_sc_binds, dont_sc_binds_fvs) = partitionBinds should_sc 
binds
+    --
+    -- Another problem with this second approach is that GHC's inlining 
heuristics didn't tend to inline very
+    -- large encoded tuples even with explicit continutaion args, because the 
contination binder didn't get a
+    -- large enough discount.
+    --
+    -- My third attempt just encodes it as an unboxed tuple, which we contrive 
to buind at the top level by abstracting
+    -- it over a useless arg of void representation.
+    (sc_binds, dont_sc_binds) = partitionBinds should_sc binds
+    dont_sc_binds_fvs = coreBindsFVs dont_sc_binds
     
     -- We should zap fragile information on the Ids' we use within the tuple 
selector. The reasons are:
     --  1. They may be mutually inter-referring, and the binders of a "case" 
are not simultaneously brought into scope



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

Reply via email to