+ 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)
+ where
+ vect_scrut_bndr | isDeadBinder bndr = vectBndrNewIn bndr FSLIT("scrut")
+ | otherwise = vectBndrIn bndr
+
+ alts' = sortBy (\(alt1, _, _) (alt2, _, _) -> cmp alt1 alt2) alts
+
+ cmp (DataAlt dc1) (DataAlt dc2) = dataConTag dc1 `compare` dataConTag dc2
+ cmp DEFAULT DEFAULT = EQ
+ cmp DEFAULT _ = LT
+ cmp _ DEFAULT = GT
+
+ proc_alt sel vty lty (DataAlt dc, bndrs, body)
+ = do
+ vect_dc <- maybeV (lookupDataCon dc)
+ let tag = mkDataConTag vect_dc
+ fvs = freeVarsOf body `delVarSetList` bndrs
+ (vect_bndrs, lift_bndrs, vbody)
+ <- vect_alt_bndrs bndrs
+ $ \len -> packLiftingContext len sel tag fvs vty lty
+ $ vectExpr body
+
+ return (vect_dc, vect_bndrs, lift_bndrs, vbody)
+
+ vect_alt_bndrs [] p
+ = do
+ void_tc <- builtin voidTyCon
+ let void_ty = mkTyConApp void_tc []
+ arr_ty <- mkPArrayType void_ty
+ bndr <- newLocalVar FSLIT("voids") arr_ty
+ len <- lengthPA void_ty (Var bndr)
+ e <- p len
+ return ([], [bndr], e)
+
+ vect_alt_bndrs bndrs p
+ = localV
+ $ do
+ vbndrs <- mapM vectBndr bndrs
+ let (vect_bndrs, lift_bndrs) = unzip vbndrs
+ vv : _ = vect_bndrs
+ lv : _ = lift_bndrs
+ len <- lengthPA (idType vv) (Var lv)
+ e <- p len
+ return (vect_bndrs, lift_bndrs, e)
+
+ mk_vect_alt vect_dc bndrs body = (DataAlt vect_dc, bndrs, body)
+
+packLiftingContext :: CoreExpr -> CoreExpr -> CoreExpr -> VarSet
+ -> Type -> Type -> VM VExpr -> VM VExpr
+packLiftingContext len shape tag fvs vty lty p
+ = do
+ select <- builtin selectPAIntPrimVar
+ let sel_expr = mkApps (Var select) [shape, tag]
+ sel_var <- newLocalVar FSLIT("sel#") (exprType sel_expr)
+ lc_var <- builtin liftingContext
+ localV $
+ do
+ bnds <- mapM (packFreeVar (Var lc_var) (Var sel_var))
+ . filter isLocalId
+ $ varSetElems fvs
+ (vexpr, lexpr) <- p
+ empty <- emptyPA vty
+ return (vexpr, Let (NonRec sel_var sel_expr)
+ . mkLets (concat bnds)
+ $ Case len lc_var lty
+ [(DEFAULT, [], lexpr),
+ (LitAlt (mkMachInt 0), [], empty)])
+
+packFreeVar :: CoreExpr -> CoreExpr -> Var -> VM [CoreBind]
+packFreeVar len sel v
+ = do
+ r <- lookupVar v
+ case r of
+ Local (vv,lv) ->
+ do
+ lv' <- cloneVar lv
+ expr <- packPA (idType vv) (Var lv) len sel
+ updLEnv (upd vv lv')
+ return [(NonRec lv' expr)]
+
+ _ -> return []
+ where
+ upd vv lv' env = env { local_vars = extendVarEnv (local_vars env) v (vv, lv') }