Vectorise unlifted and tuple tycons
[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 TyCon
11 import Type
12 import TypeRep
13 import Var
14 import VarEnv
15 import Name                 ( mkSysTvName )
16 import NameEnv
17
18 import DsMonad
19
20 import PrelNames
21
22 import Outputable
23 import FastString
24 import Control.Monad        ( liftM2 )
25
26 vectorise :: HscEnv -> ModGuts -> IO ModGuts
27 vectorise hsc_env guts
28   | not (Opt_Vectorise `dopt` dflags) = return guts
29   | otherwise
30   = do
31       showPass dflags "Vectorisation"
32       eps <- hscEPS hsc_env
33       let info = hptVectInfo hsc_env `plusVectInfo` eps_vect_info eps
34       Just guts' <- initDs hsc_env (mg_module guts)
35                                    (mg_rdr_env guts)
36                                    (mg_types guts)
37                                    (vectoriseModule info guts)
38       endPass dflags "Vectorisation" Opt_D_dump_vect (mg_binds guts')
39       return guts'
40   where
41     dflags = hsc_dflags hsc_env
42
43 -- ----------------------------------------------------------------------------
44 -- Vectorisation monad
45
46 data Builtins = Builtins {
47                   parrayTyCon      :: TyCon
48                 , paTyCon          :: TyCon
49                 , closureTyCon     :: TyCon
50                 , mkClosureVar     :: Var
51                 , applyClosureVar  :: Var
52                 , mkClosurePVar    :: Var
53                 , applyClosurePVar :: Var
54                 , closurePAVar     :: Var
55                 , lengthPAVar      :: Var
56                 , replicatePAVar   :: Var
57                 }
58
59 initBuiltins :: DsM Builtins
60 initBuiltins
61   = do
62       parrayTyCon  <- dsLookupTyCon parrayTyConName
63       paTyCon      <- dsLookupTyCon paTyConName
64       closureTyCon <- dsLookupTyCon closureTyConName
65
66       mkClosureVar     <- dsLookupGlobalId mkClosureName
67       applyClosureVar  <- dsLookupGlobalId applyClosureName
68       mkClosurePVar    <- dsLookupGlobalId mkClosurePName
69       applyClosurePVar <- dsLookupGlobalId applyClosurePName
70       closurePAVar     <- dsLookupGlobalId closurePAName
71       lengthPAVar      <- dsLookupGlobalId lengthPAName
72       replicatePAVar   <- dsLookupGlobalId replicatePAName
73
74       return $ Builtins {
75                  parrayTyCon      = parrayTyCon
76                , paTyCon          = paTyCon
77                , closureTyCon     = closureTyCon
78                , mkClosureVar     = mkClosureVar
79                , applyClosureVar  = applyClosureVar
80                , mkClosurePVar    = mkClosurePVar
81                , applyClosurePVar = applyClosurePVar
82                , closurePAVar     = closurePAVar
83                , lengthPAVar      = lengthPAVar
84                , replicatePAVar   = replicatePAVar
85                }
86
87 data VEnv = VEnv {
88               -- Mapping from variables to their vectorised versions
89               --
90               vect_vars :: VarEnv Var
91
92               -- Exported variables which have a vectorised version
93               --
94             , vect_exported_vars :: VarEnv (Var, Var)
95
96               -- Mapping from TyCons to their vectorised versions.
97               -- TyCons which do not have to be vectorised are mapped to
98               -- themselves.
99             , vect_tycons :: NameEnv TyCon
100             }
101
102 initVEnv :: VectInfo -> DsM VEnv
103 initVEnv info
104   = return $ VEnv {
105                vect_vars          = mapVarEnv  snd $ vectInfoCCVar   info
106              , vect_exported_vars = emptyVarEnv
107              , vect_tycons        = mapNameEnv snd $ vectInfoCCTyCon info
108              }
109
110 -- FIXME
111 updVectInfo :: VEnv -> ModGuts -> ModGuts
112 updVectInfo env guts = guts { mg_vect_info = info' }
113   where
114     info' = info {
115               vectInfoCCVar   = vect_exported_vars env
116             , vectInfoCCTyCon = tc_env
117             }
118
119     info  = mg_vect_info guts
120     tyenv = mg_types guts
121
122     tc_env = mkNameEnv [(tc_name, (tc,tc')) | tc <- typeEnvTyCons tyenv
123                                             , let tc_name = tyConName tc
124                                             , Just tc' <- [lookupNameEnv (vect_tycons env) tc_name]]
125
126 newtype VM a = VM { runVM :: Builtins -> VEnv -> DsM (VEnv, a) }
127
128 instance Monad VM where
129   return x   = VM $ \bi env -> return (env, x)
130   VM p >>= f = VM $ \bi env -> do
131                                  (env', x) <- p bi env
132                                  runVM (f x) bi env'
133
134 liftDs :: DsM a -> VM a
135 liftDs p = VM $ \bi env -> do { x <- p; return (env, x) }
136
137 builtin :: (Builtins -> a) -> VM a
138 builtin f = VM $ \bi env -> return (env, f bi)
139
140 readEnv :: (VEnv -> a) -> VM a
141 readEnv f = VM $ \bi env -> return (env, f env)
142
143 setEnv :: VEnv -> VM ()
144 setEnv env = VM $ \_ _ -> return (env, ())
145
146 updEnv :: (VEnv -> VEnv) -> VM ()
147 updEnv f = VM $ \_ env -> return (f env, ())
148
149 newTyVar :: FastString -> Kind -> VM Var
150 newTyVar fs k
151   = do
152       u <- liftDs newUnique
153       return $ mkTyVar (mkSysTvName u fs) k
154
155 lookupTyCon :: TyCon -> VM (Maybe TyCon)
156 lookupTyCon tc = readEnv $ \env -> lookupNameEnv (vect_tycons env) (tyConName tc)
157
158 -- ----------------------------------------------------------------------------
159 -- Bindings
160
161 vectoriseModule :: VectInfo -> ModGuts -> DsM ModGuts
162 vectoriseModule info guts
163   = do
164       builtins <- initBuiltins
165       env <- initVEnv info
166       (env', guts') <- runVM (vectModule guts) builtins env
167       return $ updVectInfo env' guts'
168
169 vectModule :: ModGuts -> VM ModGuts
170 vectModule guts = return guts
171
172 -- ----------------------------------------------------------------------------
173 -- Types
174
175 paArgType :: Type -> Kind -> VM (Maybe Type)
176 paArgType ty k
177   | Just k' <- kindView k = paArgType ty k'
178
179 -- Here, we assume that for a kind (k1 -> k2) to be valid, k1 and k2 can only
180 -- be made up of * and (->), i.e., they can't be coercion kinds or #.
181 paArgType ty (FunTy k1 k2)
182   = do
183       tv  <- newTyVar FSLIT("a") k1
184       ty1 <- paArgType' (TyVarTy tv) k1
185       ty2 <- paArgType' (AppTy ty (TyVarTy tv)) k2
186       return . Just $ ForAllTy tv (FunTy ty1 ty2)
187
188 paArgType ty k
189   | isLiftedTypeKind k
190   = do
191       tc <- builtin paTyCon
192       return . Just $ TyConApp tc [ty]
193
194   | otherwise
195   = return Nothing 
196
197 paArgType' :: Type -> Kind -> VM Type
198 paArgType' ty k
199   = do
200       r <- paArgType ty k
201       case r of
202         Just ty' -> return ty'
203         Nothing  -> pprPanic "paArgType'" (ppr ty)
204
205 vectTyCon :: TyCon -> VM TyCon
206 vectTyCon tc
207   | isFunTyCon tc        = builtin closureTyCon
208   | isBoxedTupleTyCon tc = return tc
209   | isUnLiftedTyCon tc   = return tc
210   | otherwise = do
211                   r <- lookupTyCon tc
212                   case r of
213                     Just tc' -> return tc'
214
215                     -- FIXME: just for now
216                     Nothing  -> pprTrace "ccTyCon:" (ppr tc) $ return tc
217
218 vectType :: Type -> VM Type
219 vectType ty | Just ty' <- coreView ty = vectType ty
220 vectType (TyVarTy tv) = return $ TyVarTy tv
221 vectType (AppTy ty1 ty2) = liftM2 AppTy (vectType ty1) (vectType ty2)
222 vectType (TyConApp tc tys) = liftM2 TyConApp (vectTyCon tc) (mapM vectType tys)
223 vectType (FunTy ty1 ty2)   = liftM2 TyConApp (builtin closureTyCon)
224                                              (mapM vectType [ty1,ty2])
225 vectType (ForAllTy tv ty)
226   = do
227       r   <- paArgType (TyVarTy tv) (tyVarKind tv)
228       ty' <- vectType ty
229       return . ForAllTy tv $ case r of { Just paty -> FunTy paty ty'; Nothing -> ty' }
230
231 vectType ty = pprPanic "vectType:" (ppr ty)
232