- venv_bndr <- newLocalVar FSLIT("env") vty
- lenv_bndr <- newLocalVar FSLIT("env") lty
-
- let vcase = bind_venv (Var venv_bndr) vbody vbndrs
- lcase <- bind_lenv (Var lenv_bndr) lbody lc_bndr lbndrs
- return (mkLams [venv_bndr, varg] vcase, mkLams [lenv_bndr, larg] lcase)
- where
- vty = cenv_vty info
- lty = cenv_lty info
-
- arity = length (cenv_vars info)
-
- bind_venv venv vbody [] = vbody
- bind_venv venv vbody [vbndr] = Let (NonRec vbndr venv) vbody
- bind_venv venv vbody vbndrs
- = Case venv (mkWildId vty) (exprType vbody)
- [(DataAlt (tupleCon Boxed arity), vbndrs, vbody)]
-
- bind_lenv lenv lbody lc_bndr [lbndr]
- = do
- lengthPA <- builtin lengthPAVar
- return . Let (NonRec lbndr lenv)
- $ Case (mkApps (Var lengthPA) [Type vty, (Var lbndr)])
- lc_bndr
- intTy
- [(DEFAULT, [], lbody)]
-
- bind_lenv lenv lbody lc_bndr lbndrs
- = return
- $ Case (unwrapFamInstScrut (cenv_repr_tycon info)
- (cenv_repr_tyargs info)
- lenv)
- (mkWildId lty)
- (exprType lbody)
- [(DataAlt (cenv_repr_datacon info), lc_bndr : lbndrs, lbody)]
-
-vectTyAppExpr :: CoreExpr -> CoreExprWithFVs -> [Type] -> VM (CoreExpr, CoreExpr)
-vectTyAppExpr lc (_, AnnVar v) tys = vectPolyVar lc v tys
-vectTyAppExpr lc e tys = pprPanic "vectTyAppExpr" (ppr $ deAnnotate e)
+vectLam :: VarSet -> [Var] -> CoreExprWithFVs -> VM VExpr
+vectLam fvs bs body
+ = do
+ tyvars <- localTyVars
+ (vs, vvs) <- readLEnv $ \env ->
+ unzip [(var, vv) | var <- varSetElems fvs
+ , Just vv <- [lookupVarEnv (local_vars env) var]]
+
+ arg_tys <- mapM (vectType . idType) bs
+ res_ty <- vectType (exprType $ deAnnotate body)
+
+ buildClosures tyvars vvs arg_tys res_ty
+ . hoistPolyVExpr tyvars
+ $ do
+ lc <- builtin liftingContext
+ (vbndrs, vbody) <- vectBndrsIn (vs ++ bs)
+ (vectExpr body)
+ return $ vLams lc vbndrs vbody
+
+vectTyAppExpr :: CoreExprWithFVs -> [Type] -> VM VExpr
+vectTyAppExpr (_, AnnVar v) tys = vectPolyVar v tys
+vectTyAppExpr e tys = pprPanic "vectTyAppExpr" (ppr $ deAnnotate e)
+
+type CoreAltWithFVs = AnnAlt Id VarSet
+
+-- We convert
+--
+-- case e :: t of v { ... }
+--
+-- to
+--
+-- V: let v' = e in case v' of _ { ... }
+-- L: let v' = e in case v' `cast` ... of _ { ... }
+--
+-- When lifting, we have to do it this way because v must have the type
+-- [:V(T):] but the scrutinee must be cast to the representation type. We also
+-- have to handle the case where v is a wild var correctly.
+--
+
+-- FIXME: this is too lazy
+vectAlgCase scrut bndr ty [(DEFAULT, [], body)]
+ = do
+ vscrut <- vectExpr scrut
+ vty <- vectType ty
+ lty <- mkPArrayType vty
+ (vbndr, vbody) <- vectBndrIn bndr (vectExpr body)
+ return $ vCaseDEFAULT vscrut vbndr vty lty vbody