+vectModule :: ModGuts -> VM ModGuts
+vectModule guts
+ = do
+ (types', fam_insts, pa_insts) <- vectTypeEnv (mg_types guts)
+
+ let insts = map painstInstance pa_insts
+ fam_inst_env' = extendFamInstEnvList (mg_fam_inst_env guts) fam_insts
+ inst_env' = extendInstEnvList (mg_inst_env guts) insts
+ updGEnv (setInstEnvs inst_env' fam_inst_env')
+
+ dicts <- mapM buildPADict pa_insts
+ binds' <- mapM vectTopBind (mg_binds guts)
+ return $ guts { mg_types = types'
+ , mg_binds = Rec (concat dicts) : binds'
+ , mg_inst_env = inst_env'
+ , mg_fam_inst_env = fam_inst_env'
+ , mg_insts = mg_insts guts ++ insts
+ , mg_fam_insts = mg_fam_insts guts ++ fam_insts
+ }
+
+vectTopBind :: CoreBind -> VM CoreBind
+vectTopBind b@(NonRec var expr)
+ = do
+ var' <- vectTopBinder var
+ expr' <- vectTopRhs var expr
+ hs <- takeHoisted
+ return . Rec $ (var, expr) : (var', expr') : hs
+ `orElseV`
+ return b
+
+vectTopBind b@(Rec bs)
+ = do
+ vars' <- mapM vectTopBinder vars
+ exprs' <- zipWithM vectTopRhs vars exprs
+ hs <- takeHoisted
+ return . Rec $ bs ++ zip vars' exprs' ++ hs
+ `orElseV`
+ return b
+ where
+ (vars, exprs) = unzip bs
+
+vectTopBinder :: Var -> VM Var
+vectTopBinder var
+ = do
+ vty <- vectType (idType var)
+ name <- cloneName mkVectOcc (getName var)
+ let var' | isExportedId var = Id.mkExportedLocalId name vty
+ | otherwise = Id.mkLocalId name vty
+ defGlobalVar var var'
+ return var'
+
+vectTopRhs :: Var -> CoreExpr -> VM CoreExpr
+vectTopRhs var expr
+ = do
+ lc <- newLocalVar FSLIT("lc") intPrimTy
+ closedV . liftM vectorised
+ . inBind var
+ $ vectPolyExpr lc (freeVars expr)
+
+-- ----------------------------------------------------------------------------
+-- Bindings
+
+vectBndr :: Var -> VM VVar
+vectBndr v
+ = do
+ vty <- vectType (idType v)
+ lty <- mkPArrayType vty
+ let vv = v `Id.setIdType` vty
+ lv = v `Id.setIdType` lty
+ updLEnv (mapTo vv lv)
+ return (vv, lv)
+ where
+ mapTo vv lv env = env { local_vars = extendVarEnv (local_vars env) v (vv, lv) }
+
+vectBndrIn :: Var -> VM a -> VM (VVar, a)
+vectBndrIn v p
+ = localV
+ $ do
+ vv <- vectBndr v
+ x <- p
+ return (vv, x)
+
+vectBndrsIn :: [Var] -> VM a -> VM ([VVar], a)
+vectBndrsIn vs p
+ = localV
+ $ do
+ vvs <- mapM vectBndr vs
+ x <- p
+ return (vvs, x)
+