+vectModule guts
+ = do
+ (types', fam_insts, tc_binds) <- vectTypeEnv (mg_types guts)
+
+ let fam_inst_env' = extendFamInstEnvList (mg_fam_inst_env guts) fam_insts
+ updGEnv (setFamInstEnv fam_inst_env')
+
+ -- dicts <- mapM buildPADict pa_insts
+ -- workers <- mapM vectDataConWorkers pa_insts
+ binds' <- mapM vectTopBind (mg_binds guts)
+ return $ guts { mg_types = types'
+ , mg_binds = Rec tc_binds : binds'
+ , mg_fam_inst_env = fam_inst_env'
+ , mg_fam_insts = mg_fam_insts guts ++ fam_insts
+ }
+
+vectTopBind :: CoreBind -> VM CoreBind
+vectTopBind b@(NonRec var expr)
+ = do
+ (inline, expr') <- vectTopRhs var expr
+ var' <- vectTopBinder var inline expr'
+ hs <- takeHoisted
+ cexpr <- tryConvert var var' expr
+ return . Rec $ (var, cexpr) : (var', expr') : hs
+ `orElseV`
+ return b
+
+vectTopBind b@(Rec bs)
+ = do
+ (vars', _, exprs') <- fixV $ \ ~(_, inlines, rhss) ->
+ do
+ vars' <- sequence [vectTopBinder var inline rhs
+ | (var, ~(inline, rhs))
+ <- zipLazy vars (zip inlines rhss)]
+ (inlines', exprs') <- mapAndUnzipM (uncurry vectTopRhs) bs
+ return (vars', inlines', exprs')
+ hs <- takeHoisted
+ cexprs <- sequence $ zipWith3 tryConvert vars vars' exprs
+ return . Rec $ zip vars cexprs ++ zip vars' exprs' ++ hs
+ `orElseV`
+ return b
+ where
+ (vars, exprs) = unzip bs
+
+-- NOTE: vectTopBinder *MUST* be lazy in inline and expr because of how it is
+-- used inside of fixV in vectTopBind
+vectTopBinder :: Var -> Inline -> CoreExpr -> VM Var
+vectTopBinder var inline expr
+ = do
+ vty <- vectType (idType var)
+ var' <- liftM (`setIdUnfolding` unfolding) $ cloneId mkVectOcc var vty
+ defGlobalVar var var'
+ return var'
+ where
+ unfolding = case inline of
+ Inline arity -> mkInlineRule InlSat expr arity
+ DontInline -> noUnfolding
+
+vectTopRhs :: Var -> CoreExpr -> VM (Inline, CoreExpr)
+vectTopRhs var expr
+ = closedV
+ $ do
+ (inline, vexpr) <- inBind var
+ $ vectPolyExpr (isLoopBreaker $ idOccInfo var)
+ (freeVars expr)
+ return (inline, vectorised vexpr)
+
+tryConvert :: Var -> Var -> CoreExpr -> VM CoreExpr
+tryConvert var vect_var rhs
+ = fromVect (idType var) (Var vect_var) `orElseV` return rhs