Make some profiling flags dynamic
[ghc-hetmet.git] / compiler / deSugar / Desugar.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5
6 The Desugarer: turning HsSyn into Core.
7
8 \begin{code}
9 module Desugar ( deSugar, deSugarExpr ) where
10
11 import DynFlags
12 import StaticFlags
13 import HscTypes
14 import HsSyn
15 import TcRnTypes
16 import MkIface
17 import Id
18 import Name
19 import CoreSyn
20 import PprCore
21 import DsMonad
22 import DsExpr
23 import DsBinds
24 import DsForeign
25 import DsExpr           ()      -- Forces DsExpr to be compiled; DsBinds only
26                                 -- depends on DsExpr.hi-boot.
27 import Module
28 import RdrName
29 import NameSet
30 import VarSet
31 import Rules
32 import CoreLint
33 import CoreFVs
34 import ErrUtils
35 import Outputable
36 import SrcLoc
37 import Maybes
38 import FastString
39 import Coverage
40
41 import Data.IORef
42 \end{code}
43
44 %************************************************************************
45 %*                                                                      *
46 %*              The main function: deSugar
47 %*                                                                      *
48 %************************************************************************
49
50 \begin{code}
51 deSugar :: HscEnv -> ModLocation -> TcGblEnv -> IO (Messages, Maybe ModGuts)
52 -- Can modify PCS by faulting in more declarations
53
54 deSugar hsc_env 
55         mod_loc
56         tcg_env@(TcGblEnv { tcg_mod          = mod,
57                             tcg_src          = hsc_src,
58                             tcg_type_env     = type_env,
59                             tcg_imports      = imports,
60                             tcg_exports      = exports,
61                             tcg_keep         = keep_var,
62                             tcg_rdr_env      = rdr_env,
63                             tcg_fix_env      = fix_env,
64                             tcg_inst_env     = inst_env,
65                             tcg_fam_inst_env = fam_inst_env,
66                             tcg_warns        = warns,
67                             tcg_anns         = anns,
68                             tcg_binds        = binds,
69                             tcg_fords        = fords,
70                             tcg_rules        = rules,
71                             tcg_insts        = insts,
72                             tcg_fam_insts    = fam_insts,
73                             tcg_hpc          = other_hpc_info })
74
75   = do  { let dflags = hsc_dflags hsc_env
76         ; showPass dflags "Desugar"
77
78         -- Desugar the program
79         ; let export_set = availsToNameSet exports
80         ; let auto_scc = mkAutoScc dflags mod export_set
81         ; let target = hscTarget dflags
82         ; let hpcInfo = emptyHpcInfo other_hpc_info
83         ; (msgs, mb_res)
84               <- case target of
85                    HscNothing ->
86                        return (emptyMessages,
87                                Just ([], [], NoStubs, hpcInfo, emptyModBreaks))
88                    _        -> do
89                      (binds_cvr,ds_hpc_info, modBreaks)
90                          <- if (opt_Hpc
91                                   || target == HscInterpreted)
92                                && (not (isHsBoot hsc_src))
93                               then addCoverageTicksToBinds dflags mod mod_loc (typeEnvTyCons type_env) binds 
94                               else return (binds, hpcInfo, emptyModBreaks)
95                      initDs hsc_env mod rdr_env type_env $ do
96                          core_prs <- dsTopLHsBinds auto_scc binds_cvr
97                          (ds_fords, foreign_prs) <- dsForeigns fords
98                          let all_prs = foreign_prs ++ core_prs
99                          ds_rules <- mapM dsRule rules
100                          return (all_prs, catMaybes ds_rules, ds_fords, ds_hpc_info, modBreaks)
101
102         ; case mb_res of {
103            Nothing -> return (msgs, Nothing) ;
104            Just (all_prs, ds_rules, ds_fords,ds_hpc_info, modBreaks) -> do
105
106         {       -- Add export flags to bindings
107           keep_alive <- readIORef keep_var
108         ; let final_prs = addExportFlags target export_set
109                                  keep_alive all_prs ds_rules
110               ds_binds  = [Rec final_prs]
111         -- Notice that we put the whole lot in a big Rec, even the foreign binds
112         -- When compiling PrelFloat, which defines data Float = F# Float#
113         -- we want F# to be in scope in the foreign marshalling code!
114         -- You might think it doesn't matter, but the simplifier brings all top-level
115         -- things into the in-scope set before simplifying; so we get no unfolding for F#!
116
117         -- Lint result if necessary
118         ; endPass dflags "Desugar" Opt_D_dump_ds ds_binds
119
120         -- Dump output
121         ; doIfSet (dopt Opt_D_dump_ds dflags) 
122                   (printDump (ppr_ds_rules ds_rules))
123
124         ; used_names <- mkUsedNames tcg_env
125         ; deps <- mkDependencies tcg_env
126
127         ; let mod_guts = ModGuts {      
128                 mg_module       = mod,
129                 mg_boot         = isHsBoot hsc_src,
130                 mg_exports      = exports,
131                 mg_deps         = deps,
132                 mg_used_names   = used_names,
133                 mg_dir_imps     = imp_mods imports,
134                 mg_rdr_env      = rdr_env,
135                 mg_fix_env      = fix_env,
136                 mg_warns        = warns,
137                 mg_anns         = anns,
138                 mg_types        = type_env,
139                 mg_insts        = insts,
140                 mg_fam_insts    = fam_insts,
141                 mg_inst_env     = inst_env,
142                 mg_fam_inst_env = fam_inst_env,
143                 mg_rules        = ds_rules,
144                 mg_binds        = ds_binds,
145                 mg_foreign      = ds_fords,
146                 mg_hpc_info     = ds_hpc_info,
147                 mg_modBreaks    = modBreaks,
148                 mg_vect_info    = noVectInfo
149               }
150         ; return (msgs, Just mod_guts)
151         }}}
152
153 mkAutoScc :: DynFlags -> Module -> NameSet -> AutoScc
154 mkAutoScc dflags mod exports
155   | not opt_SccProfilingOn      -- No profiling
156   = NoSccs              
157     -- Add auto-scc on all top-level things
158   | dopt Opt_AutoSccsOnAllToplevs dflags
159   = AddSccs mod (\id -> not $ isDerivedOccName $ getOccName id)
160     -- See #1641.  This is pretty yucky, but I can't see a better way
161     -- to identify compiler-generated Ids, and at least this should
162     -- catch them all.
163     -- Only on exported things
164   | dopt Opt_AutoSccsOnExportedToplevs dflags
165   = AddSccs mod (\id -> idName id `elemNameSet` exports)
166   | otherwise
167   = NoSccs
168
169 deSugarExpr :: HscEnv
170             -> Module -> GlobalRdrEnv -> TypeEnv 
171             -> LHsExpr Id
172             -> IO (Messages, Maybe CoreExpr)
173 -- Prints its own errors; returns Nothing if error occurred
174
175 deSugarExpr hsc_env this_mod rdr_env type_env tc_expr = do
176     let dflags = hsc_dflags hsc_env
177     showPass dflags "Desugar"
178
179     -- Do desugaring
180     (msgs, mb_core_expr) <- initDs hsc_env this_mod rdr_env type_env $
181                                    dsLExpr tc_expr
182
183     case mb_core_expr of
184       Nothing   -> return (msgs, Nothing)
185       Just expr -> do
186
187         -- Dump output
188         dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr expr)
189
190         return (msgs, Just expr)
191
192 --              addExportFlags
193 -- Set the no-discard flag if either 
194 --      a) the Id is exported
195 --      b) it's mentioned in the RHS of an orphan rule
196 --      c) it's in the keep-alive set
197 --
198 -- It means that the binding won't be discarded EVEN if the binding
199 -- ends up being trivial (v = w) -- the simplifier would usually just 
200 -- substitute w for v throughout, but we don't apply the substitution to
201 -- the rules (maybe we should?), so this substitution would make the rule
202 -- bogus.
203
204 -- You might wonder why exported Ids aren't already marked as such;
205 -- it's just because the type checker is rather busy already and
206 -- I didn't want to pass in yet another mapping.
207
208 addExportFlags :: HscTarget -> NameSet -> NameSet -> [(Id, t)] -> [CoreRule]
209                -> [(Id, t)]
210 addExportFlags target exports keep_alive prs rules
211   = [(add_export bndr, rhs) | (bndr,rhs) <- prs]
212   where
213     add_export bndr
214         | dont_discard bndr = setIdExported bndr
215         | otherwise         = bndr
216
217     orph_rhs_fvs = unionVarSets [ ruleRhsFreeVars rule
218                                 | rule <- rules, 
219                                   not (isLocalRule rule) ]
220         -- A non-local rule keeps alive the free vars of its right-hand side. 
221         -- (A "non-local" is one whose head function is not locally defined.)
222         -- Local rules are (later, after gentle simplification) 
223         -- attached to the Id, and that keeps the rhs free vars alive.
224
225     dont_discard bndr = is_exported name
226                      || name `elemNameSet` keep_alive
227                      || bndr `elemVarSet` orph_rhs_fvs 
228                      where
229                         name = idName bndr
230
231         -- In interactive mode, we don't want to discard any top-level
232         -- entities at all (eg. do not inline them away during
233         -- simplification), and retain them all in the TypeEnv so they are
234         -- available from the command line.
235         --
236         -- isExternalName separates the user-defined top-level names from those
237         -- introduced by the type checker.
238     is_exported :: Name -> Bool
239     is_exported | target == HscInterpreted = isExternalName
240                 | otherwise                = (`elemNameSet` exports)
241
242 ppr_ds_rules :: [CoreRule] -> SDoc
243 ppr_ds_rules [] = empty
244 ppr_ds_rules rules
245   = text "" $$ text "-------------- DESUGARED RULES -----------------" $$
246     pprRules rules
247 \end{code}
248
249
250
251 %************************************************************************
252 %*                                                                      *
253 %*              Desugaring transformation rules
254 %*                                                                      *
255 %************************************************************************
256
257 \begin{code}
258 dsRule :: LRuleDecl Id -> DsM (Maybe CoreRule)
259 dsRule (L loc (HsRule name act vars lhs _tv_lhs rhs _fv_rhs))
260   = putSrcSpanDs loc $ 
261     do  { let bndrs' = [var | RuleBndr (L _ var) <- vars]
262         ; lhs'  <- dsLExpr lhs
263         ; rhs'  <- dsLExpr rhs
264
265         -- Substitute the dict bindings eagerly,
266         -- and take the body apart into a (f args) form
267         ; case decomposeRuleLhs (mkLams bndrs' lhs') of {
268                 Nothing -> do { warnDs msg; return Nothing } ;
269                 Just (bndrs, fn_id, args) -> do
270         
271         { let local_rule = isLocalId fn_id
272                 -- NB: isLocalId is False of implicit Ids.  This is good becuase
273                 -- we don't want to attach rules to the bindings of implicit Ids, 
274                 -- because they don't show up in the bindings until just before code gen
275               fn_name   = idName fn_id
276
277               rule = Rule { ru_name = name, ru_fn = fn_name, ru_act = act,
278                             ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs', 
279                             ru_rough = roughTopNames args, 
280                             ru_local = local_rule }
281         ; return (Just rule)
282         } } }
283   where
284     msg = hang (ptext (sLit "RULE left-hand side too complicated to desugar; ignored"))
285              2 (ppr lhs)
286 \end{code}