Make sure some TyCons always vectorise to themselves
[ghc-hetmet.git] / compiler / vectorise / VectBuiltIn.hs
1 {-# OPTIONS -w #-}
2 -- The above warning supression flag is a temporary kludge.
3 -- While working on this module you are encouraged to remove it and fix
4 -- any warnings in the module. See
5 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
6 -- for details
7
8 module VectBuiltIn (
9   Builtins(..), sumTyCon, prodTyCon, combinePAVar,
10   initBuiltins, initBuiltinTyCons, initBuiltinPAs, initBuiltinPRs,
11
12   primMethod, primPArray
13 ) where
14
15 #include "HsVersions.h"
16
17 import DsMonad
18 import IfaceEnv        ( lookupOrig )
19
20 import Module          ( Module )
21 import DataCon         ( DataCon )
22 import TyCon           ( TyCon, tyConName, tyConDataCons )
23 import Var             ( Var )
24 import Id              ( mkSysLocal )
25 import Name            ( Name, getOccString )
26 import NameEnv
27 import OccName
28
29 import TypeRep         ( funTyCon )
30 import Type            ( Type )
31 import TysPrim
32 import TysWiredIn      ( unitTyCon, tupleTyCon, intTyConName )
33 import Module
34 import BasicTypes      ( Boxity(..) )
35
36 import FastString
37 import Outputable
38
39 import Data.Array
40 import Control.Monad   ( liftM, zipWithM )
41
42 mAX_NDP_PROD :: Int
43 mAX_NDP_PROD = 3
44
45 mAX_NDP_SUM :: Int
46 mAX_NDP_SUM = 3
47
48 mAX_NDP_COMBINE :: Int
49 mAX_NDP_COMBINE = 2
50
51 mkNDPModule :: FastString -> Module
52 mkNDPModule m = mkModule ndpPackageId (mkModuleNameFS m)
53
54 nDP_PARRAY      = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.PArray")
55 nDP_REPR        = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Repr")
56 nDP_CLOSURE     = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Closure")
57 nDP_PRIM        = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Prim")
58 nDP_INSTANCES   = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Instances")
59
60 data Builtins = Builtins {
61                   parrayTyCon      :: TyCon
62                 , paTyCon          :: TyCon
63                 , paDataCon        :: DataCon
64                 , preprTyCon       :: TyCon
65                 , prTyCon          :: TyCon
66                 , prDataCon        :: DataCon
67                 , parrayIntPrimTyCon :: TyCon
68                 , parrayBoolPrimTyCon :: TyCon
69                 , voidTyCon        :: TyCon
70                 , wrapTyCon        :: TyCon
71                 , sumTyCons        :: Array Int TyCon
72                 , closureTyCon     :: TyCon
73                 , voidVar          :: Var
74                 , mkPRVar          :: Var
75                 , mkClosureVar     :: Var
76                 , applyClosureVar  :: Var
77                 , mkClosurePVar    :: Var
78                 , applyClosurePVar :: Var
79                 , replicatePAIntPrimVar :: Var
80                 , upToPAIntPrimVar :: Var
81                 , selectPAIntPrimVar :: Var
82                 , truesPABoolPrimVar :: Var
83                 , lengthPAVar      :: Var
84                 , replicatePAVar   :: Var
85                 , emptyPAVar       :: Var
86                 , packPAVar        :: Var
87                 , combinePAVars    :: Array Int Var
88                 , liftingContext   :: Var
89                 }
90
91 sumTyCon :: Int -> Builtins -> TyCon
92 sumTyCon n bi
93   | n >= 2 && n <= mAX_NDP_SUM = sumTyCons bi ! n
94   | otherwise = pprPanic "sumTyCon" (ppr n)
95
96 prodTyCon :: Int -> Builtins -> TyCon
97 prodTyCon n bi
98   | n == 1                      = wrapTyCon bi
99   | n >= 0 && n <= mAX_NDP_PROD = tupleTyCon Boxed n
100   | otherwise = pprPanic "prodTyCon" (ppr n)
101
102 combinePAVar :: Int -> Builtins -> Var
103 combinePAVar n bi
104   | n >= 2 && n <= mAX_NDP_COMBINE = combinePAVars bi ! n
105   | otherwise = pprPanic "combinePAVar" (ppr n)
106
107 initBuiltins :: DsM Builtins
108 initBuiltins
109   = do
110       parrayTyCon  <- externalTyCon nDP_PARRAY FSLIT("PArray")
111       paTyCon      <- externalTyCon nDP_PARRAY FSLIT("PA")
112       let [paDataCon] = tyConDataCons paTyCon
113       preprTyCon   <- externalTyCon nDP_PARRAY FSLIT("PRepr")
114       prTyCon      <- externalTyCon nDP_PARRAY FSLIT("PR")
115       let [prDataCon] = tyConDataCons prTyCon
116       parrayIntPrimTyCon <- externalTyCon nDP_PRIM FSLIT("PArray_Int#")
117       parrayBoolPrimTyCon <- externalTyCon nDP_PRIM FSLIT("PArray_Bool#")
118       closureTyCon <- externalTyCon nDP_CLOSURE FSLIT(":->")
119
120       voidTyCon    <- externalTyCon nDP_REPR FSLIT("Void")
121       wrapTyCon    <- externalTyCon nDP_REPR FSLIT("Wrap")
122       sum_tcs <- mapM (externalTyCon nDP_REPR)
123                       [mkFastString ("Sum" ++ show i) | i <- [2..mAX_NDP_SUM]]
124
125       let sumTyCons = listArray (2, mAX_NDP_SUM) sum_tcs
126
127       voidVar          <- externalVar nDP_REPR FSLIT("void")
128       mkPRVar          <- externalVar nDP_PARRAY FSLIT("mkPR")
129       mkClosureVar     <- externalVar nDP_CLOSURE FSLIT("mkClosure")
130       applyClosureVar  <- externalVar nDP_CLOSURE FSLIT("$:")
131       mkClosurePVar    <- externalVar nDP_CLOSURE FSLIT("mkClosureP")
132       applyClosurePVar <- externalVar nDP_CLOSURE FSLIT("$:^")
133       replicatePAIntPrimVar <- externalVar nDP_PRIM FSLIT("replicatePA_Int#")
134       upToPAIntPrimVar <- externalVar nDP_PRIM FSLIT("upToPA_Int#")
135       selectPAIntPrimVar <- externalVar nDP_PRIM FSLIT("selectPA_Int#")
136       truesPABoolPrimVar <- externalVar nDP_PRIM FSLIT("truesPA_Bool#")
137       lengthPAVar      <- externalVar nDP_PARRAY FSLIT("lengthPA")
138       replicatePAVar   <- externalVar nDP_PARRAY FSLIT("replicatePA")
139       emptyPAVar       <- externalVar nDP_PARRAY FSLIT("emptyPA")
140       packPAVar        <- externalVar nDP_PARRAY FSLIT("packPA")
141
142       combines <- mapM (externalVar nDP_PARRAY)
143                        [mkFastString ("combine" ++ show i ++ "PA")
144                           | i <- [2..mAX_NDP_COMBINE]]
145       let combinePAVars = listArray (2, mAX_NDP_COMBINE) combines
146
147       liftingContext <- liftM (\u -> mkSysLocal FSLIT("lc") u intPrimTy)
148                               newUnique
149
150       return $ Builtins {
151                  parrayTyCon      = parrayTyCon
152                , paTyCon          = paTyCon
153                , paDataCon        = paDataCon
154                , preprTyCon       = preprTyCon
155                , prTyCon          = prTyCon
156                , prDataCon        = prDataCon
157                , parrayIntPrimTyCon = parrayIntPrimTyCon
158                , parrayBoolPrimTyCon = parrayBoolPrimTyCon
159                , voidTyCon        = voidTyCon
160                , wrapTyCon        = wrapTyCon
161                , sumTyCons        = sumTyCons
162                , closureTyCon     = closureTyCon
163                , voidVar          = voidVar
164                , mkPRVar          = mkPRVar
165                , mkClosureVar     = mkClosureVar
166                , applyClosureVar  = applyClosureVar
167                , mkClosurePVar    = mkClosurePVar
168                , applyClosurePVar = applyClosurePVar
169                , replicatePAIntPrimVar = replicatePAIntPrimVar
170                , upToPAIntPrimVar = upToPAIntPrimVar
171                , selectPAIntPrimVar = selectPAIntPrimVar
172                , truesPABoolPrimVar = truesPABoolPrimVar
173                , lengthPAVar      = lengthPAVar
174                , replicatePAVar   = replicatePAVar
175                , emptyPAVar       = emptyPAVar
176                , packPAVar        = packPAVar
177                , combinePAVars    = combinePAVars
178                , liftingContext   = liftingContext
179                }
180
181 initBuiltinTyCons :: Builtins -> [(Name, TyCon)]
182 initBuiltinTyCons bi = (tyConName funTyCon, closureTyCon bi)
183                      : [(tyConName tc, tc) | tc <- defaultTyCons]
184
185 defaultTyCons :: [TyCon]
186 defaultTyCons = [intTyCon]
187
188 initBuiltinDicts :: [(Name, Module, FastString)] -> DsM [(Name, Var)]
189 initBuiltinDicts ps
190   = do
191       dicts <- zipWithM externalVar mods fss
192       return $ zip tcs dicts
193   where
194     (tcs, mods, fss) = unzip3 ps
195
196 initBuiltinPAs = initBuiltinDicts . builtinPAs
197
198 builtinPAs :: Builtins -> [(Name, Module, FastString)]
199 builtinPAs bi
200   = [
201       mk (tyConName $ closureTyCon bi)  nDP_CLOSURE     FSLIT("dPA_Clo")
202     , mk (tyConName $ voidTyCon bi)     nDP_REPR        FSLIT("dPA_Void")
203     , mk unitTyConName                  nDP_INSTANCES   FSLIT("dPA_Unit")
204
205     , mk intTyConName                   nDP_INSTANCES   FSLIT("dPA_Int")
206     ]
207     ++ tups
208   where
209     mk name mod fs = (name, mod, fs)
210
211     tups = map mk_tup [2..3]
212     mk_tup n = mk (tyConName $ tupleTyCon Boxed n)
213                   nDP_INSTANCES
214                   (mkFastString $ "dPA_" ++ show n)
215
216 initBuiltinPRs = initBuiltinDicts . builtinPRs
217
218 builtinPRs :: Builtins -> [(Name, Module, FastString)]
219 builtinPRs bi =
220   [
221     mk (tyConName unitTyCon)          nDP_REPR      FSLIT("dPR_Unit")
222   , mk (tyConName $ voidTyCon bi)     nDP_REPR      FSLIT("dPR_Void")
223   , mk (tyConName $ wrapTyCon bi)     nDP_REPR      FSLIT("dPR_Wrap")
224   , mk (tyConName $ closureTyCon bi)  nDP_CLOSURE   FSLIT("dPR_Clo")
225
226     -- temporary
227   , mk intTyConName          nDP_INSTANCES FSLIT("dPR_Int")
228   ]
229
230   ++ map mk_sum  [2..mAX_NDP_SUM]
231   ++ map mk_prod [2..mAX_NDP_PROD]
232   where
233     mk name mod fs = (name, mod, fs)
234
235     mk_sum n = (tyConName $ sumTyCon n bi, nDP_REPR,
236                 mkFastString ("dPR_Sum" ++ show n))
237
238     mk_prod n = (tyConName $ prodTyCon n bi, nDP_REPR,
239                  mkFastString ("dPR_" ++ show n))
240
241 externalVar :: Module -> FastString -> DsM Var
242 externalVar mod fs
243   = dsLookupGlobalId =<< lookupOrig mod (mkVarOccFS fs)
244
245 externalTyCon :: Module -> FastString -> DsM TyCon
246 externalTyCon mod fs
247   = dsLookupTyCon =<< lookupOrig mod (mkOccNameFS tcName fs)
248
249 unitTyConName = tyConName unitTyCon
250
251
252 primMethod :: TyCon -> String -> DsM (Maybe Var)
253 primMethod tycon method
254   | Just suffix <- lookupNameEnv prim_ty_cons (tyConName tycon)
255   = liftM Just
256   $ dsLookupGlobalId =<< lookupOrig nDP_PRIM (mkVarOcc $ method ++ suffix)
257
258   | otherwise = return Nothing
259
260 primPArray :: TyCon -> DsM (Maybe TyCon)
261 primPArray tycon
262   | Just suffix <- lookupNameEnv prim_ty_cons (tyConName tycon)
263   = liftM Just
264   $ dsLookupTyCon =<< lookupOrig nDP_PRIM (mkOccName tcName $ "PArray" ++ suffix)
265
266   | otherwise = return Nothing
267
268 prim_ty_cons = mkNameEnv [mk_prim intPrimTyCon]
269   where
270     mk_prim tycon = (tyConName tycon, '_' : getOccString tycon)