+ 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 tycon ty_args 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
+
+vectAlgCase tycon ty_args scrut bndr ty [(DataAlt dc, bndrs, body)]
+ = do
+ vect_tc <- maybeV (lookupTyCon tycon)
+ vty <- vectType ty
+ lty <- mkPArrayType vty
+ vexpr <- vectExpr scrut
+ (vbndr, (vbndrs, vbody)) <- vect_scrut_bndr
+ . vectBndrsIn bndrs
+ $ vectExpr body
+
+ (vscrut, arr_tc, arg_tys) <- mkVScrut (vVar vbndr)
+ vect_dc <- maybeV (lookupDataCon dc)
+ let [arr_dc] = tyConDataCons arr_tc
+ repr <- mkRepr vect_tc
+ shape_bndrs <- arrShapeVars repr
+ return . vLet (vNonRec vbndr vexpr)
+ $ vCaseProd vscrut vty lty vect_dc arr_dc shape_bndrs vbndrs vbody
+ where
+ vect_scrut_bndr | isDeadBinder bndr = vectBndrNewIn bndr FSLIT("scrut")
+ | otherwise = vectBndrIn bndr
+
+vectAlgCase tycon ty_args scrut bndr ty alts
+ = do
+ vect_tc <- maybeV (lookupTyCon tycon)
+ vty <- vectType ty
+ lty <- mkPArrayType vty
+
+ repr <- mkRepr vect_tc
+ shape_bndrs <- arrShapeVars repr
+ (len, sel, indices) <- arrSelector repr (map Var shape_bndrs)
+
+ (vbndr, valts) <- vect_scrut_bndr $ mapM (proc_alt sel lty) alts'
+ let (vect_dcs, vect_bndrss, lift_bndrss, vbodies) = unzip4 valts
+
+ vexpr <- vectExpr scrut
+ (vscrut, arr_tc, arg_tys) <- mkVScrut (vVar vbndr)
+ let [arr_dc] = tyConDataCons arr_tc
+
+ let (vect_scrut, lift_scrut) = vscrut
+ (vect_bodies, lift_bodies) = unzip vbodies
+
+ let vect_case = Case vect_scrut (mkWildId (exprType vect_scrut)) vty
+ (zipWith3 mk_vect_alt vect_dcs vect_bndrss vect_bodies)
+
+ lbody <- combinePA vty len sel indices lift_bodies
+ let lift_case = Case lift_scrut (mkWildId (exprType lift_scrut)) lty
+ [(DataAlt arr_dc, shape_bndrs ++ concat lift_bndrss,
+ lbody)]
+
+ return . vLet (vNonRec vbndr vexpr)
+ $ (vect_case, lift_case)