root/compiler/coreSyn/CoreTidy.lhs

Revision 1df198643cc5502ee103f043193d2990c9837e25, 8.0 KB (checked in by Ian Lynagh <igloo@…>, 7 months ago)

Use -fwarn-tabs when validating

We only use it for "compiler" sources, i.e. not for libraries.
Many modules have a -fno-warn-tabs kludge for now.

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