Vectorisation-specific imports
[ghc-hetmet.git] / compiler / vectorise / Vectorise.hs
1 module Vectorise( vectorise )
2 where
3
4 #include "HsVersions.h"
5
6 import DynFlags
7 import HscTypes
8
9 import CoreLint             ( showPass, endPass )
10 import CoreSyn
11 import CoreUtils
12 import CoreFVs
13 import TyCon
14 import Type
15 import TypeRep
16 import Var
17 import VarEnv
18 import Name                 ( mkSysTvName )
19 import NameEnv
20
21 import DsMonad
22
23 import PrelNames
24
25 import Outputable
26 import FastString
27 import Control.Monad        ( liftM2 )
28
29 vectorise :: HscEnv -> ModGuts -> IO ModGuts
30 vectorise hsc_env guts
31   | not (Opt_Vectorise `dopt` dflags) = return guts
32   | otherwise
33   = do
34       showPass dflags "Vectorisation"
35       eps <- hscEPS hsc_env
36       let info = hptVectInfo hsc_env `plusVectInfo` eps_vect_info eps
37       Just guts' <- initDs hsc_env (mg_module guts)
38                                    (mg_rdr_env guts)
39                                    (mg_types guts)
40                                    (vectoriseModule info guts)
41       endPass dflags "Vectorisation" Opt_D_dump_vect (mg_binds guts')
42       return guts'
43   where
44     dflags = hsc_dflags hsc_env
45
46 -- ----------------------------------------------------------------------------
47 -- Vectorisation monad
48
49 data Builtins = Builtins {
50                   parrayTyCon      :: TyCon
51                 , paTyCon          :: TyCon
52                 , closureTyCon     :: TyCon
53                 , mkClosureVar     :: Var
54                 , applyClosureVar  :: Var
55                 , mkClosurePVar    :: Var
56                 , applyClosurePVar :: Var
57                 , closurePAVar     :: Var
58                 , lengthPAVar      :: Var
59                 , replicatePAVar   :: Var
60                 }
61
62 initBuiltins :: DsM Builtins
63 initBuiltins
64   = do
65       parrayTyCon  <- dsLookupTyCon parrayTyConName
66       paTyCon      <- dsLookupTyCon paTyConName
67       closureTyCon <- dsLookupTyCon closureTyConName
68
69       mkClosureVar     <- dsLookupGlobalId mkClosureName
70       applyClosureVar  <- dsLookupGlobalId applyClosureName
71       mkClosurePVar    <- dsLookupGlobalId mkClosurePName
72       applyClosurePVar <- dsLookupGlobalId applyClosurePName
73       closurePAVar     <- dsLookupGlobalId closurePAName
74       lengthPAVar      <- dsLookupGlobalId lengthPAName
75       replicatePAVar   <- dsLookupGlobalId replicatePAName
76
77       return $ Builtins {
78                  parrayTyCon      = parrayTyCon
79                , paTyCon          = paTyCon
80                , closureTyCon     = closureTyCon
81                , mkClosureVar     = mkClosureVar
82                , applyClosureVar  = applyClosureVar
83                , mkClosurePVar    = mkClosurePVar
84                , applyClosurePVar = applyClosurePVar
85                , closurePAVar     = closurePAVar
86                , lengthPAVar      = lengthPAVar
87                , replicatePAVar   = replicatePAVar
88                }
89
90 data VEnv = VEnv {
91               -- Mapping from global variables to their vectorised versions.
92               -- 
93               vect_global_vars :: VarEnv CoreExpr
94
95               -- Mapping from local variables to their vectorised and lifted
96               -- versions.
97               --
98             , vect_local_vars :: VarEnv (CoreExpr, CoreExpr)
99
100               -- Exported variables which have a vectorised version
101               --
102             , vect_exported_vars :: VarEnv (Var, Var)
103
104               -- Mapping from TyCons to their vectorised versions.
105               -- TyCons which do not have to be vectorised are mapped to
106               -- themselves.
107               --
108             , vect_tycons :: NameEnv TyCon
109
110               -- Mapping from TyCons to their PA dictionaries
111               --
112             , vect_tycon_pa :: NameEnv CoreExpr
113
114               -- Mapping from tyvars to their PA dictionaries
115               --
116             , vect_tyvar_pa :: VarEnv CoreExpr
117             }
118
119 initVEnv :: VectInfo -> DsM VEnv
120 initVEnv info
121   = return $ VEnv {
122                vect_global_vars   = mapVarEnv  (Var . snd) $ vectInfoCCVar   info
123              , vect_local_vars    = emptyVarEnv
124              , vect_exported_vars = emptyVarEnv
125              , vect_tycons        = mapNameEnv snd $ vectInfoCCTyCon info
126              , vect_tycon_pa      = emptyNameEnv
127              , vect_tyvar_pa      = emptyVarEnv
128              }
129
130 -- FIXME
131 updVectInfo :: VEnv -> ModGuts -> ModGuts
132 updVectInfo env guts = guts { mg_vect_info = info' }
133   where
134     info' = info {
135               vectInfoCCVar   = vect_exported_vars env
136             , vectInfoCCTyCon = tc_env
137             }
138
139     info  = mg_vect_info guts
140     tyenv = mg_types guts
141
142     tc_env = mkNameEnv [(tc_name, (tc,tc')) | tc <- typeEnvTyCons tyenv
143                                             , let tc_name = tyConName tc
144                                             , Just tc' <- [lookupNameEnv (vect_tycons env) tc_name]]
145
146 data VResult a = Yes VEnv a | No
147
148 newtype VM a = VM { runVM :: Builtins -> VEnv -> DsM (VResult a) }
149
150 instance Monad VM where
151   return x   = VM $ \bi env -> return (Yes env x)
152   VM p >>= f = VM $ \bi env -> do
153                                  r <- p bi env
154                                  case r of
155                                    Yes env' x -> runVM (f x) bi env'
156                                    No         -> return No
157
158 noV :: VM a
159 noV = VM $ \bi env -> return No
160
161 tryV :: VM a -> VM (Maybe a)
162 tryV (VM p) = VM $ \bi env -> do
163                                 r <- p bi env
164                                 case r of
165                                   Yes env' x -> return (Yes env' (Just x))
166                                   No         -> return (Yes env Nothing)
167
168 maybeV :: VM (Maybe a) -> VM a
169 maybeV p = maybe noV return =<< p
170
171 orElseV :: VM a -> VM a -> VM a
172 orElseV p q = maybe q return =<< tryV p
173
174 liftDs :: DsM a -> VM a
175 liftDs p = VM $ \bi env -> do { x <- p; return (Yes env x) }
176
177 builtin :: (Builtins -> a) -> VM a
178 builtin f = VM $ \bi env -> return (Yes env (f bi))
179
180 readEnv :: (VEnv -> a) -> VM a
181 readEnv f = VM $ \bi env -> return (Yes env (f env))
182
183 setEnv :: VEnv -> VM ()
184 setEnv env = VM $ \_ _ -> return (Yes env ())
185
186 updEnv :: (VEnv -> VEnv) -> VM ()
187 updEnv f = VM $ \_ env -> return (Yes (f env) ())
188
189 newTyVar :: FastString -> Kind -> VM Var
190 newTyVar fs k
191   = do
192       u <- liftDs newUnique
193       return $ mkTyVar (mkSysTvName u fs) k
194
195 lookupVar :: Var -> VM CoreExpr
196 lookupVar v = maybeV . readEnv $ \env -> lookupVarEnv (vect_vars env) v
197
198 lookupTyCon :: TyCon -> VM (Maybe TyCon)
199 lookupTyCon tc = readEnv $ \env -> lookupNameEnv (vect_tycons env) (tyConName tc)
200
201 -- ----------------------------------------------------------------------------
202 -- Bindings
203
204 vectoriseModule :: VectInfo -> ModGuts -> DsM ModGuts
205 vectoriseModule info guts
206   = do
207       builtins <- initBuiltins
208       env <- initVEnv info
209       r <- runVM (vectModule guts) builtins env
210       case r of
211         Yes env' guts' -> return $ updVectInfo env' guts'
212         No             -> return guts
213
214 vectModule :: ModGuts -> VM ModGuts
215 vectModule guts = return guts
216
217 -- ----------------------------------------------------------------------------
218 -- Types
219
220 paArgType :: Type -> Kind -> VM (Maybe Type)
221 paArgType ty k
222   | Just k' <- kindView k = paArgType ty k'
223
224 -- Here, we assume that for a kind (k1 -> k2) to be valid, k1 and k2 can only
225 -- be made up of * and (->), i.e., they can't be coercion kinds or #.
226 paArgType ty (FunTy k1 k2)
227   = do
228       tv  <- newTyVar FSLIT("a") k1
229       ty1 <- paArgType' (TyVarTy tv) k1
230       ty2 <- paArgType' (AppTy ty (TyVarTy tv)) k2
231       return . Just $ ForAllTy tv (FunTy ty1 ty2)
232
233 paArgType ty k
234   | isLiftedTypeKind k
235   = do
236       tc <- builtin paTyCon
237       return . Just $ TyConApp tc [ty]
238
239   | otherwise
240   = return Nothing 
241
242 paArgType' :: Type -> Kind -> VM Type
243 paArgType' ty k
244   = do
245       r <- paArgType ty k
246       case r of
247         Just ty' -> return ty'
248         Nothing  -> pprPanic "paArgType'" (ppr ty)
249
250 vectTyCon :: TyCon -> VM TyCon
251 vectTyCon tc
252   | isFunTyCon tc        = builtin closureTyCon
253   | isBoxedTupleTyCon tc = return tc
254   | isUnLiftedTyCon tc   = return tc
255   | otherwise = do
256                   r <- lookupTyCon tc
257                   case r of
258                     Just tc' -> return tc'
259
260                     -- FIXME: just for now
261                     Nothing  -> pprTrace "ccTyCon:" (ppr tc) $ return tc
262
263 vectType :: Type -> VM Type
264 vectType ty | Just ty' <- coreView ty = vectType ty
265 vectType (TyVarTy tv) = return $ TyVarTy tv
266 vectType (AppTy ty1 ty2) = liftM2 AppTy (vectType ty1) (vectType ty2)
267 vectType (TyConApp tc tys) = liftM2 TyConApp (vectTyCon tc) (mapM vectType tys)
268 vectType (FunTy ty1 ty2)   = liftM2 TyConApp (builtin closureTyCon)
269                                              (mapM vectType [ty1,ty2])
270 vectType (ForAllTy tv ty)
271   = do
272       r   <- paArgType (TyVarTy tv) (tyVarKind tv)
273       ty' <- vectType ty
274       return . ForAllTy tv $ case r of { Just paty -> FunTy paty ty'; Nothing -> ty' }
275
276 vectType ty = pprPanic "vectType:" (ppr ty)
277
278 isClosureTyCon :: TyCon -> Bool
279 isClosureTyCon tc = tyConUnique tc == closureTyConKey
280
281 splitClosureTy :: Type -> (Type, Type)
282 splitClosureTy ty
283   | Just (tc, [arg_ty, res_ty]) <- splitTyConApp_maybe ty
284   , isClosureTyCon tc
285   = (arg_ty, res_ty)
286
287   | otherwise = pprPanic "splitClosureTy" (ppr ty)
288