7197e77a72271398d31db445c4efb7d7d8393e77
[ghc-hetmet.git] / ghc / compiler / simplCore / SimplCore.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[SimplCore]{Driver for simplifying @Core@ programs}
5
6 \begin{code}
7 module SimplCore ( core2core, simplifyExpr ) where
8
9 #include "HsVersions.h"
10
11 import CmdLineOpts      ( CoreToDo(..), SimplifierSwitch(..), 
12                           SwitchResult(..), intSwitchSet,
13                           DynFlags, DynFlag(..), dopt, dopt_CoreToDo
14                         )
15 import CoreLint         ( showPass, endPass )
16 import CoreSyn
17 import CoreFVs          ( ruleRhsFreeVars )
18 import HscTypes         ( PersistentCompilerState(..),
19                           PackageRuleBase, HomeSymbolTable, IsExported, ModDetails(..)
20                         )
21 import CSE              ( cseProgram )
22 import Rules            ( RuleBase, emptyRuleBase, ruleBaseFVs, ruleBaseIds, 
23                           extendRuleBaseList, addRuleBaseFVs, pprRuleBase )
24 import Module           ( moduleEnvElts )
25 import CoreUnfold
26 import PprCore          ( pprCoreBindings, pprCoreExpr )
27 import OccurAnal        ( occurAnalyseBinds, occurAnalyseGlobalExpr )
28 import CoreUtils        ( coreBindsSize )
29 import Simplify         ( simplTopBinds, simplExpr )
30 import SimplUtils       ( simplBinders )
31 import SimplMonad
32 import ErrUtils         ( dumpIfSet, dumpIfSet_dyn )
33 import FloatIn          ( floatInwards )
34 import FloatOut         ( floatOutwards )
35 import Id               ( idName, isDataConWrapId, setIdNoDiscard, isLocalId, isImplicitId )
36 import VarSet
37 import LiberateCase     ( liberateCase )
38 import SAT              ( doStaticArgs )
39 import Specialise       ( specProgram)
40 import SpecConstr       ( specConstrProgram)
41 import UsageSPInf       ( doUsageSPInf )
42 import StrictAnal       ( saBinds )
43 import WorkWrap         ( wwTopBinds )
44 import CprAnalyse       ( cprAnalyse )
45
46 import UniqSupply       ( UniqSupply, mkSplitUniqSupply, splitUniqSupply )
47 import IO               ( hPutStr, stderr )
48 import Outputable
49
50 import Maybes           ( orElse )
51 import List             ( partition )
52 \end{code}
53
54 %************************************************************************
55 %*                                                                      *
56 \subsection{The driver for the simplifier}
57 %*                                                                      *
58 %************************************************************************
59
60 \begin{code}
61 core2core :: DynFlags           -- includes spec of what core-to-core passes to do
62           -> PersistentCompilerState
63           -> HomeSymbolTable
64           -> IsExported
65           -> ModDetails
66           -> IO ModDetails
67
68 core2core dflags pcs hst is_exported 
69           mod_details@(ModDetails { md_binds = binds_in, md_rules = rules_in })
70   = do
71         let core_todos    = dopt_CoreToDo dflags
72         let pkg_rule_base = pcs_rules pcs               -- Rule-base accumulated from imported packages
73         
74
75         us <-  mkSplitUniqSupply 's'
76         let (cp_us, ru_us) = splitUniqSupply us
77
78                 -- COMPUTE THE RULE BASE TO USE
79         (rule_base, local_rule_ids, orphan_rules, rule_rhs_fvs)
80                 <- prepareRules dflags pkg_rule_base hst ru_us binds_in rules_in
81
82                 -- PREPARE THE BINDINGS
83         let binds1 = updateBinders local_rule_ids rule_rhs_fvs is_exported binds_in
84
85                 -- DO THE BUSINESS
86         (stats, processed_binds)
87                 <- doCorePasses dflags rule_base (zeroSimplCount dflags) cp_us binds1 core_todos
88
89         dumpIfSet_dyn dflags Opt_D_dump_simpl_stats
90                   "Grand total simplifier statistics"
91                   (pprSimplCount stats)
92
93         -- Return results
94         -- We only return local orphan rules, i.e., local rules not attached to an Id
95         -- The bindings cotain more rules, embedded in the Ids
96         return (mod_details { md_binds = processed_binds, md_rules = orphan_rules})
97
98
99 simplifyExpr :: DynFlags -- includes spec of what core-to-core passes to do
100              -> PersistentCompilerState
101              -> HomeSymbolTable
102              -> CoreExpr
103              -> IO CoreExpr
104 -- simplifyExpr is called by the driver to simplify an
105 -- expression typed in at the interactive prompt
106 simplifyExpr dflags pcs hst expr
107   = do  {
108         ; showPass dflags "Simplify"
109
110         ; us <-  mkSplitUniqSupply 's'
111
112         ; let (expr', _counts) = initSmpl dflags sw_chkr us emptyVarSet black_list_nothing      
113                                           (simplExprGently expr)
114
115         ; dumpIfSet_dyn dflags Opt_D_dump_simpl "Simplified expression"
116                         (pprCoreExpr expr')
117
118         ; return expr'
119         }
120   where
121     sw_chkr any          = SwBool False -- A bit bogus
122     black_list_nothing v = False        -- Black list nothing
123
124
125 doCorePasses :: DynFlags
126              -> RuleBase        -- the main rule base
127              -> SimplCount      -- simplifier stats
128              -> UniqSupply      -- uniques
129              -> [CoreBind]      -- local binds in (with rules attached)
130              -> [CoreToDo]      -- which passes to do
131              -> IO (SimplCount, [CoreBind])  -- stats, binds, local orphan rules
132
133 doCorePasses dflags rb stats us binds []
134   = return (stats, binds)
135
136 doCorePasses dflags rb stats us binds (to_do : to_dos) 
137   = do
138         let (us1, us2) = splitUniqSupply us
139
140         (stats1, binds1) <- doCorePass dflags rb us1 binds to_do
141
142         doCorePasses dflags rb (stats `plusSimplCount` stats1) us2 binds1 to_dos
143
144 doCorePass dfs rb us binds (CoreDoSimplify sw_chkr) 
145    = _scc_ "Simplify"      simplifyPgm dfs rb sw_chkr us binds
146 doCorePass dfs rb us binds CoreCSE                      
147    = _scc_ "CommonSubExpr" noStats dfs (cseProgram dfs binds)
148 doCorePass dfs rb us binds CoreLiberateCase             
149    = _scc_ "LiberateCase"  noStats dfs (liberateCase dfs binds)
150 doCorePass dfs rb us binds CoreDoFloatInwards       
151    = _scc_ "FloatInwards"  noStats dfs (floatInwards dfs binds)
152 doCorePass dfs rb us binds (CoreDoFloatOutwards f)  
153    = _scc_ "FloatOutwards" noStats dfs (floatOutwards dfs f us binds)
154 doCorePass dfs rb us binds CoreDoStaticArgs             
155    = _scc_ "StaticArgs"    noStats dfs (doStaticArgs us binds)
156 doCorePass dfs rb us binds CoreDoStrictness             
157    = _scc_ "Stranal"       noStats dfs (saBinds dfs binds)
158 doCorePass dfs rb us binds CoreDoWorkerWrapper      
159    = _scc_ "WorkWrap"      noStats dfs (wwTopBinds dfs us binds)
160 doCorePass dfs rb us binds CoreDoSpecialising       
161    = _scc_ "Specialise"    noStats dfs (specProgram dfs us binds)
162 doCorePass dfs rb us binds CoreDoSpecConstr
163    = _scc_ "SpecConstr"    noStats dfs (specConstrProgram dfs us binds)
164 doCorePass dfs rb us binds CoreDoCPResult               
165    = _scc_ "CPResult"      noStats dfs (cprAnalyse dfs binds)
166 doCorePass dfs rb us binds CoreDoPrintCore              
167    = _scc_ "PrintCore"     noStats dfs (printCore binds)
168 doCorePass dfs rb us binds CoreDoUSPInf             
169    = _scc_ "CoreUsageSPInf" noStats dfs (doUsageSPInf dfs us binds)
170 doCorePass dfs rb us binds CoreDoGlomBinds              
171    = noStats dfs (glomBinds dfs binds)
172 doCorePass dfs rb us binds CoreDoNothing
173    = noStats dfs (return binds)
174
175 printCore binds = do dumpIfSet True "Print Core"
176                                (pprCoreBindings binds)
177                      return binds
178
179 -- most passes return no stats and don't change rules
180 noStats dfs thing = do { binds <- thing; return (zeroSimplCount dfs, binds) }
181 \end{code}
182
183
184
185 %************************************************************************
186 %*                                                                      *
187 \subsection{Dealing with rules}
188 %*                                                                      *
189 %************************************************************************
190
191 -- prepareLocalRuleBase takes the CoreBinds and rules defined in this module.
192 -- It attaches those rules that are for local Ids to their binders, and
193 -- returns the remainder attached to Ids in an IdSet.  It also returns
194 -- Ids mentioned on LHS of some rule; these should be blacklisted.
195
196 -- The rule Ids and LHS Ids are black-listed; that is, they aren't inlined
197 -- so that the opportunity to apply the rule isn't lost too soon
198
199 \begin{code}
200 prepareRules :: DynFlags -> PackageRuleBase -> HomeSymbolTable
201              -> UniqSupply
202              -> [CoreBind]
203              -> [IdCoreRule]            -- Local rules
204              -> IO (RuleBase,           -- Full rule base
205                     IdSet,              -- Local rule Ids
206                     [IdCoreRule],       -- Orphan rules
207                     IdSet)              -- RHS free vars of all rules
208
209 prepareRules dflags pkg_rule_base hst us binds local_rules
210   = do  { let (better_rules,_) = initSmpl dflags sw_chkr us local_ids black_list_all 
211                                           (mapSmpl simplRule local_rules)
212
213         ; let (local_rules, orphan_rules) = partition (isLocalId . fst) better_rules
214               rule_rhs_fvs                = unionVarSets (map (ruleRhsFreeVars . snd) better_rules)
215               local_rule_base             = extendRuleBaseList emptyRuleBase local_rules
216               local_rule_ids              = ruleBaseIds local_rule_base -- Local Ids with rules attached
217               imp_rule_base               = foldl add_rules pkg_rule_base (moduleEnvElts hst)
218               rule_base                   = extendRuleBaseList imp_rule_base orphan_rules
219               final_rule_base             = addRuleBaseFVs rule_base (ruleBaseFVs local_rule_base)
220                 -- The last step black-lists the free vars of local rules too
221
222         ; dumpIfSet_dyn dflags Opt_D_dump_rules "Transformation rules"
223                 (vcat [text "Local rules", pprRuleBase local_rule_base,
224                        text "",
225                        text "Imported rules", pprRuleBase final_rule_base])
226
227         ; return (final_rule_base, local_rule_ids, orphan_rules, rule_rhs_fvs)
228     }
229   where
230     sw_chkr any      = SwBool False                     -- A bit bogus
231     black_list_all v = not (isDataConWrapId v)
232                 -- This stops all inlining except the
233                 -- wrappers for data constructors
234
235     add_rules rule_base mds = extendRuleBaseList rule_base (md_rules mds)
236
237         -- Boringly, we need to gather the in-scope set.
238         -- Typically this thunk won't even be forced, but the test in
239         -- simpVar fails if it isn't right, and it might conceiveably matter
240     local_ids = foldr (unionVarSet . mkVarSet . bindersOf) emptyVarSet binds
241
242
243 updateBinders :: IdSet                  -- Locally defined ids with their Rules attached
244               -> IdSet                  -- Ids free in the RHS of local rules
245               -> IsExported
246               -> [CoreBind] -> [CoreBind]
247         -- A horrible function
248
249 -- Update the binders of top-level bindings as follows
250 --      a) Attach the rules for each locally-defined Id to that Id.
251 --      b) Set the no-discard flag if either the Id is exported,
252 --         or it's mentoined in the RHS of a rule
253 -- 
254 -- Reason for (a)
255 --      - It makes the rules easier to look up
256 --      - It means that transformation rules and specialisations for
257 --        locally defined Ids are handled uniformly
258 --      - It keeps alive things that are referred to only from a rule
259 --        (the occurrence analyser knows about rules attached to Ids)
260 --      - It makes sure that, when we apply a rule, the free vars
261 --        of the RHS are more likely to be in scope
262 --
263 -- Reason for (b)
264 --     It means that the binding won't be discarded EVEN if the binding
265 --     ends up being trivial (v = w) -- the simplifier would usually just 
266 --     substitute w for v throughout, but we don't apply the substitution to
267 --     the rules (maybe we should?), so this substitution would make the rule
268 --     bogus.
269
270 updateBinders rule_ids rule_rhs_fvs is_exported binds
271   = map update_bndrs binds
272   where
273     update_bndrs (NonRec b r) = NonRec (update_bndr b) r
274     update_bndrs (Rec prs)    = Rec [(update_bndr b, r) | (b,r) <- prs]
275
276     update_bndr bndr 
277         | isImplicitId bndr = bndr      -- Constructors, selectors; doesn't 
278                                         -- make sense to call setIdNoDiscard
279                                         -- Also can't have rules
280         | dont_discard bndr = setIdNoDiscard bndr_with_rules
281         | otherwise         = bndr_with_rules
282         where
283           bndr_with_rules = lookupVarSet rule_ids bndr `orElse` bndr
284
285     dont_discard bndr =  is_exported (idName bndr)
286                       || bndr `elemVarSet` rule_rhs_fvs 
287 \end{code}
288
289
290 We must do some gentle simplification on the template (but not the RHS)
291 of each rule.  The case that forced me to add this was the fold/build rule,
292 which without simplification looked like:
293         fold k z (build (/\a. g a))  ==>  ...
294 This doesn't match unless you do eta reduction on the build argument.
295
296 \begin{code}
297 simplRule rule@(id, BuiltinRule _)
298   = returnSmpl rule
299 simplRule rule@(id, Rule name bndrs args rhs)
300   = simplBinders bndrs                  $ \ bndrs' -> 
301     mapSmpl simplExprGently args        `thenSmpl` \ args' ->
302     simplExprGently rhs                 `thenSmpl` \ rhs' ->
303     returnSmpl (id, Rule name bndrs' args' rhs')
304
305 -- It's important that simplExprGently does eta reduction.
306 -- For example, in a rule like:
307 --      augment g (build h) 
308 -- we do not want to get
309 --      augment (\a. g a) (build h)
310 -- otherwise we don't match when given an argument like
311 --      (\a. h a a)
312 --
313 -- The simplifier does indeed do eta reduction (it's in
314 -- Simplify.completeLam) but only if -O is on.
315 \end{code}
316
317 \begin{code}
318 simplExprGently :: CoreExpr -> SimplM CoreExpr
319 -- Simplifies an expression 
320 --      does occurrence analysis, then simplification
321 --      and repeats (twice currently) because one pass
322 --      alone leaves tons of crud.
323 -- Used (a) for user expressions typed in at the interactive prompt
324 --      (b) the LHS and RHS of a RULE
325 simplExprGently expr
326   = simplExpr (occurAnalyseGlobalExpr expr)     `thenSmpl` \ expr1 ->
327     simplExpr (occurAnalyseGlobalExpr expr1)
328 \end{code}
329
330
331 %************************************************************************
332 %*                                                                      *
333 \subsection{Glomming}
334 %*                                                                      *
335 %************************************************************************
336
337 \begin{code}
338 glomBinds :: DynFlags -> [CoreBind] -> IO [CoreBind]
339 -- Glom all binds together in one Rec, in case any
340 -- transformations have introduced any new dependencies
341 --
342 -- NB: the global invariant is this:
343 --      *** the top level bindings are never cloned, and are always unique ***
344 --
345 -- We sort them into dependency order, but applying transformation rules may
346 -- make something at the top refer to something at the bottom:
347 --      f = \x -> p (q x)
348 --      h = \y -> 3
349 --      
350 --      RULE:  p (q x) = h x
351 --
352 -- Applying this rule makes f refer to h, 
353 -- although it doesn't appear to in the source program.  
354 -- This pass lets us control where it happens.
355 --
356 -- NOTICE that this cannot happen for rules whose head is a locally-defined
357 -- function.  It only happens for rules whose head is an imported function
358 -- (p in the example above).  So, for example, the rule had been
359 --      RULE: f (p x) = h x
360 -- then the rule for f would be attached to f itself (in its IdInfo) 
361 -- by prepareLocalRuleBase and h would be regarded by the occurrency 
362 -- analyser as free in f.
363
364 glomBinds dflags binds
365   = do { showPass dflags "GlomBinds" ;
366          let { recd_binds = [Rec (flattenBinds binds)] } ;
367          return recd_binds }
368         -- Not much point in printing the result... 
369         -- just consumes output bandwidth
370 \end{code}
371
372
373 %************************************************************************
374 %*                                                                      *
375 \subsection{The driver for the simplifier}
376 %*                                                                      *
377 %************************************************************************
378
379 \begin{code}
380 simplifyPgm :: DynFlags 
381             -> RuleBase
382             -> (SimplifierSwitch -> SwitchResult)
383             -> UniqSupply
384             -> [CoreBind]                   -- Input
385             -> IO (SimplCount, [CoreBind])  -- New bindings
386
387 simplifyPgm dflags rule_base
388             sw_chkr us binds
389   = do {
390         showPass dflags "Simplify";
391
392         (termination_msg, it_count, counts_out, binds') 
393            <- iteration us 1 (zeroSimplCount dflags) binds;
394
395         dumpIfSet (dopt Opt_D_verbose_core2core dflags 
396                    && dopt Opt_D_dump_simpl_stats dflags)
397                   "Simplifier statistics"
398                   (vcat [text termination_msg <+> text "after" <+> ppr it_count <+> text "iterations",
399                          text "",
400                          pprSimplCount counts_out]);
401
402         endPass dflags "Simplify" Opt_D_verbose_core2core binds';
403
404         return (counts_out, binds')
405     }
406   where
407     max_iterations    = getSimplIntSwitch sw_chkr MaxSimplifierIterations
408     black_list_fn     = blackListed rule_lhs_fvs (intSwitchSet sw_chkr SimplInlinePhase)
409     imported_rule_ids = ruleBaseIds rule_base
410     rule_lhs_fvs      = ruleBaseFVs rule_base
411  
412     iteration us iteration_no counts binds
413       -- Try and force thunks off the binds; significantly reduces
414       -- space usage, especially with -O.  JRS, 000620.
415       | let sz = coreBindsSize binds in sz == sz
416       = do {
417                 -- Occurrence analysis
418            let { tagged_binds = _scc_ "OccAnal" occurAnalyseBinds binds } ;
419
420            dumpIfSet_dyn dflags Opt_D_dump_occur_anal "Occurrence analysis"
421                      (pprCoreBindings tagged_binds);
422
423                 -- SIMPLIFY
424                 -- We do this with a *case* not a *let* because lazy pattern
425                 -- matching bit us with bad space leak!
426                 -- With a let, we ended up with
427                 --   let
428                 --      t = initSmpl ...
429                 --      counts' = snd t
430                 --   in
431                 --      case t of {(_,counts') -> if counts'=0 then ...
432                 -- So the conditional didn't force counts', because the
433                 -- selection got duplicated.  Sigh!
434            case initSmpl dflags sw_chkr us1 imported_rule_ids black_list_fn 
435                          (simplTopBinds tagged_binds)
436                 of { (binds', counts') -> do {
437                         -- The imported_rule_ids are used by initSmpl to initialise
438                         -- the in-scope set.  That way, the simplifier will change any
439                         -- occurrences of the imported id to the one in the imported_rule_ids
440                         -- set, which are decorated with their rules.
441
442            let { all_counts = counts `plusSimplCount` counts' } ;
443
444                 -- Stop if nothing happened; don't dump output
445            if isZeroSimplCount counts' then
446                 return ("Simplifier reached fixed point", iteration_no, all_counts, binds')
447            else do {
448
449                 -- Dump the result of this iteration
450            dumpIfSet_dyn dflags Opt_D_dump_simpl_iterations
451                      ("Simplifier iteration " ++ show iteration_no 
452                       ++ " out of " ++ show max_iterations)
453                      (pprSimplCount counts') ;
454
455            endPass dflags 
456                     ("Simplifier iteration " ++ show iteration_no ++ " result")
457                     Opt_D_dump_simpl_iterations
458                     binds' ;
459
460                 -- Stop if we've run out of iterations
461            if iteration_no == max_iterations then
462                 do {
463 #ifdef DEBUG
464                     if  max_iterations > 2 then
465                             hPutStr stderr ("NOTE: Simplifier still going after " ++ 
466                                     show max_iterations ++ 
467                                     " iterations; bailing out.\n")
468                     else 
469 #endif
470                         return ();
471
472                     return ("Simplifier baled out", iteration_no, all_counts, binds')
473                 }
474
475                 -- Else loop
476            else iteration us2 (iteration_no + 1) all_counts binds'
477         }  } } }
478       where
479           (us1, us2) = splitUniqSupply us
480 \end{code}