PageRenderTime 23ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/coreSyn/CoreTidy.lhs

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