2 module Vectorise.Utils.Closure (
11 import Vectorise.Utils.Hoisting
12 import Vectorise.Builtins
14 import Vectorise.Monad
29 mkClosure :: Type -> Type -> Type -> VExpr -> VExpr -> VM VExpr
30 mkClosure arg_ty res_ty env_ty (vfn,lfn) (venv,lenv)
31 = do Just dict <- paDictOfType env_ty
32 mkv <- builtin closureVar
33 mkl <- builtin liftedClosureVar
34 return (Var mkv `mkTyApps` [arg_ty, res_ty, env_ty] `mkApps` [dict, vfn, lfn, venv],
35 Var mkl `mkTyApps` [arg_ty, res_ty, env_ty] `mkApps` [dict, vfn, lfn, lenv])
38 mkClosureApp :: Type -> Type -> VExpr -> VExpr -> VM VExpr
39 mkClosureApp arg_ty res_ty (vclo, lclo) (varg, larg)
40 = do vapply <- builtin applyVar
41 lapply <- builtin liftedApplyVar
42 lc <- builtin liftingContext
43 return (Var vapply `mkTyApps` [arg_ty, res_ty] `mkApps` [vclo, varg],
44 Var lapply `mkTyApps` [arg_ty, res_ty] `mkApps` [Var lc, lclo, larg])
47 buildClosures :: [TyVar] -> [VVar] -> [Type] -> Type -> VM VExpr -> VM VExpr
48 buildClosures _ _ [] _ mk_body
50 buildClosures tvs vars [arg_ty] res_ty mk_body
51 = -- liftM vInlineMe $
52 buildClosure tvs vars arg_ty res_ty mk_body
53 buildClosures tvs vars (arg_ty : arg_tys) res_ty mk_body
55 res_ty' <- mkClosureTypes arg_tys res_ty
56 arg <- newLocalVVar (fsLit "x") arg_ty
58 buildClosure tvs vars arg_ty res_ty'
59 . hoistPolyVExpr tvs (Inline (length vars + 1))
61 lc <- builtin liftingContext
62 clo <- buildClosures tvs (vars ++ [arg]) arg_tys res_ty mk_body
63 return $ vLams lc (vars ++ [arg]) clo
66 -- (clo <x1,...,xn> <f,f^>, aclo (Arr lc xs1 ... xsn) <f,f^>)
68 -- f = \env v -> case env of <x1,...,xn> -> e x1 ... xn v
69 -- f^ = \env v -> case env of Arr l xs1 ... xsn -> e^ l x1 ... xn v
71 buildClosure :: [TyVar] -> [VVar] -> Type -> Type -> VM VExpr -> VM VExpr
72 buildClosure tvs vars arg_ty res_ty mk_body
74 (env_ty, env, bind) <- buildEnv vars
75 env_bndr <- newLocalVVar (fsLit "env") env_ty
76 arg_bndr <- newLocalVVar (fsLit "arg") arg_ty
78 fn <- hoistPolyVExpr tvs (Inline 2)
80 lc <- builtin liftingContext
83 . vLams lc [env_bndr, arg_bndr]
84 $ bind (vVar env_bndr)
85 (vVarApps lc body (vars ++ [arg_bndr]))
87 mkClosure arg_ty res_ty env_ty fn env
90 -- Environments ---------------------------------------------------------------
91 buildEnv :: [VVar] -> VM (Type, VExpr, VExpr -> VExpr -> VExpr)
94 void <- builtin voidVar
95 pvoid <- builtin pvoidVar
96 return (ty, vVar (void, pvoid), \_ body -> body)
98 buildEnv [v] = return (vVarType v, vVar v,
99 \env body -> vLet (vNonRec v env) body)
104 (lenv_tc, lenv_tyargs) <- pdataReprTyCon ty
106 let venv_con = tupleCon Boxed (length vs)
107 [lenv_con] = tyConDataCons lenv_tc
109 venv = mkCoreTup (map Var vvs)
110 lenv = Var (dataConWrapId lenv_con)
111 `mkTyApps` lenv_tyargs
114 vbind env body = mkWildCase env ty (exprType body)
115 [(DataAlt venv_con, vvs, body)]
118 let scrut = unwrapFamInstScrut lenv_tc lenv_tyargs env
120 mkWildCase scrut (exprType scrut) (exprType body)
121 [(DataAlt lenv_con, lvs, body)]
123 bind (venv, lenv) (vbody, lbody) = (vbind venv vbody,
126 return (ty, (venv, lenv), bind)
128 (vvs, lvs) = unzip vs
129 tys = map vVarType vs
130 ty = mkBoxedTupleTy tys