1 {-# OPTIONS -fno-warn-missing-signatures #-}
14 import Vectorise.Convert
16 import Vectorise.Monad
17 import Vectorise.Builtins
18 import Vectorise.Type.Type
19 import Vectorise.Type.TyConDecl
20 import Vectorise.Type.Classify
21 import Vectorise.Type.PADict
22 import Vectorise.Type.PData
23 import Vectorise.Type.PRepr
24 import Vectorise.Type.Repr
25 import Vectorise.Utils.Closure
26 import Vectorise.Utils.Hoisting
52 dtrace s x = if debug then pprTrace "VectType" s x else x
55 -- | Vectorise a type environment.
56 -- The type environment contains all the type things defined in a module.
59 -> VM ( TypeEnv -- Vectorised type environment.
60 , [FamInst] -- New type family instances.
61 , [(Var, CoreExpr)]) -- New top level bindings.
66 cs <- readGEnv $ mk_map . global_tycons
68 -- Split the list of TyCons into the ones we have to vectorise vs the
69 -- ones we can pass through unchanged. We also pass through algebraic
70 -- types that use non Haskell98 features, as we don't handle those.
71 let (conv_tcs, keep_tcs) = classifyTyCons cs groups
72 keep_dcs = concatMap tyConDataCons keep_tcs
74 zipWithM_ defTyCon keep_tcs keep_tcs
75 zipWithM_ defDataCon keep_dcs keep_dcs
77 new_tcs <- vectTyConDecls conv_tcs
79 let orig_tcs = keep_tcs ++ conv_tcs
81 -- We don't need to make new representation types for dictionary
82 -- constructors. The constructors are always fully applied, and we don't
83 -- need to lift them to arrays as a dictionary of a particular type
84 -- always has the same value.
85 let vect_tcs = filter (not . isClassTyCon)
88 (_, binds, inst_tcs) <- fixV $ \ ~(dfuns', _, _) ->
90 defTyConPAs (zipLazy vect_tcs dfuns')
91 reprs <- mapM tyConRepr vect_tcs
92 repr_tcs <- zipWith3M buildPReprTyCon orig_tcs vect_tcs reprs
93 pdata_tcs <- zipWith3M buildPDataTyCon orig_tcs vect_tcs reprs
96 $ zipWith5 buildTyConBindings
104 return (dfuns, binds, repr_tcs ++ pdata_tcs)
106 let all_new_tcs = new_tcs ++ inst_tcs
108 let new_env = extendTypeEnvList env
109 (map ATyCon all_new_tcs
110 ++ [ADataCon dc | tc <- all_new_tcs
111 , dc <- tyConDataCons tc])
113 return (new_env, map mkLocalFamInst inst_tcs, binds)
115 tycons = typeEnvTyCons env
116 groups = tyConGroups tycons
118 mk_map env = listToUFM_Directly [(u, getUnique n /= u) | (u,n) <- nameEnvUniqueElts env]
122 buildTyConBindings :: TyCon -> TyCon -> TyCon -> TyCon -> SumRepr -> VM Var
123 buildTyConBindings orig_tc vect_tc prepr_tc pdata_tc repr
124 = do vectDataConWorkers orig_tc vect_tc pdata_tc
125 buildPADict vect_tc prepr_tc pdata_tc repr
128 vectDataConWorkers :: TyCon -> TyCon -> TyCon -> VM ()
129 vectDataConWorkers orig_tc vect_tc arr_tc
131 . zipWith3 def_worker (tyConDataCons orig_tc) rep_tys
132 $ zipWith4 mk_data_con (tyConDataCons vect_tc)
135 (tail $ tails rep_tys)
136 mapM_ (uncurry hoistBinding) bs
138 tyvars = tyConTyVars vect_tc
139 var_tys = mkTyVarTys tyvars
140 ty_args = map Type var_tys
141 res_ty = mkTyConApp vect_tc var_tys
143 cons = tyConDataCons vect_tc
145 [arr_dc] = tyConDataCons arr_tc
147 rep_tys = map dataConRepArgTys $ tyConDataCons vect_tc
150 mk_data_con con tys pre post
151 = liftM2 (,) (vect_data_con con)
152 (lift_data_con tys pre post (mkDataConTag con))
154 sel_replicate len tag
156 rep <- builtin (selReplicate arity)
157 return [rep `mkApps` [len, tag]]
159 | otherwise = return []
161 vect_data_con con = return $ mkConApp con ty_args
162 lift_data_con tys pre_tys post_tys tag
164 len <- builtin liftingContext
165 args <- mapM (newLocalVar (fsLit "xs"))
166 =<< mapM mkPDataType tys
168 sel <- sel_replicate (Var len) tag
170 pre <- mapM emptyPD (concat pre_tys)
171 post <- mapM emptyPD (concat post_tys)
173 return . mkLams (len : args)
174 . wrapFamInstBody arr_tc var_tys
176 $ ty_args ++ sel ++ pre ++ map Var args ++ post
178 def_worker data_con arg_tys mk_body
180 arity <- polyArity tyvars
183 . polyAbstract tyvars $ \args ->
184 liftM (mkLams (tyvars ++ args) . vectorised)
185 $ buildClosures tyvars [] arg_tys res_ty mk_body
187 raw_worker <- cloneId mkVectOcc orig_worker (exprType body)
188 let vect_worker = raw_worker `setIdUnfolding`
189 mkInlineRule body (Just arity)
190 defGlobalVar orig_worker vect_worker
191 return (vect_worker, body)
193 orig_worker = dataConWorkId data_con