module VectUtils (
collectAnnTypeBinders, collectAnnTypeArgs, isAnnTypeArg,
+ collectAnnValBinders,
+ mkDataConTag,
splitClosureTy,
mkPADictType, mkPArrayType,
- paDictArgType, paDictOfType,
- paMethod, lengthPA, replicatePA, emptyPA,
+ parrayReprTyCon, parrayReprDataCon, mkVScrut,
+ paDictArgType, paDictOfType, paDFunType,
+ paMethod, lengthPA, replicatePA, emptyPA, liftPA,
polyAbstract, polyApply, polyVApply,
- lookupPArrayFamInst,
- hoistExpr, hoistPolyVExpr, takeHoisted,
- buildClosure
+ hoistBinding, hoistExpr, hoistPolyVExpr, takeHoisted,
+ buildClosure, buildClosures,
+ mkClosureApp
) where
#include "HsVersions.h"
import Type
import TypeRep
import TyCon
-import DataCon ( dataConWrapId )
+import DataCon ( DataCon, dataConWrapId, dataConTag )
import Var
import Id ( mkWildId )
import MkId ( unwrapFamInstScrut )
go bs (_, AnnLam b e) | isTyVar b = go (b:bs) e
go bs e = (reverse bs, e)
+collectAnnValBinders :: AnnExpr Var ann -> ([Var], AnnExpr Var ann)
+collectAnnValBinders expr = go [] expr
+ where
+ go bs (_, AnnLam b e) | isId b = go (b:bs) e
+ go bs e = (reverse bs, e)
+
isAnnTypeArg :: AnnExpr b ann -> Bool
isAnnTypeArg (_, AnnType t) = True
isAnnTypeArg _ = False
+mkDataConTag :: DataCon -> CoreExpr
+mkDataConTag dc = mkConApp intDataCon [mkIntLitInt $ dataConTag dc]
+
isClosureTyCon :: TyCon -> Bool
isClosureTyCon tc = tyConName tc == closureTyConName
| otherwise = pprPanic "splitPArrayTy" (ppr ty)
+mkClosureType :: Type -> Type -> VM Type
+mkClosureType arg_ty res_ty
+ = do
+ tc <- builtin closureTyCon
+ return $ mkTyConApp tc [arg_ty, res_ty]
+
+mkClosureTypes :: [Type] -> Type -> VM Type
+mkClosureTypes arg_tys res_ty
+ = do
+ tc <- builtin closureTyCon
+ return $ foldr (mk tc) res_ty arg_tys
+ where
+ mk tc arg_ty res_ty = mkTyConApp tc [arg_ty, res_ty]
+
mkPADictType :: Type -> VM Type
mkPADictType ty
= do
- tc <- builtin paDictTyCon
+ tc <- builtin paTyCon
return $ TyConApp tc [ty]
mkPArrayType :: Type -> VM Type
tc <- builtin parrayTyCon
return $ TyConApp tc [ty]
+parrayReprTyCon :: Type -> VM (TyCon, [Type])
+parrayReprTyCon ty = builtin parrayTyCon >>= (`lookupFamInst` [ty])
+
+parrayReprDataCon :: Type -> VM (DataCon, [Type])
+parrayReprDataCon ty
+ = do
+ (tc, arg_tys) <- parrayReprTyCon ty
+ let [dc] = tyConDataCons tc
+ return (dc, arg_tys)
+
+mkVScrut :: VExpr -> VM (VExpr, TyCon, [Type])
+mkVScrut (ve, le)
+ = do
+ (tc, arg_tys) <- parrayReprTyCon (exprType ve)
+ return ((ve, unwrapFamInstScrut tc arg_tys le), tc, arg_tys)
+
paDictArgType :: TyVar -> VM (Maybe Type)
paDictArgType tv = go (TyVarTy tv) (tyVarKind tv)
where
paDFunApply dfun ty_args
paDictOfTyApp (TyConApp tc _) ty_args
= do
- pa_class <- builtin paClass
- (dfun, ty_args') <- lookupInst pa_class [TyConApp tc ty_args]
- paDFunApply (Var dfun) ty_args'
+ dfun <- traceMaybeV "paDictOfTyApp" (ppr tc) (lookupTyConPA tc)
+ paDFunApply (Var dfun) ty_args
paDictOfTyApp ty ty_args = pprPanic "paDictOfTyApp" (ppr ty)
+paDFunType :: TyCon -> VM Type
+paDFunType tc
+ = do
+ margs <- mapM paDictArgType tvs
+ res <- mkPADictType (mkTyConApp tc arg_tys)
+ return . mkForAllTys tvs
+ $ mkFunTys [arg | Just arg <- margs] res
+ where
+ tvs = tyConTyVars tc
+ arg_tys = mkTyVarTys tvs
+
paDFunApply :: CoreExpr -> [Type] -> VM CoreExpr
paDFunApply dfun tys
= do
emptyPA :: Type -> VM CoreExpr
emptyPA = paMethod emptyPAVar
+liftPA :: CoreExpr -> VM CoreExpr
+liftPA x
+ = do
+ lc <- builtin liftingContext
+ replicatePA (Var lc) x
+
newLocalVVar :: FastString -> Type -> VM VVar
newLocalVVar fs vty
= do
dicts <- mapM paDictOfType tys
return $ mapVect (\e -> e `mkTyApps` tys `mkApps` dicts) expr
-lookupPArrayFamInst :: Type -> VM (TyCon, [Type])
-lookupPArrayFamInst ty = builtin parrayTyCon >>= (`lookupFamInst` [ty])
+hoistBinding :: Var -> CoreExpr -> VM ()
+hoistBinding v e = updGEnv $ \env ->
+ env { global_bindings = (v,e) : global_bindings env }
hoistExpr :: FastString -> CoreExpr -> VM Var
hoistExpr fs expr
= do
var <- newLocalVar fs (exprType expr)
- updGEnv $ \env ->
- env { global_bindings = (var, expr) : global_bindings env }
+ hoistBinding var expr
return var
-hoistVExpr :: FastString -> VExpr -> VM VVar
-hoistVExpr fs (ve, le)
+hoistVExpr :: VExpr -> VM VVar
+hoistVExpr (ve, le)
= do
+ fs <- getBindName
vv <- hoistExpr ('v' `consFS` fs) ve
lv <- hoistExpr ('l' `consFS` fs) le
return (vv, lv)
-hoistPolyVExpr :: FastString -> [TyVar] -> VM VExpr -> VM VExpr
-hoistPolyVExpr fs tvs p
+hoistPolyVExpr :: [TyVar] -> VM VExpr -> VM VExpr
+hoistPolyVExpr tvs p
= do
expr <- closedV . polyAbstract tvs $ \abstract ->
liftM (mapVect abstract) p
- fn <- hoistVExpr fs expr
+ fn <- hoistVExpr expr
polyVApply (vVar fn) (mkTyVarTys tvs)
takeHoisted :: VM [(Var, CoreExpr)]
setGEnv $ env { global_bindings = [] }
return $ global_bindings env
-
mkClosure :: Type -> Type -> Type -> VExpr -> VExpr -> VM VExpr
mkClosure arg_ty res_ty env_ty (vfn,lfn) (venv,lenv)
= do
return (Var mkv `mkTyApps` [arg_ty, res_ty, env_ty] `mkApps` [dict, vfn, lfn, venv],
Var mkl `mkTyApps` [arg_ty, res_ty, env_ty] `mkApps` [dict, vfn, lfn, lenv])
+mkClosureApp :: VExpr -> VExpr -> VM VExpr
+mkClosureApp (vclo, lclo) (varg, larg)
+ = do
+ vapply <- builtin applyClosureVar
+ lapply <- builtin applyClosurePVar
+ return (Var vapply `mkTyApps` [arg_ty, res_ty] `mkApps` [vclo, varg],
+ Var lapply `mkTyApps` [arg_ty, res_ty] `mkApps` [lclo, larg])
+ where
+ (arg_ty, res_ty) = splitClosureTy (exprType vclo)
+
+buildClosures :: [TyVar] -> [VVar] -> [Type] -> Type -> VM VExpr -> VM VExpr
+buildClosures tvs vars [arg_ty] res_ty mk_body
+ = buildClosure tvs vars arg_ty res_ty mk_body
+buildClosures tvs vars (arg_ty : arg_tys) res_ty mk_body
+ = do
+ res_ty' <- mkClosureTypes arg_tys res_ty
+ arg <- newLocalVVar FSLIT("x") arg_ty
+ buildClosure tvs vars arg_ty res_ty'
+ . hoistPolyVExpr tvs
+ $ do
+ lc <- builtin liftingContext
+ clo <- buildClosures tvs (vars ++ [arg]) arg_tys res_ty mk_body
+ return $ vLams lc (vars ++ [arg]) clo
+
-- (clo <x1,...,xn> <f,f^>, aclo (Arr lc xs1 ... xsn) <f,f^>)
-- where
-- f = \env v -> case env of <x1,...,xn> -> e x1 ... xn v
-- f^ = \env v -> case env of Arr l xs1 ... xsn -> e^ l x1 ... xn v
-
-buildClosure :: [TyVar] -> Var -> [VVar] -> Type -> Type -> VM VExpr -> VM VExpr
-buildClosure tvs lv vars arg_ty res_ty mk_body
+--
+buildClosure :: [TyVar] -> [VVar] -> Type -> Type -> VM VExpr -> VM VExpr
+buildClosure tvs vars arg_ty res_ty mk_body
= do
- (env_ty, env, bind) <- buildEnv lv vars
+ (env_ty, env, bind) <- buildEnv vars
env_bndr <- newLocalVVar FSLIT("env") env_ty
arg_bndr <- newLocalVVar FSLIT("arg") arg_ty
- fn <- hoistPolyVExpr FSLIT("fn") tvs
+ fn <- hoistPolyVExpr tvs
$ do
+ lc <- builtin liftingContext
body <- mk_body
body' <- bind (vVar env_bndr)
- (vVarApps lv body (vars ++ [arg_bndr]))
+ (vVarApps lc body (vars ++ [arg_bndr]))
return (vLamsWithoutLC [env_bndr, arg_bndr] body')
mkClosure arg_ty res_ty env_ty fn env
-buildEnv :: Var -> [VVar] -> VM (Type, VExpr, VExpr -> VExpr -> VM VExpr)
-buildEnv lv vvs
+buildEnv :: [VVar] -> VM (Type, VExpr, VExpr -> VExpr -> VM VExpr)
+buildEnv vvs
= do
+ lc <- builtin liftingContext
let (ty, venv, vbind) = mkVectEnv tys vs
- (lenv, lbind) <- mkLiftEnv lv tys ls
+ (lenv, lbind) <- mkLiftEnv lc tys ls
return (ty, (venv, lenv),
\(venv,lenv) (vbody,lbody) ->
do
ty = mkCoreTupTy tys
mkLiftEnv :: Var -> [Type] -> [Var] -> VM (CoreExpr, CoreExpr -> CoreExpr -> VM CoreExpr)
-mkLiftEnv lv [ty] [v]
+mkLiftEnv lc [ty] [v]
= return (Var v, \env body ->
do
len <- lengthPA (Var v)
return . Let (NonRec v env)
- $ Case len lv (exprType body) [(DEFAULT, [], body)])
+ $ Case len lc (exprType body) [(DEFAULT, [], body)])
-- NOTE: this transparently deals with empty environments
-mkLiftEnv lv tys vs
+mkLiftEnv lc tys vs
= do
- (env_tc, env_tyargs) <- lookupPArrayFamInst vty
+ (env_tc, env_tyargs) <- parrayReprTyCon vty
let [env_con] = tyConDataCons env_tc
env = Var (dataConWrapId env_con)
`mkTyApps` env_tyargs
- `mkVarApps` (lv : vs)
+ `mkVarApps` (lc : vs)
bind env body = let scrut = unwrapFamInstScrut env_tc env_tyargs env
in
return $ Case scrut (mkWildId (exprType scrut))
(exprType body)
- [(DataAlt env_con, lv : bndrs, body)]
+ [(DataAlt env_con, lc : bndrs, body)]
return (env, bind)
where
vty = mkCoreTupTy tys