2 module Vectorise.Utils.Closure (
11 import Vectorise.Builtins
13 import Vectorise.Monad
28 mkClosure :: Type -> Type -> Type -> VExpr -> VExpr -> VM VExpr
29 mkClosure arg_ty res_ty env_ty (vfn,lfn) (venv,lenv)
30 = do Just dict <- paDictOfType env_ty
31 mkv <- builtin closureVar
32 mkl <- builtin liftedClosureVar
33 return (Var mkv `mkTyApps` [arg_ty, res_ty, env_ty] `mkApps` [dict, vfn, lfn, venv],
34 Var mkl `mkTyApps` [arg_ty, res_ty, env_ty] `mkApps` [dict, vfn, lfn, lenv])
37 mkClosureApp :: Type -> Type -> VExpr -> VExpr -> VM VExpr
38 mkClosureApp arg_ty res_ty (vclo, lclo) (varg, larg)
39 = do vapply <- builtin applyVar
40 lapply <- builtin liftedApplyVar
41 lc <- builtin liftingContext
42 return (Var vapply `mkTyApps` [arg_ty, res_ty] `mkApps` [vclo, varg],
43 Var lapply `mkTyApps` [arg_ty, res_ty] `mkApps` [Var lc, lclo, larg])
46 buildClosures :: [TyVar] -> [VVar] -> [Type] -> Type -> VM VExpr -> VM VExpr
47 buildClosures _ _ [] _ mk_body
49 buildClosures tvs vars [arg_ty] res_ty mk_body
50 = -- liftM vInlineMe $
51 buildClosure tvs vars arg_ty res_ty mk_body
52 buildClosures tvs vars (arg_ty : arg_tys) res_ty mk_body
54 res_ty' <- mkClosureTypes arg_tys res_ty
55 arg <- newLocalVVar (fsLit "x") arg_ty
57 buildClosure tvs vars arg_ty res_ty'
58 . hoistPolyVExpr tvs (Inline (length vars + 1))
60 lc <- builtin liftingContext
61 clo <- buildClosures tvs (vars ++ [arg]) arg_tys res_ty mk_body
62 return $ vLams lc (vars ++ [arg]) clo
65 -- (clo <x1,...,xn> <f,f^>, aclo (Arr lc xs1 ... xsn) <f,f^>)
67 -- f = \env v -> case env of <x1,...,xn> -> e x1 ... xn v
68 -- f^ = \env v -> case env of Arr l xs1 ... xsn -> e^ l x1 ... xn v
70 buildClosure :: [TyVar] -> [VVar] -> Type -> Type -> VM VExpr -> VM VExpr
71 buildClosure tvs vars arg_ty res_ty mk_body
73 (env_ty, env, bind) <- buildEnv vars
74 env_bndr <- newLocalVVar (fsLit "env") env_ty
75 arg_bndr <- newLocalVVar (fsLit "arg") arg_ty
77 fn <- hoistPolyVExpr tvs (Inline 2)
79 lc <- builtin liftingContext
82 . vLams lc [env_bndr, arg_bndr]
83 $ bind (vVar env_bndr)
84 (vVarApps lc body (vars ++ [arg_bndr]))
86 mkClosure arg_ty res_ty env_ty fn env
89 -- Environments ---------------------------------------------------------------
90 buildEnv :: [VVar] -> VM (Type, VExpr, VExpr -> VExpr -> VExpr)
93 void <- builtin voidVar
94 pvoid <- builtin pvoidVar
95 return (ty, vVar (void, pvoid), \_ body -> body)
97 buildEnv [v] = return (vVarType v, vVar v,
98 \env body -> vLet (vNonRec v env) body)
103 (lenv_tc, lenv_tyargs) <- pdataReprTyCon ty
105 let venv_con = tupleCon Boxed (length vs)
106 [lenv_con] = tyConDataCons lenv_tc
108 venv = mkCoreTup (map Var vvs)
109 lenv = Var (dataConWrapId lenv_con)
110 `mkTyApps` lenv_tyargs
113 vbind env body = mkWildCase env ty (exprType body)
114 [(DataAlt venv_con, vvs, body)]
117 let scrut = unwrapFamInstScrut lenv_tc lenv_tyargs env
119 mkWildCase scrut (exprType scrut) (exprType body)
120 [(DataAlt lenv_con, lvs, body)]
122 bind (venv, lenv) (vbody, lbody) = (vbind venv vbody,
125 return (ty, (venv, lenv), bind)
127 (vvs, lvs) = unzip vs
128 tys = map vVarType vs
129 ty = mkBoxedTupleTy tys