module VectUtils (
collectAnnTypeBinders, collectAnnTypeArgs, isAnnTypeArg,
+ collectAnnValBinders,
splitClosureTy,
mkPADictType, mkPArrayType,
paDictArgType, paDictOfType,
- paMethod, lengthPA, replicatePA, emptyPA,
- polyAbstract, polyApply,
+ paMethod, lengthPA, replicatePA, emptyPA, liftPA,
+ polyAbstract, polyApply, polyVApply,
lookupPArrayFamInst,
- hoistExpr, takeHoisted
+ hoistExpr, hoistPolyVExpr, takeHoisted,
+ buildClosure, buildClosures,
+ mkClosureApp
) where
#include "HsVersions.h"
+import VectCore
import VectMonad
import DsUtils
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
| 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
emptyPA :: Type -> VM CoreExpr
emptyPA = paMethod emptyPAVar
-type Vect a = (a,a)
-type VVar = Vect Var
-type VExpr = Vect CoreExpr
-
-vectorised :: Vect a -> a
-vectorised = fst
-
-lifted :: Vect a -> a
-lifted = snd
-
-mapVect :: (a -> b) -> Vect a -> Vect b
-mapVect f (x,y) = (f x, f y)
+liftPA :: CoreExpr -> VM CoreExpr
+liftPA x
+ = do
+ lc <- builtin liftingContext
+ replicatePA (Var lc) x
newLocalVVar :: FastString -> Type -> VM VVar
newLocalVVar fs vty
lv <- newLocalVar fs lty
return (vv,lv)
-vVar :: VVar -> VExpr
-vVar = mapVect Var
-
-mkVLams :: [VVar] -> VExpr -> VExpr
-mkVLams vvs (ve,le) = (mkLams vs ve, mkLams ls le)
- where
- (vs,ls) = unzip vvs
-
-mkVVarApps :: Var -> VExpr -> [VVar] -> VExpr
-mkVVarApps lc (ve, le) vvs = (ve `mkVarApps` vs, le `mkVarApps` (lc : ls))
- where
- (vs,ls) = unzip vvs
-
polyAbstract :: [TyVar] -> ((CoreExpr -> CoreExpr) -> VM a) -> VM a
polyAbstract tvs p
= localV
dicts <- mapM paDictOfType tys
return $ expr `mkTyApps` tys `mkApps` dicts
+polyVApply :: VExpr -> [Type] -> VM VExpr
+polyVApply expr tys
+ = 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])
env { global_bindings = (var, expr) : global_bindings env }
return var
-hoistPolyExpr :: FastString -> [TyVar] -> CoreExpr -> VM CoreExpr
-hoistPolyExpr fs tvs expr
+hoistVExpr :: VExpr -> VM VVar
+hoistVExpr (ve, le)
= do
- poly_expr <- closedV . polyAbstract tvs $ \abstract -> return (abstract expr)
- fn <- hoistExpr fs poly_expr
- polyApply (Var fn) (mkTyVarTys tvs)
+ fs <- getBindName
+ vv <- hoistExpr ('v' `consFS` fs) ve
+ lv <- hoistExpr ('l' `consFS` fs) le
+ return (vv, lv)
-hoistPolyVExpr :: FastString -> [TyVar] -> VExpr -> VM VExpr
-hoistPolyVExpr fs tvs (ve, le)
+hoistPolyVExpr :: [TyVar] -> VM VExpr -> VM VExpr
+hoistPolyVExpr tvs p
= do
- ve' <- hoistPolyExpr ('v' `consFS` fs) tvs ve
- le' <- hoistPolyExpr ('l' `consFS` fs) tvs le
- return (ve',le')
+ expr <- closedV . polyAbstract tvs $ \abstract ->
+ liftM (mapVect abstract) p
+ fn <- hoistVExpr expr
+ polyVApply (vVar fn) (mkTyVarTys tvs)
takeHoisted :: VM [(Var, CoreExpr)]
takeHoisted
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] -> VVar -> VExpr -> VM VExpr
-buildClosure tvs lv vars arg 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_bndr <- newLocalVVar FSLIT("env") env_ty
-
- fn <- hoistPolyVExpr FSLIT("fn") tvs
- . mkVLams [env_bndr, arg]
- . bind (vVar env_bndr)
- $ mkVVarApps lv body (vars ++ [arg])
+ (env_ty, env, bind) <- buildEnv vars
+ env_bndr <- newLocalVVar FSLIT("env") env_ty
+ arg_bndr <- newLocalVVar FSLIT("arg") arg_ty
+
+ fn <- hoistPolyVExpr tvs
+ $ do
+ lc <- builtin liftingContext
+ body <- mk_body
+ body' <- bind (vVar env_bndr)
+ (vVarApps lc body (vars ++ [arg_bndr]))
+ return (vLamsWithoutLC [env_bndr, arg_bndr] body')
mkClosure arg_ty res_ty env_ty fn env
- where
- arg_ty = idType (vectorised arg)
- res_ty = exprType (vectorised body)
-
-
-buildEnv :: Var -> [VVar] -> VM (Type, VExpr, VExpr -> VExpr -> 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) -> (vbind venv vbody, lbind lenv lbody))
+ \(venv,lenv) (vbody,lbody) ->
+ do
+ let vbody' = vbind venv vbody
+ lbody' <- lbind lenv lbody
+ return (vbody', lbody'))
where
(vs,ls) = unzip vvs
tys = map idType vs
where
ty = mkCoreTupTy tys
-mkLiftEnv :: Var -> [Type] -> [Var] -> VM (CoreExpr, CoreExpr -> CoreExpr -> CoreExpr)
-mkLiftEnv lv [ty] [v]
- = do
- len <- lengthPA (Var v)
- return (Var v, \env body -> Let (NonRec v env)
- $ Case len lv (exprType body) [(DEFAULT, [], body)])
+mkLiftEnv :: Var -> [Type] -> [Var] -> VM (CoreExpr, CoreExpr -> CoreExpr -> VM CoreExpr)
+mkLiftEnv lc [ty] [v]
+ = return (Var v, \env body ->
+ do
+ len <- lengthPA (Var v)
+ return . Let (NonRec v env)
+ $ 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
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
- Case scrut (mkWildId (exprType scrut)) (exprType body)
- [(DataAlt env_con, lv : vs, body)]
+ return $ Case scrut (mkWildId (exprType scrut))
+ (exprType body)
+ [(DataAlt env_con, lc : bndrs, body)]
return (env, bind)
where
vty = mkCoreTupTy tys
+ bndrs | null vs = [mkWildId unitTy]
+ | otherwise = vs
+