X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fvectorise%2FVectorise.hs;h=1c185bdfd9732018e230838509a64623a562421f;hb=a1515d75e38a32d69636c98bb590f6195e2ab3d1;hp=40970c736f0990020db9e80cd06de3b66361a11f;hpb=17b297d97d327620ed6bfab942f8992b2446f1bf;p=ghc-hetmet.git diff --git a/compiler/vectorise/Vectorise.hs b/compiler/vectorise/Vectorise.hs index 40970c7..1c185bd 100644 --- a/compiler/vectorise/Vectorise.hs +++ b/compiler/vectorise/Vectorise.hs @@ -1,15 +1,13 @@ -{-# OPTIONS_GHC -w #-} +{-# OPTIONS -w #-} -- The above warning supression flag is a temporary kludge. -- While working on this module you are encouraged to remove it and fix -- any warnings in the module. See --- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings -- for details module Vectorise( vectorise ) where -#include "HsVersions.h" - import VectMonad import VectUtils import VectType @@ -42,7 +40,7 @@ import Module ( Module ) import DsMonad hiding (mapAndUnzipM) import DsUtils ( mkCoreTup, mkCoreTupTy ) -import Literal ( Literal ) +import Literal ( Literal, mkMachInt ) import PrelNames import TysWiredIn import TysPrim ( intPrimTy ) @@ -51,6 +49,7 @@ import BasicTypes ( Boxity(..) ) import Outputable import FastString import Control.Monad ( liftM, liftM2, zipWithM, mapAndUnzipM ) +import Data.List ( sortBy, unzip4 ) vectorise :: HscEnv -> UniqSupply -> RuleBase -> ModGuts -> IO (SimplCount, ModGuts) @@ -69,10 +68,10 @@ vectModule :: ModGuts -> VM ModGuts 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) @@ -88,7 +87,8 @@ vectTopBind b@(NonRec var expr) var' <- vectTopBinder var expr' <- vectTopRhs var expr hs <- takeHoisted - return . Rec $ (var, expr) : (var', expr') : hs + cexpr <- tryConvert var var' expr + return . Rec $ (var, cexpr) : (var', expr') : hs `orElseV` return b @@ -97,7 +97,8 @@ vectTopBind b@(Rec bs) vars' <- mapM vectTopBinder vars exprs' <- zipWithM vectTopRhs vars exprs hs <- takeHoisted - return . Rec $ bs ++ zip vars' exprs' ++ hs + cexprs <- sequence $ zipWith3 tryConvert vars vars' exprs + return . Rec $ zip vars cexprs ++ zip vars' exprs' ++ hs `orElseV` return b where @@ -110,7 +111,7 @@ vectTopBinder var var' <- cloneId mkVectOcc var vty defGlobalVar var var' return var' - + vectTopRhs :: Var -> CoreExpr -> VM CoreExpr vectTopRhs var expr = do @@ -118,6 +119,10 @@ vectTopRhs var expr . inBind var $ vectPolyExpr (freeVars expr) +tryConvert :: Var -> Var -> CoreExpr -> VM CoreExpr +tryConvert var vect_var rhs + = fromVect (idType var) (Var vect_var) `orElseV` return rhs + -- ---------------------------------------------------------------------------- -- Bindings @@ -133,6 +138,16 @@ vectBndr v where mapTo vv lv env = env { local_vars = extendVarEnv (local_vars env) v (vv, lv) } +vectBndrNew :: Var -> FastString -> VM VVar +vectBndrNew v fs + = do + vty <- vectType (idType v) + vv <- newLocalVVar fs vty + updLEnv (upd vv) + return vv + where + upd vv env = env { local_vars = extendVarEnv (local_vars env) v vv } + vectBndrIn :: Var -> VM a -> VM (VVar, a) vectBndrIn v p = localV @@ -141,6 +156,14 @@ vectBndrIn v p x <- p return (vv, x) +vectBndrNewIn :: Var -> FastString -> VM a -> VM (VVar, a) +vectBndrNewIn v fs p + = localV + $ do + vv <- vectBndrNew v fs + x <- p + return (vv, x) + vectBndrIn' :: Var -> (VVar -> VM a) -> VM (VVar, a) vectBndrIn' v p = localV @@ -191,14 +214,16 @@ vectLiteral lit return (Lit lit, lexpr) vectPolyExpr :: CoreExprWithFVs -> VM VExpr +vectPolyExpr (_, AnnNote note expr) + = liftM (vNote note) $ vectPolyExpr expr vectPolyExpr expr = polyAbstract tvs $ \abstract -> do mono' <- vectExpr mono return $ mapVect abstract mono' where - (tvs, mono) = collectAnnTypeBinders expr - + (tvs, mono) = collectAnnTypeBinders expr + vectExpr :: CoreExprWithFVs -> VM VExpr vectExpr (_, AnnType ty) = liftM vType (vectType ty) @@ -216,6 +241,17 @@ vectExpr e@(_, AnnApp _ arg) where (fn, tys) = collectAnnTypeArgs e +vectExpr (_, AnnApp (_, AnnVar v) (_, AnnLit lit)) + | Just con <- isDataConId_maybe v + , is_special_con con + = do + let vexpr = App (Var v) (Lit lit) + lexpr <- liftPA vexpr + return (vexpr, lexpr) + where + is_special_con con = con `elem` [intDataCon, floatDataCon, doubleDataCon] + + vectExpr (_, AnnApp fn arg) = do arg_ty' <- vectType arg_ty @@ -227,8 +263,9 @@ vectExpr (_, AnnApp fn arg) (arg_ty, res_ty) = splitFunTy . exprType $ deAnnotate fn vectExpr (_, AnnCase scrut bndr ty alts) - | isAlgType scrut_ty - = vectAlgCase scrut bndr ty alts + | Just (tycon, ty_args) <- splitTyConApp_maybe scrut_ty + , isAlgTyCon tycon + = vectAlgCase tycon ty_args scrut bndr ty alts where scrut_ty = exprType (deAnnotate scrut) @@ -261,6 +298,8 @@ vectExpr e@(fvs, AnnLam bndr _) where (bs,body) = collectAnnValBinders e +vectExpr e = pprPanic "vectExpr" (ppr $ deAnnotate e) + vectLam :: VarSet -> [Var] -> CoreExprWithFVs -> VM VExpr vectLam fvs bs body = do @@ -279,7 +318,7 @@ vectLam fvs bs body (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) @@ -292,15 +331,16 @@ type CoreAltWithFVs = AnnAlt Id VarSet -- -- to -- --- V: let v = e in case v of _ { ... } --- L: let v = e in case v `cast` ... of _ { ... } +-- 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. --- +-- [: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)] +vectAlgCase tycon ty_args scrut bndr ty [(DEFAULT, [], body)] = do vscrut <- vectExpr scrut vty <- vectType ty @@ -308,20 +348,144 @@ vectAlgCase scrut bndr ty [(DEFAULT, [], body)] (vbndr, vbody) <- vectBndrIn bndr (vectExpr body) return $ vCaseDEFAULT vscrut vbndr vty lty vbody -vectAlgCase scrut bndr ty [(DataAlt dc, bndrs, body)] +vectAlgCase tycon ty_args scrut bndr ty [(DataAlt dc, [], 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)) <- vectBndrIn bndr + (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 - let shape_tys = take (dataConRepArity arr_dc - length bndrs) - (dataConRepArgTys arr_dc) - shape_bndrs <- mapM (newLocalVar FSLIT("s")) shape_tys + 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 vty 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) + 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) + $ Case len lc_var lty + [(DEFAULT, [], mkLets (concat bnds) 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') } +