PageRenderTime 25ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/ghc-7.0.4/compiler/vectorise/Vectorise/Type/Env.hs

http://picorec.googlecode.com/
Haskell | 190 lines | 140 code | 37 blank | 13 comment | 2 complexity | 9c0cb8e9136e686ebbc72c6ce1026b00 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
  2. #if __GLASGOW_HASKELL__ >= 611
  3. {-# OPTIONS_GHC -XNoMonoLocalBinds #-}
  4. #endif
  5. -- Roman likes local bindings
  6. -- If this module lives on I'd like to get rid of this flag in due course
  7. module Vectorise.Type.Env (
  8. vectTypeEnv,
  9. )
  10. where
  11. import Vectorise.Env
  12. import Vectorise.Vect
  13. import Vectorise.Monad
  14. import Vectorise.Builtins
  15. import Vectorise.Type.TyConDecl
  16. import Vectorise.Type.Classify
  17. import Vectorise.Type.PADict
  18. import Vectorise.Type.PData
  19. import Vectorise.Type.PRepr
  20. import Vectorise.Type.Repr
  21. import Vectorise.Utils
  22. import HscTypes
  23. import CoreSyn
  24. import CoreUtils
  25. import CoreUnfold
  26. import DataCon
  27. import TyCon
  28. import Type
  29. import FamInstEnv
  30. import OccName
  31. import Id
  32. import MkId
  33. import Var
  34. import NameEnv
  35. import Unique
  36. import UniqFM
  37. import Util
  38. import Outputable
  39. import FastString
  40. import MonadUtils
  41. import Control.Monad
  42. import Data.List
  43. debug = False
  44. dtrace s x = if debug then pprTrace "VectType" s x else x
  45. -- | Vectorise a type environment.
  46. -- The type environment contains all the type things defined in a module.
  47. vectTypeEnv
  48. :: TypeEnv
  49. -> VM ( TypeEnv -- Vectorised type environment.
  50. , [FamInst] -- New type family instances.
  51. , [(Var, CoreExpr)]) -- New top level bindings.
  52. vectTypeEnv env
  53. = dtrace (ppr env)
  54. $ do
  55. cs <- readGEnv $ mk_map . global_tycons
  56. -- Split the list of TyCons into the ones we have to vectorise vs the
  57. -- ones we can pass through unchanged. We also pass through algebraic
  58. -- types that use non Haskell98 features, as we don't handle those.
  59. let (conv_tcs, keep_tcs) = classifyTyCons cs groups
  60. keep_dcs = concatMap tyConDataCons keep_tcs
  61. zipWithM_ defTyCon keep_tcs keep_tcs
  62. zipWithM_ defDataCon keep_dcs keep_dcs
  63. new_tcs <- vectTyConDecls conv_tcs
  64. let orig_tcs = keep_tcs ++ conv_tcs
  65. -- We don't need to make new representation types for dictionary
  66. -- constructors. The constructors are always fully applied, and we don't
  67. -- need to lift them to arrays as a dictionary of a particular type
  68. -- always has the same value.
  69. let vect_tcs = filter (not . isClassTyCon)
  70. $ keep_tcs ++ new_tcs
  71. (_, binds, inst_tcs) <- fixV $ \ ~(dfuns', _, _) ->
  72. do
  73. defTyConPAs (zipLazy vect_tcs dfuns')
  74. reprs <- mapM tyConRepr vect_tcs
  75. repr_tcs <- zipWith3M buildPReprTyCon orig_tcs vect_tcs reprs
  76. pdata_tcs <- zipWith3M buildPDataTyCon orig_tcs vect_tcs reprs
  77. dfuns <- sequence
  78. $ zipWith5 buildTyConBindings
  79. orig_tcs
  80. vect_tcs
  81. repr_tcs
  82. pdata_tcs
  83. reprs
  84. binds <- takeHoisted
  85. return (dfuns, binds, repr_tcs ++ pdata_tcs)
  86. let all_new_tcs = new_tcs ++ inst_tcs
  87. let new_env = extendTypeEnvList env
  88. (map ATyCon all_new_tcs
  89. ++ [ADataCon dc | tc <- all_new_tcs
  90. , dc <- tyConDataCons tc])
  91. return (new_env, map mkLocalFamInst inst_tcs, binds)
  92. where
  93. tycons = typeEnvTyCons env
  94. groups = tyConGroups tycons
  95. mk_map env = listToUFM_Directly [(u, getUnique n /= u) | (u,n) <- nameEnvUniqueElts env]
  96. buildTyConBindings :: TyCon -> TyCon -> TyCon -> TyCon -> SumRepr -> VM Var
  97. buildTyConBindings orig_tc vect_tc prepr_tc pdata_tc repr
  98. = do vectDataConWorkers orig_tc vect_tc pdata_tc
  99. buildPADict vect_tc prepr_tc pdata_tc repr
  100. vectDataConWorkers :: TyCon -> TyCon -> TyCon -> VM ()
  101. vectDataConWorkers orig_tc vect_tc arr_tc
  102. = do bs <- sequence
  103. . zipWith3 def_worker (tyConDataCons orig_tc) rep_tys
  104. $ zipWith4 mk_data_con (tyConDataCons vect_tc)
  105. rep_tys
  106. (inits rep_tys)
  107. (tail $ tails rep_tys)
  108. mapM_ (uncurry hoistBinding) bs
  109. where
  110. tyvars = tyConTyVars vect_tc
  111. var_tys = mkTyVarTys tyvars
  112. ty_args = map Type var_tys
  113. res_ty = mkTyConApp vect_tc var_tys
  114. cons = tyConDataCons vect_tc
  115. arity = length cons
  116. [arr_dc] = tyConDataCons arr_tc
  117. rep_tys = map dataConRepArgTys $ tyConDataCons vect_tc
  118. mk_data_con con tys pre post
  119. = liftM2 (,) (vect_data_con con)
  120. (lift_data_con tys pre post (mkDataConTag con))
  121. sel_replicate len tag
  122. | arity > 1 = do
  123. rep <- builtin (selReplicate arity)
  124. return [rep `mkApps` [len, tag]]
  125. | otherwise = return []
  126. vect_data_con con = return $ mkConApp con ty_args
  127. lift_data_con tys pre_tys post_tys tag
  128. = do
  129. len <- builtin liftingContext
  130. args <- mapM (newLocalVar (fsLit "xs"))
  131. =<< mapM mkPDataType tys
  132. sel <- sel_replicate (Var len) tag
  133. pre <- mapM emptyPD (concat pre_tys)
  134. post <- mapM emptyPD (concat post_tys)
  135. return . mkLams (len : args)
  136. . wrapFamInstBody arr_tc var_tys
  137. . mkConApp arr_dc
  138. $ ty_args ++ sel ++ pre ++ map Var args ++ post
  139. def_worker data_con arg_tys mk_body
  140. = do
  141. arity <- polyArity tyvars
  142. body <- closedV
  143. . inBind orig_worker
  144. . polyAbstract tyvars $ \args ->
  145. liftM (mkLams (tyvars ++ args) . vectorised)
  146. $ buildClosures tyvars [] arg_tys res_ty mk_body
  147. raw_worker <- cloneId mkVectOcc orig_worker (exprType body)
  148. let vect_worker = raw_worker `setIdUnfolding`
  149. mkInlineUnfolding (Just arity) body
  150. defGlobalVar orig_worker vect_worker
  151. return (vect_worker, body)
  152. where
  153. orig_worker = dataConWorkId data_con