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