root/compiler/simplCore/SimplCore.lhs

Revision ac230c5ef652e27f61d954281ae6a3195e1f9970, 36.8 KB (checked in by Simon Peyton Jones <simonpj@…>, 4 weeks ago)

Allow cases with empty alterantives

This patch allows, for the first time, case expressions with an empty
list of alternatives. Max suggested the idea, and Trac #6067 showed
that it is really quite important.

So I've implemented the idea, fixing #6067. Main changes

  • See Note [Empty case alternatives] in CoreSyn?
  • Various foldr1's become foldrs
  • IfaceCase? does not record the type of the alternatives. I added IfaceECase for empty-alternative cases.
  • Core Lint does not complain about empty cases
  • MkCore?.castBottomExpr constructs an empty-alternative case expression (case e of ty {})
  • Property mode set to 100644
Line 
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{-# OPTIONS -fno-warn-tabs #-}
8-- The above warning supression flag is a temporary kludge.
9-- While working on this module you are encouraged to remove it and
10-- detab the module (please do the detabbing in a separate patch). See
11--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
12-- for details
13
14module SimplCore ( core2core, simplifyExpr ) where
15
16#include "HsVersions.h"
17
18import DynFlags
19import CoreSyn
20import CoreSubst
21import HscTypes
22import CSE              ( cseProgram )
23import Rules            ( RuleBase, emptyRuleBase, mkRuleBase, unionRuleBase,
24                          extendRuleBaseList, ruleCheckProgram, addSpecInfo, )
25import PprCore          ( pprCoreBindings, pprCoreExpr )
26import OccurAnal        ( occurAnalysePgm, occurAnalyseExpr )
27import IdInfo
28import CoreUtils        ( coreBindsSize, coreBindsStats, exprSize )
29import Simplify         ( simplTopBinds, simplExpr )
30import SimplUtils       ( simplEnvForGHCi, activeRule )
31import SimplEnv
32import SimplMonad
33import CoreMonad
34import qualified ErrUtils as Err
35import FloatIn          ( floatInwards )
36import FloatOut         ( floatOutwards )
37import FamInstEnv
38import Id
39import BasicTypes       ( CompilerPhase(..), isDefaultInlinePragma )
40import VarSet
41import VarEnv
42import LiberateCase     ( liberateCase )
43import SAT              ( doStaticArgs )
44import Specialise       ( specProgram)
45import SpecConstr       ( specConstrProgram)
46import DmdAnal          ( dmdAnalPgm )
47import WorkWrap         ( wwTopBinds )
48import Vectorise        ( vectorise )
49import FastString
50import Util
51
52import UniqSupply       ( UniqSupply, mkSplitUniqSupply, splitUniqSupply )
53import Outputable
54import Control.Monad
55
56#ifdef GHCI
57import Type             ( mkTyConTy )
58import RdrName          ( mkRdrQual )
59import OccName          ( mkVarOcc )
60import PrelNames        ( pluginTyConName )
61import DynamicLoading   ( forceLoadTyCon, lookupRdrNameInModule, getValueSafely )
62import Module           ( ModuleName )
63import Panic
64#endif
65\end{code}
66
67%************************************************************************
68%*                                                                      *
69\subsection{The driver for the simplifier}
70%*                                                                      *
71%************************************************************************
72
73\begin{code}
74core2core :: HscEnv -> ModGuts -> IO ModGuts
75core2core hsc_env guts
76  = do { us <- mkSplitUniqSupply 's'
77       -- make sure all plugins are loaded
78
79       ; let builtin_passes = getCoreToDo dflags
80       ;
81       ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base us mod $
82                        do { all_passes <- addPluginPasses dflags builtin_passes
83                           ; runCorePasses all_passes guts }
84
85{--
86       ; Err.dumpIfSet_dyn dflags Opt_D_dump_core_pipeline
87             "Plugin information" "" -- TODO FIXME: dump plugin info
88--}
89       ; Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_stats
90             "Grand total simplifier statistics"
91             (pprSimplCount stats)
92
93       ; return guts2 }
94  where
95    dflags         = hsc_dflags hsc_env
96    home_pkg_rules = hptRules hsc_env (dep_mods (mg_deps guts))
97    hpt_rule_base  = mkRuleBase home_pkg_rules
98    mod            = mg_module guts
99    -- mod: get the module out of the current HscEnv so we can retrieve it from the monad.
100    -- This is very convienent for the users of the monad (e.g. plugins do not have to
101    -- consume the ModGuts to find the module) but somewhat ugly because mg_module may
102    -- _theoretically_ be changed during the Core pipeline (it's part of ModGuts), which
103    -- would mean our cached value would go out of date.
104\end{code}
105
106
107%************************************************************************
108%*                                                                      *
109           Generating the main optimisation pipeline
110%*                                                                      *
111%************************************************************************
112
113\begin{code}
114getCoreToDo :: DynFlags -> [CoreToDo]
115getCoreToDo dflags
116  = core_todo
117  where
118    opt_level     = optLevel           dflags
119    phases        = simplPhases        dflags
120    max_iter      = maxSimplIterations dflags
121    rule_check    = ruleCheck          dflags
122    strictness    = dopt Opt_Strictness                   dflags
123    full_laziness = dopt Opt_FullLaziness                 dflags
124    do_specialise = dopt Opt_Specialise                   dflags
125    do_float_in   = dopt Opt_FloatIn                      dflags
126    cse           = dopt Opt_CSE                          dflags
127    spec_constr   = dopt Opt_SpecConstr                   dflags
128    liberate_case = dopt Opt_LiberateCase                 dflags
129    static_args   = dopt Opt_StaticArgumentTransformation dflags
130    rules_on      = dopt Opt_EnableRewriteRules           dflags
131    eta_expand_on = dopt Opt_DoLambdaEtaExpansion         dflags
132
133    maybe_rule_check phase = runMaybe rule_check (CoreDoRuleCheck phase)
134
135    maybe_strictness_before phase
136      = runWhen (phase `elem` strictnessBefore dflags) CoreDoStrictness
137
138    base_mode = SimplMode { sm_phase      = panic "base_mode"
139                          , sm_names      = []
140                          , sm_rules      = rules_on
141                          , sm_eta_expand = eta_expand_on
142                          , sm_inline     = True
143                          , sm_case_case  = True }
144
145    simpl_phase phase names iter
146      = CoreDoPasses
147      $   [ maybe_strictness_before phase
148          , CoreDoSimplify iter
149                (base_mode { sm_phase = Phase phase
150                           , sm_names = names })
151
152          , maybe_rule_check (Phase phase) ]
153
154          -- Vectorisation can introduce a fair few common sub expressions involving
155          --  DPH primitives. For example, see the Reverse test from dph-examples.
156          --  We need to eliminate these common sub expressions before their definitions
157          --  are inlined in phase 2. The CSE introduces lots of  v1 = v2 bindings,
158          --  so we also run simpl_gently to inline them.
159      ++  (if dopt Opt_Vectorise dflags && phase == 3
160            then [CoreCSE, simpl_gently]
161            else [])
162
163    vectorisation
164      = runWhen (dopt Opt_Vectorise dflags) $
165          CoreDoPasses [ simpl_gently, CoreDoVectorisation ]
166
167                -- By default, we have 2 phases before phase 0.
168
169                -- Want to run with inline phase 2 after the specialiser to give
170                -- maximum chance for fusion to work before we inline build/augment
171                -- in phase 1.  This made a difference in 'ansi' where an
172                -- overloaded function wasn't inlined till too late.
173
174                -- Need phase 1 so that build/augment get
175                -- inlined.  I found that spectral/hartel/genfft lost some useful
176                -- strictness in the function sumcode' if augment is not inlined
177                -- before strictness analysis runs
178    simpl_phases = CoreDoPasses [ simpl_phase phase ["main"] max_iter
179                                | phase <- [phases, phases-1 .. 1] ]
180
181
182        -- initial simplify: mk specialiser happy: minimum effort please
183    simpl_gently = CoreDoSimplify max_iter
184                       (base_mode { sm_phase = InitialPhase
185                                  , sm_names = ["Gentle"]
186                                  , sm_rules = rules_on   -- Note [RULEs enabled in SimplGently]
187                                  , sm_inline = False
188                                  , sm_case_case = False })
189                          -- Don't do case-of-case transformations.
190                          -- This makes full laziness work better
191
192    core_todo =
193     if opt_level == 0 then
194       [ vectorisation
195       , CoreDoSimplify max_iter
196             (base_mode { sm_phase = Phase 0
197                        , sm_names = ["Non-opt simplification"] }) 
198       ]
199
200     else {- opt_level >= 1 -} [
201
202    -- We want to do the static argument transform before full laziness as it
203    -- may expose extra opportunities to float things outwards. However, to fix
204    -- up the output of the transformation we need at do at least one simplify
205    -- after this before anything else
206        runWhen static_args (CoreDoPasses [ simpl_gently, CoreDoStaticArgs ]),
207
208        -- We run vectorisation here for now, but we might also try to run
209        -- it later
210        vectorisation,
211
212        -- initial simplify: mk specialiser happy: minimum effort please
213        simpl_gently,
214
215        -- Specialisation is best done before full laziness
216        -- so that overloaded functions have all their dictionary lambdas manifest
217        runWhen do_specialise CoreDoSpecialising,
218
219        runWhen full_laziness $
220           CoreDoFloatOutwards FloatOutSwitches {
221                                 floatOutLambdas   = Just 0,
222                                 floatOutConstants = True,
223                                 floatOutPartialApplications = False },
224                -- Was: gentleFloatOutSwitches
225                --
226                -- I have no idea why, but not floating constants to
227                -- top level is very bad in some cases.
228                --
229                -- Notably: p_ident in spectral/rewrite
230                --          Changing from "gentle" to "constantsOnly"
231                --          improved rewrite's allocation by 19%, and
232                --          made 0.0% difference to any other nofib
233                --          benchmark
234                --
235                -- Not doing floatOutPartialApplications yet, we'll do
236                -- that later on when we've had a chance to get more
237                -- accurate arity information.  In fact it makes no
238                -- difference at all to performance if we do it here,
239                -- but maybe we save some unnecessary to-and-fro in
240                -- the simplifier.
241
242        runWhen do_float_in CoreDoFloatInwards,
243
244        simpl_phases,
245
246                -- Phase 0: allow all Ids to be inlined now
247                -- This gets foldr inlined before strictness analysis
248
249                -- At least 3 iterations because otherwise we land up with
250                -- huge dead expressions because of an infelicity in the
251                -- simpifier.
252                --      let k = BIG in foldr k z xs
253                -- ==>  let k = BIG in letrec go = \xs -> ...(k x).... in go xs
254                -- ==>  let k = BIG in letrec go = \xs -> ...(BIG x).... in go xs
255                -- Don't stop now!
256        simpl_phase 0 ["main"] (max max_iter 3),
257
258        runWhen strictness (CoreDoPasses [
259                CoreDoStrictness,
260                CoreDoWorkerWrapper,
261                simpl_phase 0 ["post-worker-wrapper"] max_iter
262                ]),
263
264        runWhen full_laziness $
265           CoreDoFloatOutwards FloatOutSwitches {
266                                 floatOutLambdas   = floatLamArgs dflags,
267                                 floatOutConstants = True,
268                                 floatOutPartialApplications = True },
269                -- nofib/spectral/hartel/wang doubles in speed if you
270                -- do full laziness late in the day.  It only happens
271                -- after fusion and other stuff, so the early pass doesn't
272                -- catch it.  For the record, the redex is
273                --        f_el22 (f_el21 r_midblock)
274
275
276        runWhen cse CoreCSE,
277                -- We want CSE to follow the final full-laziness pass, because it may
278                -- succeed in commoning up things floated out by full laziness.
279                -- CSE used to rely on the no-shadowing invariant, but it doesn't any more
280
281        runWhen do_float_in CoreDoFloatInwards,
282
283        maybe_rule_check (Phase 0),
284
285                -- Case-liberation for -O2.  This should be after
286                -- strictness analysis and the simplification which follows it.
287        runWhen liberate_case (CoreDoPasses [
288            CoreLiberateCase,
289            simpl_phase 0 ["post-liberate-case"] max_iter
290            ]),         -- Run the simplifier after LiberateCase to vastly
291                        -- reduce the possiblility of shadowing
292                        -- Reason: see Note [Shadowing] in SpecConstr.lhs
293
294        runWhen spec_constr CoreDoSpecConstr,
295
296        maybe_rule_check (Phase 0),
297
298        -- Final clean-up simplification:
299        simpl_phase 0 ["final"] max_iter
300     ]
301\end{code}
302
303Loading plugins
304
305\begin{code}
306addPluginPasses :: DynFlags -> [CoreToDo] -> CoreM [CoreToDo]
307#ifndef GHCI
308addPluginPasses _ builtin_passes = return builtin_passes
309#else
310addPluginPasses dflags builtin_passes
311  = do { hsc_env <- getHscEnv
312       ; named_plugins <- liftIO (loadPlugins hsc_env)
313       ; foldM query_plug builtin_passes named_plugins }
314  where
315    query_plug todos (mod_nm, plug)
316       = installCoreToDos plug options todos
317       where
318         options = [ option | (opt_mod_nm, option) <- pluginModNameOpts dflags
319                            , opt_mod_nm == mod_nm ]
320
321loadPlugins :: HscEnv -> IO [(ModuleName, Plugin)]
322loadPlugins hsc_env
323  = do { let to_load = pluginModNames (hsc_dflags hsc_env)
324       ; plugins <- mapM (loadPlugin hsc_env) to_load
325       ; return $ to_load `zip` plugins }
326
327loadPlugin :: HscEnv -> ModuleName -> IO Plugin
328loadPlugin hsc_env mod_name
329  = do { let plugin_rdr_name = mkRdrQual mod_name (mkVarOcc "plugin")
330       ; mb_name <- lookupRdrNameInModule hsc_env mod_name plugin_rdr_name
331       ; case mb_name of {
332            Nothing -> throwGhcException (CmdLineError $ showSDoc $ hsep
333                          [ ptext (sLit "The module"), ppr mod_name
334                          , ptext (sLit "did not export the plugin name")
335                          , ppr plugin_rdr_name ]) ;
336            Just name ->
337
338     do { plugin_tycon <- forceLoadTyCon hsc_env pluginTyConName
339        ; mb_plugin <- getValueSafely hsc_env name (mkTyConTy plugin_tycon)
340        ; case mb_plugin of
341            Nothing -> throwGhcException (CmdLineError $ showSDoc $ hsep
342                          [ ptext (sLit "The value"), ppr name
343                          , ptext (sLit "did not have the type")
344                          , ppr pluginTyConName, ptext (sLit "as required")])
345            Just plugin -> return plugin } } }
346#endif
347\end{code}
348
349%************************************************************************
350%*                                                                      *
351                  The CoreToDo interpreter
352%*                                                                      *
353%************************************************************************
354
355\begin{code}
356runCorePasses :: [CoreToDo] -> ModGuts -> CoreM ModGuts
357runCorePasses passes guts
358  = foldM do_pass guts passes
359  where
360    do_pass guts CoreDoNothing = return guts
361    do_pass guts (CoreDoPasses ps) = runCorePasses ps guts
362    do_pass guts pass
363       = do { dflags <- getDynFlags
364            ; liftIO $ showPass dflags pass
365            ; guts' <- doCorePass pass guts
366            ; liftIO $ endPass dflags pass (mg_binds guts') (mg_rules guts')
367            ; return guts' }
368
369doCorePass :: CoreToDo -> ModGuts -> CoreM ModGuts
370doCorePass pass@(CoreDoSimplify {})  = {-# SCC "Simplify" #-}
371                                       simplifyPgm pass
372
373doCorePass CoreCSE                   = {-# SCC "CommonSubExpr" #-}
374                                       doPass cseProgram
375
376doCorePass CoreLiberateCase          = {-# SCC "LiberateCase" #-}
377                                       doPassD liberateCase
378
379doCorePass CoreDoFloatInwards        = {-# SCC "FloatInwards" #-}
380                                       doPass floatInwards
381
382doCorePass (CoreDoFloatOutwards f)   = {-# SCC "FloatOutwards" #-}
383                                       doPassDUM (floatOutwards f)
384
385doCorePass CoreDoStaticArgs          = {-# SCC "StaticArgs" #-}
386                                       doPassU doStaticArgs
387
388doCorePass CoreDoStrictness          = {-# SCC "Stranal" #-}
389                                       doPassDM dmdAnalPgm
390
391doCorePass CoreDoWorkerWrapper       = {-# SCC "WorkWrap" #-}
392                                       doPassU wwTopBinds
393
394doCorePass CoreDoSpecialising        = {-# SCC "Specialise" #-}
395                                       specProgram
396
397doCorePass CoreDoSpecConstr          = {-# SCC "SpecConstr" #-}
398                                       specConstrProgram
399
400doCorePass CoreDoVectorisation       = {-# SCC "Vectorise" #-}
401                                       vectorise
402
403doCorePass CoreDoPrintCore              = observe   printCore
404doCorePass (CoreDoRuleCheck phase pat)  = ruleCheckPass phase pat
405doCorePass CoreDoNothing                = return
406doCorePass (CoreDoPasses passes)        = runCorePasses passes
407
408#ifdef GHCI
409doCorePass (CoreDoPluginPass _ pass) = {-# SCC "Plugin" #-} pass
410#endif
411
412doCorePass pass = pprPanic "doCorePass" (ppr pass)
413\end{code}
414
415%************************************************************************
416%*                                                                      *
417\subsection{Core pass combinators}
418%*                                                                      *
419%************************************************************************
420
421\begin{code}
422printCore :: a -> CoreProgram -> IO ()
423printCore _ binds = Err.dumpIfSet True "Print Core" (pprCoreBindings binds)
424
425ruleCheckPass :: CompilerPhase -> String -> ModGuts -> CoreM ModGuts
426ruleCheckPass current_phase pat guts = do
427    rb <- getRuleBase
428    dflags <- getDynFlags
429    liftIO $ Err.showPass dflags "RuleCheck"
430    liftIO $ printDump (ruleCheckProgram current_phase pat rb (mg_binds guts))
431    return guts
432
433
434doPassDUM :: (DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram) -> ModGuts -> CoreM ModGuts
435doPassDUM do_pass = doPassM $ \binds -> do
436    dflags <- getDynFlags
437    us     <- getUniqueSupplyM
438    liftIO $ do_pass dflags us binds
439
440doPassDM :: (DynFlags -> CoreProgram -> IO CoreProgram) -> ModGuts -> CoreM ModGuts
441doPassDM do_pass = doPassDUM (\dflags -> const (do_pass dflags))
442
443doPassD :: (DynFlags -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
444doPassD do_pass = doPassDM (\dflags -> return . do_pass dflags)
445
446doPassDU :: (DynFlags -> UniqSupply -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
447doPassDU do_pass = doPassDUM (\dflags us -> return . do_pass dflags us)
448
449doPassU :: (UniqSupply -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
450doPassU do_pass = doPassDU (const do_pass)
451
452-- Most passes return no stats and don't change rules: these combinators
453-- let us lift them to the full blown ModGuts+CoreM world
454doPassM :: Monad m => (CoreProgram -> m CoreProgram) -> ModGuts -> m ModGuts
455doPassM bind_f guts = do
456    binds' <- bind_f (mg_binds guts)
457    return (guts { mg_binds = binds' })
458
459doPass :: (CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
460doPass bind_f guts = return $ guts { mg_binds = bind_f (mg_binds guts) }
461
462-- Observer passes just peek; don't modify the bindings at all
463observe :: (DynFlags -> CoreProgram -> IO a) -> ModGuts -> CoreM ModGuts
464observe do_pass = doPassM $ \binds -> do
465    dflags <- getDynFlags
466    _ <- liftIO $ do_pass dflags binds
467    return binds
468\end{code}
469
470
471%************************************************************************
472%*                                                                      *
473        Gentle simplification
474%*                                                                      *
475%************************************************************************
476
477\begin{code}
478simplifyExpr :: DynFlags -- includes spec of what core-to-core passes to do
479             -> CoreExpr
480             -> IO CoreExpr
481-- simplifyExpr is called by the driver to simplify an
482-- expression typed in at the interactive prompt
483--
484-- Also used by Template Haskell
485simplifyExpr dflags expr
486  = do  {
487        ; Err.showPass dflags "Simplify"
488
489        ; us <-  mkSplitUniqSupply 's'
490
491        ; let sz = exprSize expr
492              (expr', counts) = initSmpl dflags emptyRuleBase emptyFamInstEnvs us sz $
493                                 simplExprGently (simplEnvForGHCi dflags) expr
494
495        ; Err.dumpIfSet (dopt Opt_D_dump_simpl_stats dflags)
496                  "Simplifier statistics" (pprSimplCount counts)
497
498        ; Err.dumpIfSet_dyn dflags Opt_D_dump_simpl "Simplified expression"
499                        (pprCoreExpr expr')
500
501        ; return expr'
502        }
503
504simplExprGently :: SimplEnv -> CoreExpr -> SimplM CoreExpr
505-- Simplifies an expression
506--      does occurrence analysis, then simplification
507--      and repeats (twice currently) because one pass
508--      alone leaves tons of crud.
509-- Used (a) for user expressions typed in at the interactive prompt
510--      (b) the LHS and RHS of a RULE
511--      (c) Template Haskell splices
512--
513-- The name 'Gently' suggests that the SimplifierMode is SimplGently,
514-- and in fact that is so.... but the 'Gently' in simplExprGently doesn't
515-- enforce that; it just simplifies the expression twice
516
517-- It's important that simplExprGently does eta reduction; see
518-- Note [Simplifying the left-hand side of a RULE] above.  The
519-- simplifier does indeed do eta reduction (it's in Simplify.completeLam)
520-- but only if -O is on.
521
522simplExprGently env expr = do
523    expr1 <- simplExpr env (occurAnalyseExpr expr)
524    simplExpr env (occurAnalyseExpr expr1)
525\end{code}
526
527
528%************************************************************************
529%*                                                                      *
530\subsection{The driver for the simplifier}
531%*                                                                      *
532%************************************************************************
533
534\begin{code}
535simplifyPgm :: CoreToDo -> ModGuts -> CoreM ModGuts
536simplifyPgm pass guts
537  = do { hsc_env <- getHscEnv
538       ; us <- getUniqueSupplyM
539       ; rb <- getRuleBase
540       ; liftIOWithCount $
541         simplifyPgmIO pass hsc_env us rb guts }
542
543simplifyPgmIO :: CoreToDo
544              -> HscEnv
545              -> UniqSupply
546              -> RuleBase
547              -> ModGuts
548              -> IO (SimplCount, ModGuts)  -- New bindings
549
550simplifyPgmIO pass@(CoreDoSimplify max_iterations mode)
551              hsc_env us hpt_rule_base
552              guts@(ModGuts { mg_module = this_mod
553                            , mg_binds = binds, mg_rules = rules
554                            , mg_fam_inst_env = fam_inst_env })
555  = do { (termination_msg, it_count, counts_out, guts')
556           <- do_iteration us 1 [] binds rules
557
558        ; Err.dumpIfSet (dump_phase && dopt Opt_D_dump_simpl_stats dflags)
559                  "Simplifier statistics for following pass"
560                  (vcat [text termination_msg <+> text "after" <+> ppr it_count <+> text "iterations",
561                         blankLine,
562                         pprSimplCount counts_out])
563
564        ; return (counts_out, guts')
565    }
566  where
567    dflags      = hsc_dflags hsc_env
568    dump_phase  = dumpSimplPhase dflags mode
569    simpl_env   = mkSimplEnv mode
570    active_rule = activeRule simpl_env
571
572    do_iteration :: UniqSupply
573                 -> Int          -- Counts iterations
574                 -> [SimplCount] -- Counts from earlier iterations, reversed
575                 -> CoreProgram  -- Bindings in
576                 -> [CoreRule]   -- and orphan rules
577                 -> IO (String, Int, SimplCount, ModGuts)
578
579    do_iteration us iteration_no counts_so_far binds rules
580        -- iteration_no is the number of the iteration we are
581        -- about to begin, with '1' for the first
582      | iteration_no > max_iterations   -- Stop if we've run out of iterations
583      = WARN( debugIsOn && (max_iterations > 2)
584            , hang (ptext (sLit "Simplifier baling out after") <+> int max_iterations
585                    <+> ptext (sLit "iterations")
586                    <+> (brackets $ hsep $ punctuate comma $
587                         map (int . simplCountN) (reverse counts_so_far)))
588                 2 (ptext (sLit "Size =") <+> ppr (coreBindsStats binds)))
589
590                -- Subtract 1 from iteration_no to get the
591                -- number of iterations we actually completed
592        return ( "Simplifier baled out", iteration_no - 1
593               , totalise counts_so_far
594               , guts { mg_binds = binds, mg_rules = rules } )
595
596      -- Try and force thunks off the binds; significantly reduces
597      -- space usage, especially with -O.  JRS, 000620.
598      | let sz = coreBindsSize binds
599      , sz == sz     -- Force it
600      = do {
601                -- Occurrence analysis
602           let {   -- During the 'InitialPhase' (i.e., before vectorisation), we need to make sure
603                   -- that the right-hand sides of vectorisation declarations are taken into
604                   -- account during occurence analysis.
605                 maybeVects   = case sm_phase mode of
606                                  InitialPhase -> mg_vect_decls guts
607                                  _            -> []
608               ; tagged_binds = {-# SCC "OccAnal" #-}
609                     occurAnalysePgm this_mod active_rule rules maybeVects binds
610               } ;
611           Err.dumpIfSet_dyn dflags Opt_D_dump_occur_anal "Occurrence analysis"
612                     (pprCoreBindings tagged_binds);
613
614                -- Get any new rules, and extend the rule base
615                -- See Note [Overall plumbing for rules] in Rules.lhs
616                -- We need to do this regularly, because simplification can
617                -- poke on IdInfo thunks, which in turn brings in new rules
618                -- behind the scenes.  Otherwise there's a danger we'll simply
619                -- miss the rules for Ids hidden inside imported inlinings
620           eps <- hscEPS hsc_env ;
621           let  { rule_base1 = unionRuleBase hpt_rule_base (eps_rule_base eps)
622                ; rule_base2 = extendRuleBaseList rule_base1 rules
623                ; simpl_binds = {-# SCC "SimplTopBinds" #-}
624                                simplTopBinds simpl_env tagged_binds
625                ; fam_envs = (eps_fam_inst_env eps, fam_inst_env) } ;
626
627                -- Simplify the program
628                -- We do this with a *case* not a *let* because lazy pattern
629                -- matching bit us with bad space leak!
630                -- With a let, we ended up with
631                --   let
632                --      t = initSmpl ...
633                --      counts1 = snd t
634                --   in
635                --      case t of {(_,counts1) -> if counts1=0 then ... }
636                -- So the conditional didn't force counts1, because the
637                -- selection got duplicated.  Sigh!
638           case initSmpl dflags rule_base2 fam_envs us1 sz simpl_binds of {
639                (env1, counts1) -> do {
640
641           let  { binds1 = getFloatBinds env1
642                ; rules1 = substRulesForImportedIds (mkCoreSubst (text "imp-rules") env1) rules
643                } ;
644
645                -- Stop if nothing happened; don't dump output
646           if isZeroSimplCount counts1 then
647                return ( "Simplifier reached fixed point", iteration_no
648                       , totalise (counts1 : counts_so_far)  -- Include "free" ticks
649                       , guts { mg_binds = binds1, mg_rules = rules1 } )
650           else do {
651                -- Short out indirections
652                -- We do this *after* at least one run of the simplifier
653                -- because indirection-shorting uses the export flag on *occurrences*
654                -- and that isn't guaranteed to be ok until after the first run propagates
655                -- stuff from the binding site to its occurrences
656                --
657                -- ToDo: alas, this means that indirection-shorting does not happen at all
658                --       if the simplifier does nothing (not common, I know, but unsavoury)
659           let { binds2 = {-# SCC "ZapInd" #-} shortOutIndirections binds1 } ;
660
661                -- Dump the result of this iteration
662           end_iteration dflags pass iteration_no counts1 binds2 rules1 ;
663
664                -- Loop
665           do_iteration us2 (iteration_no + 1) (counts1:counts_so_far) binds2 rules1
666           } } } }
667      | otherwise = panic "do_iteration"
668      where
669        (us1, us2) = splitUniqSupply us
670
671        -- Remember the counts_so_far are reversed
672        totalise :: [SimplCount] -> SimplCount
673        totalise = foldr (\c acc -> acc `plusSimplCount` c)
674                         (zeroSimplCount dflags)
675
676simplifyPgmIO _ _ _ _ _ = panic "simplifyPgmIO"
677
678-------------------
679end_iteration :: DynFlags -> CoreToDo -> Int
680             -> SimplCount -> CoreProgram -> [CoreRule] -> IO ()
681end_iteration dflags pass iteration_no counts binds rules
682  = do { dumpPassResult dflags mb_flag hdr pp_counts binds rules
683       ; lintPassResult dflags pass binds }
684  where
685    mb_flag | dopt Opt_D_dump_simpl_iterations dflags = Just Opt_D_dump_simpl_phases
686            | otherwise                               = Nothing
687            -- Show details if Opt_D_dump_simpl_iterations is on
688
689    hdr = ptext (sLit "Simplifier iteration=") <> int iteration_no
690    pp_counts = vcat [ ptext (sLit "---- Simplifier counts for") <+> hdr
691                     , pprSimplCount counts
692                     , ptext (sLit "---- End of simplifier counts for") <+> hdr ]
693\end{code}
694
695
696%************************************************************************
697%*                                                                      *
698                Shorting out indirections
699%*                                                                      *
700%************************************************************************
701
702If we have this:
703
704        x_local = <expression>
705        ...bindings...
706        x_exported = x_local
707
708where x_exported is exported, and x_local is not, then we replace it with this:
709
710        x_exported = <expression>
711        x_local = x_exported
712        ...bindings...
713
714Without this we never get rid of the x_exported = x_local thing.  This
715save a gratuitous jump (from \tr{x_exported} to \tr{x_local}), and
716makes strictness information propagate better.  This used to happen in
717the final phase, but it's tidier to do it here.
718
719Note [Transferring IdInfo]
720~~~~~~~~~~~~~~~~~~~~~~~~~~
721We want to propagage any useful IdInfo on x_local to x_exported.
722
723STRICTNESS: if we have done strictness analysis, we want the strictness info on
724x_local to transfer to x_exported.  Hence the copyIdInfo call.
725
726RULES: we want to *add* any RULES for x_local to x_exported.
727
728
729Note [Messing up the exported Id's RULES]
730~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
731We must be careful about discarding (obviously) or even merging the
732RULES on the exported Id. The example that went bad on me at one stage
733was this one:
734
735    iterate :: (a -> a) -> a -> [a]
736        [Exported]
737    iterate = iterateList
738
739    iterateFB c f x = x `c` iterateFB c f (f x)
740    iterateList f x =  x : iterateList f (f x)
741        [Not exported]
742
743    {-# RULES
744    "iterate"   forall f x.     iterate f x = build (\c _n -> iterateFB c f x)
745    "iterateFB"                 iterateFB (:) = iterateList
746     #-}
747
748This got shorted out to:
749
750    iterateList :: (a -> a) -> a -> [a]
751    iterateList = iterate
752
753    iterateFB c f x = x `c` iterateFB c f (f x)
754    iterate f x =  x : iterate f (f x)
755
756    {-# RULES
757    "iterate"   forall f x.     iterate f x = build (\c _n -> iterateFB c f x)
758    "iterateFB"                 iterateFB (:) = iterate
759     #-}
760
761And now we get an infinite loop in the rule system
762        iterate f x -> build (\cn -> iterateFB c f x)
763                    -> iterateFB (:) f x
764                    -> iterate f x
765
766Old "solution":
767        use rule switching-off pragmas to get rid
768        of iterateList in the first place
769
770But in principle the user *might* want rules that only apply to the Id
771he says.  And inline pragmas are similar
772   {-# NOINLINE f #-}
773   f = local
774   local = <stuff>
775Then we do not want to get rid of the NOINLINE.
776
777Hence hasShortableIdinfo.
778
779
780Note [Rules and indirection-zapping]
781~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
782Problem: what if x_exported has a RULE that mentions something in ...bindings...?
783Then the things mentioned can be out of scope!  Solution
784 a) Make sure that in this pass the usage-info from x_exported is
785        available for ...bindings...
786 b) If there are any such RULES, rec-ify the entire top-level.
787    It'll get sorted out next time round
788
789Other remarks
790~~~~~~~~~~~~~
791If more than one exported thing is equal to a local thing (i.e., the
792local thing really is shared), then we do one only:
793\begin{verbatim}
794        x_local = ....
795        x_exported1 = x_local
796        x_exported2 = x_local
797==>
798        x_exported1 = ....
799
800        x_exported2 = x_exported1
801\end{verbatim}
802
803We rely on prior eta reduction to simplify things like
804\begin{verbatim}
805        x_exported = /\ tyvars -> x_local tyvars
806==>
807        x_exported = x_local
808\end{verbatim}
809Hence,there's a possibility of leaving unchanged something like this:
810\begin{verbatim}
811        x_local = ....
812        x_exported1 = x_local Int
813\end{verbatim}
814By the time we've thrown away the types in STG land this
815could be eliminated.  But I don't think it's very common
816and it's dangerous to do this fiddling in STG land
817because we might elminate a binding that's mentioned in the
818unfolding for something.
819
820\begin{code}
821type IndEnv = IdEnv Id          -- Maps local_id -> exported_id
822
823shortOutIndirections :: CoreProgram -> CoreProgram
824shortOutIndirections binds
825  | isEmptyVarEnv ind_env = binds
826  | no_need_to_flatten    = binds'                      -- See Note [Rules and indirect-zapping]
827  | otherwise             = [Rec (flattenBinds binds')] -- for this no_need_to_flatten stuff
828  where
829    ind_env            = makeIndEnv binds
830    exp_ids            = varSetElems ind_env    -- These exported Ids are the subjects
831    exp_id_set         = mkVarSet exp_ids       -- of the indirection-elimination
832    no_need_to_flatten = all (null . specInfoRules . idSpecialisation) exp_ids
833    binds'             = concatMap zap binds
834
835    zap (NonRec bndr rhs) = [NonRec b r | (b,r) <- zapPair (bndr,rhs)]
836    zap (Rec pairs)       = [Rec (concatMap zapPair pairs)]
837
838    zapPair (bndr, rhs)
839        | bndr `elemVarSet` exp_id_set             = []
840        | Just exp_id <- lookupVarEnv ind_env bndr = [(transferIdInfo exp_id bndr, rhs),
841                                                      (bndr, Var exp_id)]
842        | otherwise                                = [(bndr,rhs)]
843
844makeIndEnv :: [CoreBind] -> IndEnv
845makeIndEnv binds
846  = foldr add_bind emptyVarEnv binds
847  where
848    add_bind :: CoreBind -> IndEnv -> IndEnv
849    add_bind (NonRec exported_id rhs) env = add_pair (exported_id, rhs) env
850    add_bind (Rec pairs)              env = foldr add_pair env pairs
851
852    add_pair :: (Id,CoreExpr) -> IndEnv -> IndEnv
853    add_pair (exported_id, Var local_id) env
854        | shortMeOut env exported_id local_id = extendVarEnv env local_id exported_id
855    add_pair _ env = env
856
857-----------------
858shortMeOut :: IndEnv -> Id -> Id -> Bool
859shortMeOut ind_env exported_id local_id
860-- The if-then-else stuff is just so I can get a pprTrace to see
861-- how often I don't get shorting out becuase of IdInfo stuff
862  = if isExportedId exported_id &&              -- Only if this is exported
863
864       isLocalId local_id &&                    -- Only if this one is defined in this
865                                                --      module, so that we *can* change its
866                                                --      binding to be the exported thing!
867
868       not (isExportedId local_id) &&           -- Only if this one is not itself exported,
869                                                --      since the transformation will nuke it
870
871       not (local_id `elemVarEnv` ind_env)      -- Only if not already substituted for
872    then
873        if hasShortableIdInfo exported_id
874        then True       -- See Note [Messing up the exported Id's IdInfo]
875        else WARN( True, ptext (sLit "Not shorting out:") <+> ppr exported_id )
876             False
877    else
878        False
879
880-----------------
881hasShortableIdInfo :: Id -> Bool
882-- True if there is no user-attached IdInfo on exported_id,
883-- so we can safely discard it
884-- See Note [Messing up the exported Id's IdInfo]
885hasShortableIdInfo id
886  =  isEmptySpecInfo (specInfo info)
887  && isDefaultInlinePragma (inlinePragInfo info)
888  && not (isStableUnfolding (unfoldingInfo info))
889  where
890     info = idInfo id
891
892-----------------
893transferIdInfo :: Id -> Id -> Id
894-- See Note [Transferring IdInfo]
895-- If we have
896--      lcl_id = e; exp_id = lcl_id
897-- and lcl_id has useful IdInfo, we don't want to discard it by going
898--      gbl_id = e; lcl_id = gbl_id
899-- Instead, transfer IdInfo from lcl_id to exp_id
900-- Overwriting, rather than merging, seems to work ok.
901transferIdInfo exported_id local_id
902  = modifyIdInfo transfer exported_id
903  where
904    local_info = idInfo local_id
905    transfer exp_info = exp_info `setStrictnessInfo` strictnessInfo local_info
906                                 `setUnfoldingInfo`     unfoldingInfo local_info
907                                 `setInlinePragInfo`    inlinePragInfo local_info
908                                 `setSpecInfo`          addSpecInfo (specInfo exp_info) new_info
909    new_info = setSpecInfoHead (idName exported_id)
910                               (specInfo local_info)
911        -- Remember to set the function-name field of the
912        -- rules as we transfer them from one function to another
913\end{code}
Note: See TracBrowser for help on using the browser.