eliminate a bit of duplication
[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,
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 mkNDPModule :: FastString -> Module
49 mkNDPModule m = mkModule ndpPackageId (mkModuleNameFS m)
50
51 nDP_PARRAY      = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.PArray")
52 nDP_REPR        = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Repr")
53 nDP_CLOSURE     = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Closure")
54 nDP_PRIM        = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Prim")
55 nDP_INSTANCES   = mkNDPModule FSLIT("Data.Array.Parallel.Lifted.Instances")
56
57 data Builtins = Builtins {
58                   parrayTyCon      :: TyCon
59                 , paTyCon          :: TyCon
60                 , paDataCon        :: DataCon
61                 , preprTyCon       :: TyCon
62                 , prTyCon          :: TyCon
63                 , prDataCon        :: DataCon
64                 , parrayIntPrimTyCon :: TyCon
65                 , voidTyCon        :: TyCon
66                 , wrapTyCon        :: TyCon
67                 , sumTyCons        :: Array Int TyCon
68                 , closureTyCon     :: TyCon
69                 , voidVar          :: Var
70                 , mkPRVar          :: Var
71                 , mkClosureVar     :: Var
72                 , applyClosureVar  :: Var
73                 , mkClosurePVar    :: Var
74                 , applyClosurePVar :: Var
75                 , replicatePAIntPrimVar :: Var
76                 , upToPAIntPrimVar :: Var
77                 , lengthPAVar      :: Var
78                 , replicatePAVar   :: Var
79                 , emptyPAVar       :: Var
80                 -- , packPAVar        :: Var
81                 -- , combinePAVar     :: Var
82                 , liftingContext   :: Var
83                 }
84
85 sumTyCon :: Int -> Builtins -> TyCon
86 sumTyCon n bi
87   | n >= 2 && n <= mAX_NDP_SUM = sumTyCons bi ! n
88   | otherwise = pprPanic "sumTyCon" (ppr n)
89
90 prodTyCon :: Int -> Builtins -> TyCon
91 prodTyCon n bi
92   | n == 1                      = wrapTyCon bi
93   | n >= 0 && n <= mAX_NDP_PROD = tupleTyCon Boxed n
94   | otherwise = pprPanic "prodTyCon" (ppr n)
95
96 initBuiltins :: DsM Builtins
97 initBuiltins
98   = do
99       parrayTyCon  <- externalTyCon nDP_PARRAY FSLIT("PArray")
100       paTyCon      <- externalTyCon nDP_PARRAY FSLIT("PA")
101       let [paDataCon] = tyConDataCons paTyCon
102       preprTyCon   <- externalTyCon nDP_PARRAY FSLIT("PRepr")
103       prTyCon      <- externalTyCon nDP_PARRAY FSLIT("PR")
104       let [prDataCon] = tyConDataCons prTyCon
105       parrayIntPrimTyCon <- externalTyCon nDP_PRIM FSLIT("PArray_Int#")
106       closureTyCon <- externalTyCon nDP_CLOSURE FSLIT(":->")
107
108       voidTyCon    <- externalTyCon nDP_REPR FSLIT("Void")
109       wrapTyCon    <- externalTyCon nDP_REPR FSLIT("Wrap")
110       sum_tcs <- mapM (externalTyCon nDP_REPR)
111                       [mkFastString ("Sum" ++ show i) | i <- [2..mAX_NDP_SUM]]
112
113       let sumTyCons = listArray (2, mAX_NDP_SUM) sum_tcs
114
115       voidVar          <- externalVar nDP_REPR FSLIT("void")
116       mkPRVar          <- externalVar nDP_PARRAY FSLIT("mkPR")
117       mkClosureVar     <- externalVar nDP_CLOSURE FSLIT("mkClosure")
118       applyClosureVar  <- externalVar nDP_CLOSURE FSLIT("$:")
119       mkClosurePVar    <- externalVar nDP_CLOSURE FSLIT("mkClosureP")
120       applyClosurePVar <- externalVar nDP_CLOSURE FSLIT("$:^")
121       replicatePAIntPrimVar <- externalVar nDP_PRIM FSLIT("replicatePA_Int#")
122       upToPAIntPrimVar <- externalVar nDP_PRIM FSLIT("upToPA_Int#")
123       lengthPAVar      <- externalVar nDP_PARRAY FSLIT("lengthPA")
124       replicatePAVar   <- externalVar nDP_PARRAY FSLIT("replicatePA")
125       emptyPAVar       <- externalVar nDP_PARRAY FSLIT("emptyPA")
126       -- packPAVar        <- dsLookupGlobalId packPAName
127       -- combinePAVar     <- dsLookupGlobalId combinePAName
128
129       liftingContext <- liftM (\u -> mkSysLocal FSLIT("lc") u intPrimTy)
130                               newUnique
131
132       return $ Builtins {
133                  parrayTyCon      = parrayTyCon
134                , paTyCon          = paTyCon
135                , paDataCon        = paDataCon
136                , preprTyCon       = preprTyCon
137                , prTyCon          = prTyCon
138                , prDataCon        = prDataCon
139                , parrayIntPrimTyCon = parrayIntPrimTyCon
140                , voidTyCon        = voidTyCon
141                , wrapTyCon        = wrapTyCon
142                , sumTyCons        = sumTyCons
143                , closureTyCon     = closureTyCon
144                , voidVar          = voidVar
145                , mkPRVar          = mkPRVar
146                , mkClosureVar     = mkClosureVar
147                , applyClosureVar  = applyClosureVar
148                , mkClosurePVar    = mkClosurePVar
149                , applyClosurePVar = applyClosurePVar
150                , replicatePAIntPrimVar = replicatePAIntPrimVar
151                , upToPAIntPrimVar = upToPAIntPrimVar
152                , lengthPAVar      = lengthPAVar
153                , replicatePAVar   = replicatePAVar
154                , emptyPAVar       = emptyPAVar
155                -- , packPAVar        = packPAVar
156                -- , combinePAVar     = combinePAVar
157                , liftingContext   = liftingContext
158                }
159
160 initBuiltinTyCons :: Builtins -> [(Name, TyCon)]
161 initBuiltinTyCons bi = [(tyConName funTyCon, closureTyCon bi)]
162
163 initBuiltinDicts :: [(Name, Module, FastString)] -> DsM [(Name, Var)]
164 initBuiltinDicts ps
165   = do
166       dicts <- zipWithM externalVar mods fss
167       return $ zip tcs dicts
168   where
169     (tcs, mods, fss) = unzip3 ps
170
171 initBuiltinPAs = initBuiltinDicts . builtinPAs
172
173 builtinPAs :: Builtins -> [(Name, Module, FastString)]
174 builtinPAs bi
175   = [
176       mk (tyConName $ closureTyCon bi)  nDP_CLOSURE     FSLIT("dPA_Clo")
177     , mk (tyConName $ voidTyCon bi)     nDP_REPR        FSLIT("dPA_Void")
178     , mk unitTyConName                  nDP_INSTANCES   FSLIT("dPA_Unit")
179
180     , mk intTyConName                   nDP_INSTANCES   FSLIT("dPA_Int")
181     ]
182     ++ tups
183   where
184     mk name mod fs = (name, mod, fs)
185
186     tups = map mk_tup [2..3]
187     mk_tup n = mk (tyConName $ tupleTyCon Boxed n)
188                   nDP_INSTANCES
189                   (mkFastString $ "dPA_" ++ show n)
190
191 initBuiltinPRs = initBuiltinDicts . builtinPRs
192
193 builtinPRs :: Builtins -> [(Name, Module, FastString)]
194 builtinPRs bi =
195   [
196     mk (tyConName unitTyCon)          nDP_REPR      FSLIT("dPR_Unit")
197   , mk (tyConName $ voidTyCon bi)     nDP_REPR      FSLIT("dPR_Void")
198   , mk (tyConName $ wrapTyCon bi)     nDP_REPR      FSLIT("dPR_Wrap")
199   , mk (tyConName $ closureTyCon bi)  nDP_CLOSURE   FSLIT("dPR_Clo")
200
201     -- temporary
202   , mk intTyConName          nDP_INSTANCES FSLIT("dPR_Int")
203   ]
204
205   ++ map mk_sum  [2..mAX_NDP_SUM]
206   ++ map mk_prod [2..mAX_NDP_PROD]
207   where
208     mk name mod fs = (name, mod, fs)
209
210     mk_sum n = (tyConName $ sumTyCon n bi, nDP_REPR,
211                 mkFastString ("dPR_Sum" ++ show n))
212
213     mk_prod n = (tyConName $ prodTyCon n bi, nDP_REPR,
214                  mkFastString ("dPR_" ++ show n))
215
216 externalVar :: Module -> FastString -> DsM Var
217 externalVar mod fs
218   = dsLookupGlobalId =<< lookupOrig mod (mkVarOccFS fs)
219
220 externalTyCon :: Module -> FastString -> DsM TyCon
221 externalTyCon mod fs
222   = dsLookupTyCon =<< lookupOrig mod (mkOccNameFS tcName fs)
223
224 unitTyConName = tyConName unitTyCon
225
226
227 primMethod :: TyCon -> String -> DsM (Maybe Var)
228 primMethod tycon method
229   | Just suffix <- lookupNameEnv prim_ty_cons (tyConName tycon)
230   = liftM Just
231   $ dsLookupGlobalId =<< lookupOrig nDP_PRIM (mkVarOcc $ method ++ suffix)
232
233   | otherwise = return Nothing
234
235 primPArray :: TyCon -> DsM (Maybe TyCon)
236 primPArray tycon
237   | Just suffix <- lookupNameEnv prim_ty_cons (tyConName tycon)
238   = liftM Just
239   $ dsLookupTyCon =<< lookupOrig nDP_PRIM (mkOccName tcName $ "PArray" ++ suffix)
240
241   | otherwise = return Nothing
242
243 prim_ty_cons = mkNameEnv [mk_prim intPrimTyCon]
244   where
245     mk_prim tycon = (tyConName tycon, '_' : getOccString tycon)