Nicer error message for #3782
[ghc-hetmet.git] / compiler / vectorise / Vectorise / Builtins / Base.hs
1
2 -- | Builtin types and functions used by the vectoriser.
3 --   These are all defined in the DPH package.
4 module Vectorise.Builtins.Base (
5         -- * Hard config
6         mAX_DPH_PROD,
7         mAX_DPH_SUM,
8         mAX_DPH_COMBINE,
9         mAX_DPH_SCALAR_ARGS,
10         
11         -- * Builtins
12         Builtins(..),
13         indexBuiltin,
14         
15         -- * Projections
16         selTy,
17         selReplicate,
18         selPick,
19         selTags,
20         selElements,
21         sumTyCon,
22         prodTyCon,
23         prodDataCon,
24         combinePDVar,
25         scalarZip,
26         closureCtrFun
27 ) where
28 import Vectorise.Builtins.Modules
29 import BasicTypes
30 import Class
31 import CoreSyn
32 import TysWiredIn
33 import Type
34 import TyCon
35 import DataCon
36 import Var
37 import Outputable
38 import Data.Array
39
40
41 -- Numbers of things exported by the DPH library.
42 mAX_DPH_PROD :: Int
43 mAX_DPH_PROD = 5
44
45 mAX_DPH_SUM :: Int
46 mAX_DPH_SUM = 2
47
48 mAX_DPH_COMBINE :: Int
49 mAX_DPH_COMBINE = 2
50
51 mAX_DPH_SCALAR_ARGS :: Int
52 mAX_DPH_SCALAR_ARGS = 3
53
54
55 -- | Holds the names of the builtin types and functions used by the vectoriser.
56 data Builtins 
57         = Builtins 
58         { dphModules       :: Modules
59
60         -- From dph-common:Data.Array.Parallel.Lifted.PArray
61         , parrayTyCon      :: TyCon                     -- ^ PArray
62         , parrayDataCon    :: DataCon                   -- ^ PArray
63         , pdataTyCon       :: TyCon                     -- ^ PData
64         , paTyCon          :: TyCon                     -- ^ PA
65         , paDataCon        :: DataCon                   -- ^ PA
66         , preprTyCon       :: TyCon                     -- ^ PRepr
67         , prTyCon          :: TyCon                     -- ^ PR
68         , prDataCon        :: DataCon                   -- ^ PR
69         , replicatePDVar   :: Var                       -- ^ replicatePD
70         , emptyPDVar       :: Var                       -- ^ emptyPD
71         , packByTagPDVar   :: Var                       -- ^ packByTagPD
72         , combinePDVars    :: Array Int Var             -- ^ combinePD
73         , scalarClass      :: Class                     -- ^ Scalar
74
75         -- From dph-common:Data.Array.Parallel.Lifted.Closure
76         , closureTyCon     :: TyCon                     -- ^ :->
77         , closureVar       :: Var                       -- ^ closure
78         , applyVar         :: Var                       -- ^ $: 
79         , liftedClosureVar :: Var                       -- ^ liftedClosure
80         , liftedApplyVar   :: Var                       -- ^ liftedApply
81         , closureCtrFuns   :: Array Int Var             -- ^ closure1 .. closure2
82
83         -- From dph-common:Data.Array.Parallel.Lifted.Repr
84         , voidTyCon        :: TyCon                     -- ^ Void
85         , wrapTyCon        :: TyCon                     -- ^ Wrap
86         , sumTyCons        :: Array Int TyCon           -- ^ Sum2 .. Sum3
87         , voidVar          :: Var                       -- ^ void
88         , pvoidVar         :: Var                       -- ^ pvoid
89         , fromVoidVar      :: Var                       -- ^ fromVoid
90         , punitVar         :: Var                       -- ^ punit
91
92         -- From dph-common:Data.Array.Parallel.Lifted.Selector
93         , selTys           :: Array Int Type            -- ^ Sel2
94         , selReplicates    :: Array Int CoreExpr        -- ^ replicate2
95         , selPicks         :: Array Int CoreExpr        -- ^ pick2
96         , selTagss         :: Array Int CoreExpr        -- ^ tagsSel2
97         , selEls           :: Array (Int, Int) CoreExpr -- ^ elementsSel2_0 .. elementsSel_2_1
98
99         -- From dph-common:Data.Array.Parallel.Lifted.Scalar
100         -- NOTE: map is counted as a zipWith fn with one argument array.
101         , scalarZips       :: Array Int Var             -- ^ map, zipWith, zipWith3
102
103         -- A Fresh variable
104         , liftingContext   :: Var                       -- ^ lc
105         }
106
107
108 -- | Get an element from one of the arrays of contained by a `Builtins`.
109 --   If the indexed thing is not in the array then panic.
110 indexBuiltin 
111         :: (Ix i, Outputable i) 
112         => String                       -- ^ Name of the selector we've used, for panic messages.
113         -> (Builtins -> Array i a)      -- ^ Field selector for the `Builtins`.
114         -> i                            -- ^ Index into the array.
115         -> Builtins 
116         -> a
117
118 indexBuiltin fn f i bi
119   | inRange (bounds xs) i = xs ! i
120   | otherwise             
121   = pprSorry "Vectorise.Builtins.indexBuiltin" 
122         (vcat   [ text ""
123                 , text "DPH builtin function '" <> text fn <> text "' of size '" <> ppr i <> text "' is not yet implemented."
124                 , text "This function does not appear in your source program, but it is needed"
125                 , text "to compile your code in the backend. This is a known, current limitation"
126                 , text "of DPH. If you want it to to work you should send mail to cvs-ghc@haskell.org"
127                 , text "and ask what you can do to help (it might involve some GHC hacking)."])
128
129   where xs = f bi
130
131
132 -- Projections ----------------------------------------------------------------
133 -- We use these wrappers instead of indexing the `Builtin` structure directly
134 -- because they give nicer panic messages if the indexed thing cannot be found.
135
136 selTy :: Int -> Builtins -> Type
137 selTy           = indexBuiltin "selTy" selTys
138
139 selReplicate :: Int -> Builtins -> CoreExpr
140 selReplicate    = indexBuiltin "selReplicate" selReplicates 
141
142 selPick :: Int -> Builtins -> CoreExpr
143 selPick         = indexBuiltin "selPick" selPicks
144
145 selTags :: Int -> Builtins -> CoreExpr
146 selTags         = indexBuiltin "selTags" selTagss
147
148 selElements :: Int -> Int -> Builtins -> CoreExpr
149 selElements i j = indexBuiltin "selElements" selEls (i,j)
150
151 sumTyCon :: Int -> Builtins -> TyCon
152 sumTyCon        = indexBuiltin "sumTyCon" sumTyCons
153
154 prodTyCon :: Int -> Builtins -> TyCon
155 prodTyCon n _
156         | n >= 2 && n <= mAX_DPH_PROD 
157         = tupleTyCon Boxed n
158
159         | otherwise
160         = pprPanic "prodTyCon" (ppr n)
161
162 prodDataCon :: Int -> Builtins -> DataCon
163 prodDataCon n bi 
164  = case tyConDataCons (prodTyCon n bi) of
165         [con]   -> con
166         _       -> pprPanic "prodDataCon" (ppr n)
167
168 combinePDVar :: Int -> Builtins -> Var
169 combinePDVar    = indexBuiltin "combinePDVar" combinePDVars
170
171 scalarZip :: Int -> Builtins -> Var
172 scalarZip       = indexBuiltin "scalarZip" scalarZips
173
174 closureCtrFun :: Int -> Builtins -> Var
175 closureCtrFun   = indexBuiltin "closureCtrFun" closureCtrFuns
176
177