2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[SimplCore]{Driver for simplifying @Core@ programs}
8 -- The above warning supression flag is a temporary kludge.
9 -- While working on this module you are encouraged to remove it and fix
10 -- any warnings in the module. See
11 -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
14 module SimplCore ( core2core, simplifyExpr ) where
16 #include "HsVersions.h"
18 import DynFlags ( CoreToDo(..), SimplifierSwitch(..),
19 SimplifierMode(..), DynFlags, DynFlag(..), dopt,
20 getCoreToDo, shouldDumpSimplPhase )
23 import CSE ( cseProgram )
24 import Rules ( RuleBase, emptyRuleBase, mkRuleBase, unionRuleBase,
25 extendRuleBaseList, pprRuleBase, ruleCheckProgram,
26 addSpecInfo, addIdSpecialisations )
27 import PprCore ( pprCoreBindings, pprCoreExpr, pprRules )
28 import OccurAnal ( occurAnalysePgm, occurAnalyseExpr )
29 import IdInfo ( setNewStrictnessInfo, newStrictnessInfo,
30 setWorkerInfo, workerInfo, setSpecInfoHead,
31 setInlinePragInfo, inlinePragInfo,
32 setSpecInfo, specInfo, specInfoRules )
33 import CoreUtils ( coreBindsSize )
34 import Simplify ( simplTopBinds, simplExpr )
35 import SimplEnv ( SimplEnv, simplBinders, mkSimplEnv, setInScopeSet )
37 import ErrUtils ( dumpIfSet, dumpIfSet_dyn, showPass )
38 import CoreLint ( endPassIf, endIteration )
39 import FloatIn ( floatInwards )
40 import FloatOut ( floatOutwards )
44 import TyCon ( tyConSelIds, tyConDataCons )
45 import Class ( classSelIds )
48 import NameEnv ( lookupNameEnv )
49 import LiberateCase ( liberateCase )
50 import SAT ( doStaticArgs )
51 import Specialise ( specProgram)
52 import SpecConstr ( specConstrProgram)
53 import DmdAnal ( dmdAnalPgm )
54 import WorkWrap ( wwTopBinds )
56 import StrictAnal ( saBinds )
57 import CprAnalyse ( cprAnalyse )
59 import Vectorise ( vectorise )
62 import UniqSupply ( UniqSupply, mkSplitUniqSupply, splitUniqSupply )
63 import IO ( hPutStr, stderr )
66 import List ( partition, intersperse )
70 %************************************************************************
72 \subsection{The driver for the simplifier}
74 %************************************************************************
81 core2core hsc_env guts
83 ; let dflags = hsc_dflags hsc_env
84 core_todos = getCoreToDo dflags
86 ; us <- mkSplitUniqSupply 's'
87 ; let (cp_us, ru_us) = splitUniqSupply us
89 -- COMPUTE THE RULE BASE TO USE
90 ; (imp_rule_base, guts1) <- prepareRules hsc_env guts ru_us
92 -- Note [Injecting implicit bindings]
93 ; let implicit_binds = getImplicitBinds (mg_types guts1)
94 guts2 = guts1 { mg_binds = implicit_binds ++ mg_binds guts1 }
97 ; (stats, guts3) <- doCorePasses hsc_env imp_rule_base cp_us
98 (zeroSimplCount dflags)
101 ; dumpIfSet_dyn dflags Opt_D_dump_simpl_stats
102 "Grand total simplifier statistics"
103 (pprSimplCount stats)
108 simplifyExpr :: DynFlags -- includes spec of what core-to-core passes to do
111 -- simplifyExpr is called by the driver to simplify an
112 -- expression typed in at the interactive prompt
113 simplifyExpr dflags expr
115 ; showPass dflags "Simplify"
117 ; us <- mkSplitUniqSupply 's'
119 ; let (expr', _counts) = initSmpl dflags emptyRuleBase emptyFamInstEnvs us $
120 simplExprGently gentleSimplEnv expr
122 ; dumpIfSet_dyn dflags Opt_D_dump_simpl "Simplified expression"
128 gentleSimplEnv :: SimplEnv
129 gentleSimplEnv = mkSimplEnv SimplGently (isAmongSimpl [])
131 doCorePasses :: HscEnv
132 -> RuleBase -- the imported main rule base
133 -> UniqSupply -- uniques
134 -> SimplCount -- simplifier stats
135 -> ModGuts -- local binds in (with rules attached)
136 -> [CoreToDo] -- which passes to do
137 -> IO (SimplCount, ModGuts)
139 doCorePasses hsc_env rb us stats guts []
140 = return (stats, guts)
142 doCorePasses hsc_env rb us stats guts (CoreDoPasses to_dos1 : to_dos2)
143 = doCorePasses hsc_env rb us stats guts (to_dos1 ++ to_dos2)
145 doCorePasses hsc_env rb us stats guts (to_do : to_dos)
147 let (us1, us2) = splitUniqSupply us
148 (stats1, guts1) <- doCorePass to_do hsc_env us1 rb guts
149 doCorePasses hsc_env rb us2 (stats `plusSimplCount` stats1) guts1 to_dos
151 doCorePass :: CoreToDo -> HscEnv -> UniqSupply -> RuleBase
152 -> ModGuts -> IO (SimplCount, ModGuts)
153 doCorePass (CoreDoSimplify mode sws) = {-# SCC "Simplify" #-} simplifyPgm mode sws
154 doCorePass CoreCSE = {-# SCC "CommonSubExpr" #-} trBinds cseProgram
155 doCorePass CoreLiberateCase = {-# SCC "LiberateCase" #-} liberateCase
156 doCorePass CoreDoFloatInwards = {-# SCC "FloatInwards" #-} trBinds floatInwards
157 doCorePass (CoreDoFloatOutwards f) = {-# SCC "FloatOutwards" #-} trBindsU (floatOutwards f)
158 doCorePass CoreDoStaticArgs = {-# SCC "StaticArgs" #-} trBindsU doStaticArgs
159 doCorePass CoreDoStrictness = {-# SCC "Stranal" #-} trBinds dmdAnalPgm
160 doCorePass CoreDoWorkerWrapper = {-# SCC "WorkWrap" #-} trBindsU wwTopBinds
161 doCorePass CoreDoSpecialising = {-# SCC "Specialise" #-} trBindsU specProgram
162 doCorePass CoreDoSpecConstr = {-# SCC "SpecConstr" #-} trBindsU specConstrProgram
163 doCorePass CoreDoGlomBinds = trBinds glomBinds
164 doCorePass CoreDoVectorisation = {-# SCC "Vectorise" #-} vectorise
165 doCorePass CoreDoPrintCore = observe printCore
166 doCorePass (CoreDoRuleCheck phase pat) = ruleCheck phase pat
167 doCorePass CoreDoNothing = observe (\ _ _ -> return ())
168 #ifdef OLD_STRICTNESS
169 doCorePass CoreDoOldStrictness = {-# SCC "OldStrictness" #-} trBinds doOldStrictness
171 doCorePass CoreDoOldStrictness = panic "CoreDoOldStrictness"
173 doCorePass (CoreDoPasses _) = panic "CoreDoPasses"
175 #ifdef OLD_STRICTNESS
176 doOldStrictness dfs binds
177 = do binds1 <- saBinds dfs binds
178 binds2 <- cprAnalyse dfs binds1
182 printCore _ binds = dumpIfSet True "Print Core" (pprCoreBindings binds)
184 ruleCheck phase pat hsc_env us rb guts
185 = do let dflags = hsc_dflags hsc_env
186 showPass dflags "RuleCheck"
187 printDump (ruleCheckProgram phase pat rb (mg_binds guts))
188 return (zeroSimplCount dflags, guts)
190 -- Most passes return no stats and don't change rules
191 trBinds :: (DynFlags -> [CoreBind] -> IO [CoreBind])
192 -> HscEnv -> UniqSupply -> RuleBase -> ModGuts
193 -> IO (SimplCount, ModGuts)
194 trBinds do_pass hsc_env us rb guts
195 = do { binds' <- do_pass dflags (mg_binds guts)
196 ; return (zeroSimplCount dflags, guts { mg_binds = binds' }) }
198 dflags = hsc_dflags hsc_env
200 trBindsU :: (DynFlags -> UniqSupply -> [CoreBind] -> IO [CoreBind])
201 -> HscEnv -> UniqSupply -> RuleBase -> ModGuts
202 -> IO (SimplCount, ModGuts)
203 trBindsU do_pass hsc_env us rb guts
204 = do { binds' <- do_pass dflags us (mg_binds guts)
205 ; return (zeroSimplCount dflags, guts { mg_binds = binds' }) }
207 dflags = hsc_dflags hsc_env
209 -- Observer passes just peek; don't modify the bindings at all
210 observe :: (DynFlags -> [CoreBind] -> IO a)
211 -> HscEnv -> UniqSupply -> RuleBase -> ModGuts
212 -> IO (SimplCount, ModGuts)
213 observe do_pass hsc_env us rb guts
214 = do { binds <- do_pass dflags (mg_binds guts)
215 ; return (zeroSimplCount dflags, guts) }
217 dflags = hsc_dflags hsc_env
221 %************************************************************************
225 %************************************************************************
227 Note [Injecting implicit bindings]
228 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229 We used to inject the implict bindings right at the end, in CoreTidy.
230 But some of these bindings, notably record selectors, are not
231 constructed in an optimised form. E.g. record selector for
232 data T = MkT { x :: {-# UNPACK #-} !Int }
233 Then the unfolding looks like
234 x = \t. case t of MkT x1 -> let x = I# x1 in x
235 This generates bad code unless it's first simplified a bit.
236 (Only matters when the selector is used curried; eg map x ys.)
240 getImplicitBinds :: TypeEnv -> [CoreBind]
241 getImplicitBinds type_env
242 = map get_defn (concatMap implicit_con_ids (typeEnvTyCons type_env)
243 ++ concatMap other_implicit_ids (typeEnvElts type_env))
244 -- Put the constructor wrappers first, because
245 -- other implicit bindings (notably the fromT functions arising
246 -- from generics) use the constructor wrappers. At least that's
247 -- what External Core likes
249 implicit_con_ids tc = mapCatMaybes dataConWrapId_maybe (tyConDataCons tc)
251 other_implicit_ids (ATyCon tc) = filter (not . isNaughtyRecordSelector) (tyConSelIds tc)
252 -- The "naughty" ones are not real functions at all
253 -- They are there just so we can get decent error messages
254 -- See Note [Naughty record selectors] in MkId.lhs
255 other_implicit_ids (AClass cl) = classSelIds cl
256 other_implicit_ids _other = []
258 get_defn :: Id -> CoreBind
259 get_defn id = NonRec id (unfoldingTemplate (idUnfolding id))
263 %************************************************************************
267 %************************************************************************
269 -- prepareLocalRuleBase takes the CoreBinds and rules defined in this module.
270 -- It attaches those rules that are for local Ids to their binders, and
271 -- returns the remainder attached to Ids in an IdSet.
274 prepareRules :: HscEnv
277 -> IO (RuleBase, -- Rule base for imported things, incl
278 -- (a) rules defined in this module (orphans)
279 -- (b) rules from other modules in home package
280 -- but not things from other packages
282 ModGuts) -- Modified fields are
283 -- (a) Bindings have rules attached,
284 -- (b) Rules are now just orphan rules
286 prepareRules hsc_env@(HscEnv { hsc_dflags = dflags, hsc_HPT = hpt })
287 guts@(ModGuts { mg_binds = binds, mg_deps = deps, mg_rules = local_rules })
289 = do { let -- Simplify the local rules; boringly, we need to make an in-scope set
290 -- from the local binders, to avoid warnings from Simplify.simplVar
291 local_ids = mkInScopeSet (mkVarSet (bindersOfBinds binds))
292 env = setInScopeSet gentleSimplEnv local_ids
293 (better_rules,_) = initSmpl dflags emptyRuleBase emptyFamInstEnvs us $
294 (mapM (simplRule env) local_rules)
295 home_pkg_rules = hptRules hsc_env (dep_mods deps)
297 -- Find the rules for locally-defined Ids; then we can attach them
298 -- to the binders in the top-level bindings
301 -- - It makes the rules easier to look up
302 -- - It means that transformation rules and specialisations for
303 -- locally defined Ids are handled uniformly
304 -- - It keeps alive things that are referred to only from a rule
305 -- (the occurrence analyser knows about rules attached to Ids)
306 -- - It makes sure that, when we apply a rule, the free vars
307 -- of the RHS are more likely to be in scope
308 -- - The imported rules are carried in the in-scope set
309 -- which is extended on each iteration by the new wave of
310 -- local binders; any rules which aren't on the binding will
311 -- thereby get dropped
312 (rules_for_locals, rules_for_imps) = partition isLocalRule better_rules
313 local_rule_base = extendRuleBaseList emptyRuleBase rules_for_locals
314 binds_w_rules = updateBinders local_rule_base binds
316 hpt_rule_base = mkRuleBase home_pkg_rules
317 imp_rule_base = extendRuleBaseList hpt_rule_base rules_for_imps
319 ; dumpIfSet_dyn dflags Opt_D_dump_rules "Transformation rules"
320 (vcat [text "Local rules", pprRules better_rules,
322 text "Imported rules", pprRuleBase imp_rule_base])
324 ; return (imp_rule_base, guts { mg_binds = binds_w_rules,
325 mg_rules = rules_for_imps })
328 updateBinders :: RuleBase -> [CoreBind] -> [CoreBind]
329 updateBinders local_rules binds
330 = map update_bndrs binds
332 update_bndrs (NonRec b r) = NonRec (update_bndr b) r
333 update_bndrs (Rec prs) = Rec [(update_bndr b, r) | (b,r) <- prs]
335 update_bndr bndr = case lookupNameEnv local_rules (idName bndr) of
337 Just rules -> bndr `addIdSpecialisations` rules
338 -- The binder might have some existing rules,
339 -- arising from specialisation pragmas
343 We must do some gentle simplification on the template (but not the RHS)
344 of each rule. The case that forced me to add this was the fold/build rule,
345 which without simplification looked like:
346 fold k z (build (/\a. g a)) ==> ...
347 This doesn't match unless you do eta reduction on the build argument.
350 simplRule env rule@(BuiltinRule {})
352 simplRule env rule@(Rule { ru_bndrs = bndrs, ru_args = args, ru_rhs = rhs })
353 = do (env, bndrs') <- simplBinders env bndrs
354 args' <- mapM (simplExprGently env) args
355 rhs' <- simplExprGently env rhs
356 return (rule { ru_bndrs = bndrs', ru_args = args', ru_rhs = rhs' })
358 -- It's important that simplExprGently does eta reduction.
359 -- For example, in a rule like:
360 -- augment g (build h)
361 -- we do not want to get
362 -- augment (\a. g a) (build h)
363 -- otherwise we don't match when given an argument like
366 -- The simplifier does indeed do eta reduction (it's in
367 -- Simplify.completeLam) but only if -O is on.
371 simplExprGently :: SimplEnv -> CoreExpr -> SimplM CoreExpr
372 -- Simplifies an expression
373 -- does occurrence analysis, then simplification
374 -- and repeats (twice currently) because one pass
375 -- alone leaves tons of crud.
376 -- Used (a) for user expressions typed in at the interactive prompt
377 -- (b) the LHS and RHS of a RULE
379 -- The name 'Gently' suggests that the SimplifierMode is SimplGently,
380 -- and in fact that is so.... but the 'Gently' in simplExprGently doesn't
381 -- enforce that; it just simplifies the expression twice
383 simplExprGently env expr = do
384 expr1 <- simplExpr env (occurAnalyseExpr expr)
385 simplExpr env (occurAnalyseExpr expr1)
389 %************************************************************************
391 \subsection{Glomming}
393 %************************************************************************
396 glomBinds :: DynFlags -> [CoreBind] -> IO [CoreBind]
397 -- Glom all binds together in one Rec, in case any
398 -- transformations have introduced any new dependencies
400 -- NB: the global invariant is this:
401 -- *** the top level bindings are never cloned, and are always unique ***
403 -- We sort them into dependency order, but applying transformation rules may
404 -- make something at the top refer to something at the bottom:
408 -- RULE: p (q x) = h x
410 -- Applying this rule makes f refer to h,
411 -- although it doesn't appear to in the source program.
412 -- This pass lets us control where it happens.
414 -- NOTICE that this cannot happen for rules whose head is a locally-defined
415 -- function. It only happens for rules whose head is an imported function
416 -- (p in the example above). So, for example, the rule had been
417 -- RULE: f (p x) = h x
418 -- then the rule for f would be attached to f itself (in its IdInfo)
419 -- by prepareLocalRuleBase and h would be regarded by the occurrency
420 -- analyser as free in f.
422 glomBinds dflags binds
423 = do { showPass dflags "GlomBinds" ;
424 let { recd_binds = [Rec (flattenBinds binds)] } ;
426 -- Not much point in printing the result...
427 -- just consumes output bandwidth
431 %************************************************************************
433 \subsection{The driver for the simplifier}
435 %************************************************************************
438 simplifyPgm :: SimplifierMode
439 -> [SimplifierSwitch]
444 -> IO (SimplCount, ModGuts) -- New bindings
446 simplifyPgm mode switches hsc_env us imp_rule_base guts
448 showPass dflags "Simplify";
450 (termination_msg, it_count, counts_out, binds')
451 <- do_iteration us 1 (zeroSimplCount dflags) (mg_binds guts) ;
453 dumpIfSet (dump_phase && dopt Opt_D_dump_simpl_stats dflags)
454 "Simplifier statistics"
455 (vcat [text termination_msg <+> text "after" <+> ppr it_count <+> text "iterations",
457 pprSimplCount counts_out]);
459 endPassIf dump_phase dflags
460 ("Simplify phase " ++ phase_info ++ " done")
461 Opt_D_dump_simpl_phases binds';
463 return (counts_out, guts { mg_binds = binds' })
466 dflags = hsc_dflags hsc_env
467 phase_info = case mode of
468 SimplGently -> "gentle"
469 SimplPhase n ss -> shows n
471 . showString (concat $ intersperse "," ss)
474 dump_phase = shouldDumpSimplPhase dflags mode
476 sw_chkr = isAmongSimpl switches
477 max_iterations = intSwitchSet sw_chkr MaxSimplifierIterations `orElse` 2
479 do_iteration us iteration_no counts binds
480 -- iteration_no is the number of the iteration we are
481 -- about to begin, with '1' for the first
482 | iteration_no > max_iterations -- Stop if we've run out of iterations
484 when (debugIsOn && (max_iterations > 2)) $
485 hPutStr stderr ("NOTE: Simplifier still going after " ++
486 show max_iterations ++
487 " iterations; bailing out. Size = " ++ show (coreBindsSize binds) ++ "\n" )
488 -- Subtract 1 from iteration_no to get the
489 -- number of iterations we actually completed
490 ; return ("Simplifier bailed out", iteration_no - 1, counts, binds)
493 -- Try and force thunks off the binds; significantly reduces
494 -- space usage, especially with -O. JRS, 000620.
495 | let sz = coreBindsSize binds in sz == sz
497 -- Occurrence analysis
498 let { tagged_binds = {-# SCC "OccAnal" #-} occurAnalysePgm binds } ;
499 dumpIfSet_dyn dflags Opt_D_dump_occur_anal "Occurrence analysis"
500 (pprCoreBindings tagged_binds);
502 -- Get any new rules, and extend the rule base
503 -- We need to do this regularly, because simplification can
504 -- poke on IdInfo thunks, which in turn brings in new rules
505 -- behind the scenes. Otherwise there's a danger we'll simply
506 -- miss the rules for Ids hidden inside imported inlinings
507 eps <- hscEPS hsc_env ;
508 let { rule_base' = unionRuleBase imp_rule_base (eps_rule_base eps)
509 ; simpl_env = mkSimplEnv mode sw_chkr
510 ; simpl_binds = {-# SCC "SimplTopBinds" #-}
511 simplTopBinds simpl_env tagged_binds
512 ; fam_envs = (eps_fam_inst_env eps, mg_fam_inst_env guts) } ;
514 -- Simplify the program
515 -- We do this with a *case* not a *let* because lazy pattern
516 -- matching bit us with bad space leak!
517 -- With a let, we ended up with
522 -- case t of {(_,counts') -> if counts'=0 then ... }
523 -- So the conditional didn't force counts', because the
524 -- selection got duplicated. Sigh!
525 case initSmpl dflags rule_base' fam_envs us1 simpl_binds of {
526 (binds', counts') -> do {
528 let { all_counts = counts `plusSimplCount` counts'
529 ; herald = "Simplifier phase " ++ phase_info ++
530 ", iteration " ++ show iteration_no ++
531 " out of " ++ show max_iterations
534 -- Stop if nothing happened; don't dump output
535 if isZeroSimplCount counts' then
536 return ("Simplifier reached fixed point", iteration_no,
539 -- Short out indirections
540 -- We do this *after* at least one run of the simplifier
541 -- because indirection-shorting uses the export flag on *occurrences*
542 -- and that isn't guaranteed to be ok until after the first run propagates
543 -- stuff from the binding site to its occurrences
545 -- ToDo: alas, this means that indirection-shorting does not happen at all
546 -- if the simplifier does nothing (not common, I know, but unsavoury)
547 let { binds'' = {-# SCC "ZapInd" #-} shortOutIndirections binds' } ;
549 -- Dump the result of this iteration
550 dumpIfSet_dyn dflags Opt_D_dump_simpl_iterations herald
551 (pprSimplCount counts') ;
552 endIteration dflags herald Opt_D_dump_simpl_iterations binds'' ;
555 do_iteration us2 (iteration_no + 1) all_counts binds''
558 (us1, us2) = splitUniqSupply us
562 %************************************************************************
564 Shorting out indirections
566 %************************************************************************
570 x_local = <expression>
574 where x_exported is exported, and x_local is not, then we replace it with this:
576 x_exported = <expression>
580 Without this we never get rid of the x_exported = x_local thing. This
581 save a gratuitous jump (from \tr{x_exported} to \tr{x_local}), and
582 makes strictness information propagate better. This used to happen in
583 the final phase, but it's tidier to do it here.
585 STRICTNESS: if we have done strictness analysis, we want the strictness info on
586 x_local to transfer to x_exported. Hence the copyIdInfo call.
588 RULES: we want to *add* any RULES for x_local to x_exported.
590 Note [Rules and indirection-zapping]
591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
592 Problem: what if x_exported has a RULE that mentions something in ...bindings...?
593 Then the things mentioned can be out of scope! Solution
594 a) Make sure that in this pass the usage-info from x_exported is
595 available for ...bindings...
596 b) If there are any such RULES, rec-ify the entire top-level.
597 It'll get sorted out next time round
601 The example that went bad on me at one stage was this one:
603 iterate :: (a -> a) -> a -> [a]
605 iterate = iterateList
607 iterateFB c f x = x `c` iterateFB c f (f x)
608 iterateList f x = x : iterateList f (f x)
612 "iterate" forall f x. iterate f x = build (\c _n -> iterateFB c f x)
613 "iterateFB" iterateFB (:) = iterateList
616 This got shorted out to:
618 iterateList :: (a -> a) -> a -> [a]
619 iterateList = iterate
621 iterateFB c f x = x `c` iterateFB c f (f x)
622 iterate f x = x : iterate f (f x)
625 "iterate" forall f x. iterate f x = build (\c _n -> iterateFB c f x)
626 "iterateFB" iterateFB (:) = iterate
629 And now we get an infinite loop in the rule system
630 iterate f x -> build (\cn -> iterateFB c f x)
634 Tiresome old solution:
635 don't do shorting out if f has rewrite rules (see shortableIdInfo)
637 New solution (I think):
638 use rule switching-off pragmas to get rid
639 of iterateList in the first place
644 If more than one exported thing is equal to a local thing (i.e., the
645 local thing really is shared), then we do one only:
648 x_exported1 = x_local
649 x_exported2 = x_local
653 x_exported2 = x_exported1
656 We rely on prior eta reduction to simplify things like
658 x_exported = /\ tyvars -> x_local tyvars
662 Hence,there's a possibility of leaving unchanged something like this:
665 x_exported1 = x_local Int
667 By the time we've thrown away the types in STG land this
668 could be eliminated. But I don't think it's very common
669 and it's dangerous to do this fiddling in STG land
670 because we might elminate a binding that's mentioned in the
671 unfolding for something.
674 type IndEnv = IdEnv Id -- Maps local_id -> exported_id
676 shortOutIndirections :: [CoreBind] -> [CoreBind]
677 shortOutIndirections binds
678 | isEmptyVarEnv ind_env = binds
679 | no_need_to_flatten = binds' -- See Note [Rules and indirect-zapping]
680 | otherwise = [Rec (flattenBinds binds')] -- for this no_need_to_flatten stuff
682 ind_env = makeIndEnv binds
683 exp_ids = varSetElems ind_env -- These exported Ids are the subjects
684 exp_id_set = mkVarSet exp_ids -- of the indirection-elimination
685 no_need_to_flatten = all (null . specInfoRules . idSpecialisation) exp_ids
686 binds' = concatMap zap binds
688 zap (NonRec bndr rhs) = [NonRec b r | (b,r) <- zapPair (bndr,rhs)]
689 zap (Rec pairs) = [Rec (concatMap zapPair pairs)]
692 | bndr `elemVarSet` exp_id_set = []
693 | Just exp_id <- lookupVarEnv ind_env bndr = [(transferIdInfo exp_id bndr, rhs),
695 | otherwise = [(bndr,rhs)]
697 makeIndEnv :: [CoreBind] -> IndEnv
699 = foldr add_bind emptyVarEnv binds
701 add_bind :: CoreBind -> IndEnv -> IndEnv
702 add_bind (NonRec exported_id rhs) env = add_pair (exported_id, rhs) env
703 add_bind (Rec pairs) env = foldr add_pair env pairs
705 add_pair :: (Id,CoreExpr) -> IndEnv -> IndEnv
706 add_pair (exported_id, Var local_id) env
707 | shortMeOut env exported_id local_id = extendVarEnv env local_id exported_id
708 add_pair (exported_id, rhs) env
711 shortMeOut ind_env exported_id local_id
712 -- The if-then-else stuff is just so I can get a pprTrace to see
713 -- how often I don't get shorting out becuase of IdInfo stuff
714 = if isExportedId exported_id && -- Only if this is exported
716 isLocalId local_id && -- Only if this one is defined in this
717 -- module, so that we *can* change its
718 -- binding to be the exported thing!
720 not (isExportedId local_id) && -- Only if this one is not itself exported,
721 -- since the transformation will nuke it
723 not (local_id `elemVarEnv` ind_env) -- Only if not already substituted for
728 if isEmptySpecInfo (specInfo (idInfo exported_id)) -- Only if no rules
729 then True -- See note on "Messing up rules"
732 pprTrace "shortMeOut:" (ppr exported_id)
741 transferIdInfo :: Id -> Id -> Id
743 -- lcl_id = e; exp_id = lcl_id
744 -- and lcl_id has useful IdInfo, we don't want to discard it by going
745 -- gbl_id = e; lcl_id = gbl_id
746 -- Instead, transfer IdInfo from lcl_id to exp_id
747 -- Overwriting, rather than merging, seems to work ok.
748 transferIdInfo exported_id local_id
749 = modifyIdInfo transfer exported_id
751 local_info = idInfo local_id
752 transfer exp_info = exp_info `setNewStrictnessInfo` newStrictnessInfo local_info
753 `setWorkerInfo` workerInfo local_info
754 `setInlinePragInfo` inlinePragInfo local_info
755 `setSpecInfo` addSpecInfo (specInfo exp_info) new_info
756 new_info = setSpecInfoHead (idName exported_id)
757 (specInfo local_info)
758 -- Remember to set the function-name field of the
759 -- rules as we transfer them from one function to another