PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/coreSyn/CoreTidy.lhs

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