PageRenderTime 35ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/ghc-7.0.4/compiler/coreSyn/CoreTidy.lhs

http://picorec.googlecode.com/
Haskell | 236 lines | 166 code | 37 blank | 33 comment | 3 complexity | e5ddd026aa9047e2d53c2738c7fc3d8b MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
  1. %
  2. % (c) The University of Glasgow 2006
  3. % (c) The AQUA Project, Glasgow University, 1996-1998
  4. %
  5. This module contains "tidying" code for *nested* expressions, bindings, rules.
  6. The code for *top-level* bindings is in TidyPgm.
  7. \begin{code}
  8. module CoreTidy (
  9. tidyExpr, tidyVarOcc, tidyRule, tidyRules, tidyUnfolding
  10. ) where
  11. #include "HsVersions.h"
  12. import CoreSyn
  13. import CoreArity
  14. import Id
  15. import IdInfo
  16. import TcType( tidyType, tidyTyVarBndr )
  17. import Var
  18. import VarEnv
  19. import UniqFM
  20. import Name hiding (tidyNameOcc)
  21. import SrcLoc
  22. import Maybes
  23. import Data.List
  24. import Outputable
  25. \end{code}
  26. %************************************************************************
  27. %* *
  28. \subsection{Tidying expressions, rules}
  29. %* *
  30. %************************************************************************
  31. \begin{code}
  32. tidyBind :: TidyEnv
  33. -> CoreBind
  34. -> (TidyEnv, CoreBind)
  35. tidyBind env (NonRec bndr rhs)
  36. = tidyLetBndr env env (bndr,rhs) =: \ (env', bndr') ->
  37. (env', NonRec bndr' (tidyExpr env' rhs))
  38. tidyBind env (Rec prs)
  39. = let
  40. (env', bndrs') = mapAccumL (tidyLetBndr env') env prs
  41. in
  42. map (tidyExpr env') (map snd prs) =: \ rhss' ->
  43. (env', Rec (zip bndrs' rhss'))
  44. ------------ Expressions --------------
  45. tidyExpr :: TidyEnv -> CoreExpr -> CoreExpr
  46. tidyExpr env (Var v) = Var (tidyVarOcc env v)
  47. tidyExpr env (Type ty) = Type (tidyType env ty)
  48. tidyExpr _ (Lit lit) = Lit lit
  49. tidyExpr env (App f a) = App (tidyExpr env f) (tidyExpr env a)
  50. tidyExpr env (Note n e) = Note (tidyNote env n) (tidyExpr env e)
  51. tidyExpr env (Cast e co) = Cast (tidyExpr env e) (tidyType env co)
  52. tidyExpr env (Let b e)
  53. = tidyBind env b =: \ (env', b') ->
  54. Let b' (tidyExpr env' e)
  55. tidyExpr env (Case e b ty alts)
  56. = tidyBndr env b =: \ (env', b) ->
  57. Case (tidyExpr env e) b (tidyType env ty)
  58. (map (tidyAlt b env') alts)
  59. tidyExpr env (Lam b e)
  60. = tidyBndr env b =: \ (env', b) ->
  61. Lam b (tidyExpr env' e)
  62. ------------ Case alternatives --------------
  63. tidyAlt :: CoreBndr -> TidyEnv -> CoreAlt -> CoreAlt
  64. tidyAlt _case_bndr env (con, vs, rhs)
  65. = tidyBndrs env vs =: \ (env', vs) ->
  66. (con, vs, tidyExpr env' rhs)
  67. ------------ Notes --------------
  68. tidyNote :: TidyEnv -> Note -> Note
  69. tidyNote _ note = note
  70. ------------ Rules --------------
  71. tidyRules :: TidyEnv -> [CoreRule] -> [CoreRule]
  72. tidyRules _ [] = []
  73. tidyRules env (rule : rules)
  74. = tidyRule env rule =: \ rule ->
  75. tidyRules env rules =: \ rules ->
  76. (rule : rules)
  77. tidyRule :: TidyEnv -> CoreRule -> CoreRule
  78. tidyRule _ rule@(BuiltinRule {}) = rule
  79. tidyRule env rule@(Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs,
  80. ru_fn = fn, ru_rough = mb_ns })
  81. = tidyBndrs env bndrs =: \ (env', bndrs) ->
  82. map (tidyExpr env') args =: \ args ->
  83. rule { ru_bndrs = bndrs, ru_args = args,
  84. ru_rhs = tidyExpr env' rhs,
  85. ru_fn = tidyNameOcc env fn,
  86. ru_rough = map (fmap (tidyNameOcc env')) mb_ns }
  87. \end{code}
  88. %************************************************************************
  89. %* *
  90. \subsection{Tidying non-top-level binders}
  91. %* *
  92. %************************************************************************
  93. \begin{code}
  94. tidyNameOcc :: TidyEnv -> Name -> Name
  95. -- In rules and instances, we have Names, and we must tidy them too
  96. -- Fortunately, we can lookup in the VarEnv with a name
  97. tidyNameOcc (_, var_env) n = case lookupUFM var_env n of
  98. Nothing -> n
  99. Just v -> idName v
  100. tidyVarOcc :: TidyEnv -> Var -> Var
  101. tidyVarOcc (_, var_env) v = lookupVarEnv var_env v `orElse` v
  102. -- tidyBndr is used for lambda and case binders
  103. tidyBndr :: TidyEnv -> Var -> (TidyEnv, Var)
  104. tidyBndr env var
  105. | isTyCoVar var = tidyTyVarBndr env var
  106. | otherwise = tidyIdBndr env var
  107. tidyBndrs :: TidyEnv -> [Var] -> (TidyEnv, [Var])
  108. tidyBndrs env vars = mapAccumL tidyBndr env vars
  109. tidyLetBndr :: TidyEnv -- Knot-tied version for unfoldings
  110. -> TidyEnv -- The one to extend
  111. -> (Id, CoreExpr) -> (TidyEnv, Var)
  112. -- Used for local (non-top-level) let(rec)s
  113. tidyLetBndr rec_tidy_env env (id,rhs)
  114. = ((tidy_occ_env,new_var_env), final_id)
  115. where
  116. ((tidy_occ_env,var_env), new_id) = tidyIdBndr env id
  117. new_var_env = extendVarEnv var_env id final_id
  118. -- Override the env we get back from tidyId with the
  119. -- new IdInfo so it gets propagated to the usage sites.
  120. -- We need to keep around any interesting strictness and
  121. -- demand info because later on we may need to use it when
  122. -- converting to A-normal form.
  123. -- eg.
  124. -- f (g x), where f is strict in its argument, will be converted
  125. -- into case (g x) of z -> f z by CorePrep, but only if f still
  126. -- has its strictness info.
  127. --
  128. -- Similarly for the demand info - on a let binder, this tells
  129. -- CorePrep to turn the let into a case.
  130. --
  131. -- Similarly arity info for eta expansion in CorePrep
  132. --
  133. -- Set inline-prag info so that we preseve it across
  134. -- separate compilation boundaries
  135. final_id = new_id `setIdInfo` new_info
  136. idinfo = idInfo id
  137. new_info = idInfo new_id
  138. `setArityInfo` exprArity rhs
  139. `setStrictnessInfo` strictnessInfo idinfo
  140. `setDemandInfo` demandInfo idinfo
  141. `setInlinePragInfo` inlinePragInfo idinfo
  142. `setUnfoldingInfo` new_unf
  143. new_unf | isStableUnfolding unf = tidyUnfolding rec_tidy_env unf (panic "tidy_unf")
  144. | otherwise = noUnfolding
  145. unf = unfoldingInfo idinfo
  146. -- Non-top-level variables
  147. tidyIdBndr :: TidyEnv -> Id -> (TidyEnv, Id)
  148. tidyIdBndr env@(tidy_env, var_env) id
  149. = -- Do this pattern match strictly, otherwise we end up holding on to
  150. -- stuff in the OccName.
  151. case tidyOccName tidy_env (getOccName id) of { (tidy_env', occ') ->
  152. let
  153. -- Give the Id a fresh print-name, *and* rename its type
  154. -- The SrcLoc isn't important now,
  155. -- though we could extract it from the Id
  156. --
  157. ty' = tidyType env (idType id)
  158. name' = mkInternalName (idUnique id) occ' noSrcSpan
  159. id' = mkLocalIdWithInfo name' ty' new_info
  160. var_env' = extendVarEnv var_env id id'
  161. -- Note [Tidy IdInfo]
  162. new_info = vanillaIdInfo `setOccInfo` occInfo old_info
  163. old_info = idInfo id
  164. in
  165. ((tidy_env', var_env'), id')
  166. }
  167. ------------ Unfolding --------------
  168. tidyUnfolding :: TidyEnv -> Unfolding -> Unfolding -> Unfolding
  169. tidyUnfolding tidy_env (DFunUnfolding ar con ids) _
  170. = DFunUnfolding ar con (map (fmap (tidyExpr tidy_env)) ids)
  171. tidyUnfolding tidy_env
  172. unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src })
  173. unf_from_rhs
  174. | isStableSource src
  175. = unf { uf_tmpl = tidyExpr tidy_env unf_rhs, -- Preserves OccInfo
  176. uf_src = tidySrc tidy_env src }
  177. | otherwise
  178. = unf_from_rhs
  179. tidyUnfolding _ unf _ = unf -- NoUnfolding or OtherCon
  180. tidySrc :: TidyEnv -> UnfoldingSource -> UnfoldingSource
  181. tidySrc tidy_env (InlineWrapper w) = InlineWrapper (tidyVarOcc tidy_env w)
  182. tidySrc _ inl_info = inl_info
  183. \end{code}
  184. Note [Tidy IdInfo]
  185. ~~~~~~~~~~~~~~~~~~
  186. All nested Ids now have the same IdInfo, namely vanillaIdInfo, which
  187. should save some space; except that we preserve occurrence info for
  188. two reasons:
  189. (a) To make printing tidy core nicer
  190. (b) Because we tidy RULES and InlineRules, which may then propagate
  191. via --make into the compilation of the next module, and we want
  192. the benefit of that occurrence analysis when we use the rule or
  193. or inline the function. In particular, it's vital not to lose
  194. loop-breaker info, else we get an infinite inlining loop
  195. Note that tidyLetBndr puts more IdInfo back.
  196. \begin{code}
  197. (=:) :: a -> (a -> b) -> b
  198. m =: k = m `seq` k m
  199. \end{code}