Repository : ssh://darcs.haskell.org//srv/darcs/ghc On branch : supercompiler
http://hackage.haskell.org/trac/ghc/changeset/b896fa8d0f0bba1396970a15ddf09d7d125abeee >--------------------------------------------------------------- commit b896fa8d0f0bba1396970a15ddf09d7d125abeee Author: Max Bolingbroke <batterseapo...@hotmail.com> Date: Thu Mar 1 11:45:58 2012 +0000 Another attempt at Binds->Term translation >--------------------------------------------------------------- compiler/supercompile/Supercompile.hs | 60 ++++++++++++++++++-------------- 1 files changed, 34 insertions(+), 26 deletions(-) diff --git a/compiler/supercompile/Supercompile.hs b/compiler/supercompile/Supercompile.hs index b2813c2..d74945a 100644 --- a/compiler/supercompile/Supercompile.hs +++ b/compiler/supercompile/Supercompile.hs @@ -22,24 +22,24 @@ import qualified Supercompile.Drive.Process1 as S () import qualified Supercompile.Drive.Process2 as S () import qualified Supercompile.Drive.Process3 as S -import BasicTypes (InlinePragma(..), InlineSpec(..), isActiveIn) +import BasicTypes (InlinePragma(..), InlineSpec(..), isActiveIn, TupleSort(..)) import CoreSyn import CoreFVs (exprFreeVars) import CoreUtils (exprType) +import MkCore (mkWildValBinder) import Coercion (isCoVar, mkCoVarCo, mkAxInstCo) import DataCon (dataConAllTyVars, dataConRepArgTys, dataConTyCon, dataConWorkId) import VarSet -import VarEnv -import Name (localiseName, mkSystemName) -import OccName (mkVarOcc) -import Var (Var, varUnique, varName, setVarName) +import Name (localiseName) +import Var (Var, varName, setVarName) import Id +import MkId (realWorldPrimId) import FastString (fsLit) -import PrelNames (undefinedName) import PrimOp (primOpSig) import TcType (tcSplitDFunTy) -import Type (mkTyVarTy, mkForAllTy, mkFunTys) -import TysPrim (alphaTyVar, argAlphaTyVar) +import Type (mkTyVarTy, mkTyConApp) +import TysPrim (realWorldStatePrimTy) +import TysWiredIn (tupleTyCon, tupleCon) import TyCon (newTyConCo_maybe) import qualified Data.Map as M @@ -70,16 +70,29 @@ partitionBinds should_sc initial_binds = go initial_inside [(b, unionVarSets (ma coreBindsToCoreTerm :: (Id -> Bool) -> [CoreBind] -> (CoreExpr, Var -> [CoreBind]) coreBindsToCoreTerm should_sc binds - = (mkLets internal_sc_binds (mkChurchVarTup sc_internal_xs), - \y -> [NonRec x (mkChurchTupleSelector sc_internal_xs internal_x (Var y)) | (x, internal_x) <- sc_xs_internal_xs] ++ dont_sc_binds) + = (mkLets internal_sc_binds (mkLiftedVarTup sc_internal_xs), + \y -> [NonRec x (mkLiftedTupleSelector sc_internal_xs internal_x (Var y)) | (x, internal_x) <- sc_xs_internal_xs] ++ dont_sc_binds) where - -- We put all the sc_binds into a local let, and use Church-encoded tuples to bind back to the top level the names of + -- We put all the sc_binds into a local let, and use unboxed tuples to bind back to the top level the names of -- any of those sc_binds that are either exported *or* in the free variables of something from dont_sc_binds. -- Making that list as small as possible allows the supercompiler to determine that more things are used linearly. -- -- 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 *. + -- + -- 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 -- This is a sweet hack. Most of the top-level binders will be External names. It is a Bad Idea to locally-bind @@ -109,22 +122,17 @@ coreBindsToCoreTerm should_sc binds localiseInternaliseId x = setIdNotExported (x `setVarName` localiseName (varName x)) -- If we don't mark these Ids as not exported then we get lots of residual top-level bindings of the form x = y -mkChurchVarTup :: [Id] -> CoreExpr -mkChurchVarTup [] = Var (mkVanillaGlobal undefinedName (mkForAllTy alphaTyVar (mkTyVarTy alphaTyVar))) -mkChurchVarTup xs@(first_x:_) = Lam argAlphaTyVar $ Lam k $ Var k `mkVarApps` xs - where iss = mkInScopeSet (mkVarSet xs) - -- Gin up a name for the continuation argument from spit, glue, and an exhaustive set of shadowed names - -- - -- FIXME: We have to lie and use argAlphaTyVar here because we want to instantiate it with types of - -- kind * and of kind Constraint. - -- - -- The lie is that instantiation with types of kind # would be very bad!! Luckily this never happens - -- since the top level can never bind an unlifted value. - k = uniqAway iss $ mkLocalId (mkSystemName (varUnique first_x) (mkVarOcc "k")) - (map idType xs `mkFunTys` mkTyVarTy argAlphaTyVar) - -mkChurchTupleSelector :: [Var] -> Var -> CoreExpr -> CoreExpr -mkChurchTupleSelector xs want_x tup_e = tup_e `App` Type (idType want_x) `App` mkLams xs (Var want_x) + +-- NB: I can't see any GHC code that prevents nullary unboxed tuples, but I'm not actually sure they work +-- (note that in particular they get the same OccName as the unary versions). +mkLiftedVarTup :: [Id] -> CoreExpr +mkLiftedVarTup xs = Lam (mkWildValBinder realWorldStatePrimTy) $ Var (dataConWorkId (tupleCon UnboxedTuple (length xs))) `mkTyApps` map idType xs `mkVarApps` xs + +mkLiftedTupleSelector :: [Id] -> Id -> CoreExpr -> CoreExpr +mkLiftedTupleSelector xs want_x tup_e + = Case (tup_e `App` Var realWorldPrimId) (mkWildValBinder (mkTyConApp (tupleTyCon UnboxedTuple n) (map idType xs))) (idType want_x) + [(DataAlt (tupleCon UnboxedTuple n), xs, Var want_x)] + where n = length xs termUnfoldings :: S.Term -> [(Var, S.Term)] termUnfoldings e = go (S.termFreeVars e) emptyVarSet [] _______________________________________________ Cvs-ghc mailing list Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc