2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[SimplCore]{Driver for simplifying @Core@ programs}
7 module SimplCore ( core2core ) where
9 #include "HsVersions.h"
11 import CmdLineOpts ( CoreToDo(..), SimplifierSwitch(..),
12 SwitchResult(..), switchIsOn, intSwitchSet,
13 opt_D_dump_occur_anal, opt_D_dump_rules,
14 opt_D_dump_simpl_iterations,
15 opt_D_dump_simpl_stats,
16 opt_D_dump_simpl, opt_D_dump_rules,
17 opt_D_verbose_core2core,
18 opt_D_dump_occur_anal,
21 import CoreLint ( beginPass, endPass )
22 import CoreTidy ( tidyCorePgm )
24 import Rules ( RuleBase, ProtoCoreRule(..), pprProtoCoreRule, prepareRuleBase, orphanRule )
26 import PprCore ( pprCoreBindings )
27 import OccurAnal ( occurAnalyseBinds )
28 import CoreUtils ( exprIsTrivial, coreExprType )
29 import Simplify ( simplTopBinds, simplExpr )
30 import SimplUtils ( etaCoreExpr, findDefault, simplBinders )
32 import Const ( Con(..), Literal(..), literalType, mkMachInt )
33 import ErrUtils ( dumpIfSet )
34 import FloatIn ( floatInwards )
35 import FloatOut ( floatOutwards )
36 import Id ( Id, mkSysLocal, mkVanillaId, isBottomingId,
37 idType, setIdType, idName, idInfo, setIdNoDiscard
39 import IdInfo ( InlinePragInfo(..), specInfo, setSpecInfo,
40 inlinePragInfo, setInlinePragInfo,
41 setUnfoldingInfo, setDemandInfo
43 import Demand ( wwLazy )
46 import Module ( Module )
47 import Name ( mkLocalName, tidyOccName, tidyTopName,
48 NamedThing(..), OccName
50 import TyCon ( TyCon, isDataTyCon )
51 import PrimOp ( PrimOp(..) )
52 import PrelInfo ( unpackCStringId, unpackCString2Id, addr2IntegerId )
53 import Type ( Type, splitAlgTyConApp_maybe,
55 tidyType, tidyTypes, tidyTopType, tidyTyVar, tidyTyVars,
58 import Class ( Class, classSelIds )
59 import TysWiredIn ( smallIntegerDataCon, isIntegerTy )
60 import LiberateCase ( liberateCase )
61 import SAT ( doStaticArgs )
62 import Specialise ( specProgram)
63 import UsageSPInf ( doUsageSPInf )
64 import StrictAnal ( saBinds )
65 import WorkWrap ( wwTopBinds )
66 import CprAnalyse ( cprAnalyse )
68 import Unique ( Unique, Uniquable(..),
71 import UniqSupply ( UniqSupply, mkSplitUniqSupply, splitUniqSupply, uniqFromSupply )
72 import Constants ( tARGET_MIN_INT, tARGET_MAX_INT )
73 import Util ( mapAccumL )
74 import SrcLoc ( noSrcLoc )
77 import IO ( hPutStr, stderr )
80 import Ratio ( numerator, denominator )
83 %************************************************************************
85 \subsection{The driver for the simplifier}
87 %************************************************************************
90 core2core :: [CoreToDo] -- Spec of what core-to-core passes to do
91 -> [CoreBind] -- Binds in
92 -> [ProtoCoreRule] -- Rules
93 -> IO ([CoreBind], [ProtoCoreRule])
95 core2core core_todos binds rules
97 us <- mkSplitUniqSupply 's'
98 let (cp_us, us1) = splitUniqSupply us
99 (ru_us, ps_us) = splitUniqSupply us1
101 better_rules <- simplRules ru_us rules binds
103 let (binds1, rule_base) = prepareRuleBase binds better_rules
105 -- Do the main business
106 (stats, processed_binds) <- doCorePasses zeroSimplCount cp_us binds1
109 dumpIfSet opt_D_dump_simpl_stats
110 "Grand total simplifier statistics"
111 (pprSimplCount stats)
113 -- Do the post-simplification business
114 post_simpl_binds <- doPostSimplification ps_us processed_binds
117 return (post_simpl_binds, filter orphanRule better_rules)
120 doCorePasses stats us binds irs []
121 = return (stats, binds)
123 doCorePasses stats us binds irs (to_do : to_dos)
125 let (us1, us2) = splitUniqSupply us
126 (stats1, binds1) <- doCorePass us1 binds irs to_do
127 doCorePasses (stats `plusSimplCount` stats1) us2 binds1 irs to_dos
129 doCorePass us binds rb (CoreDoSimplify sw_chkr) = _scc_ "Simplify" simplifyPgm rb sw_chkr us binds
130 doCorePass us binds rb CoreLiberateCase = _scc_ "LiberateCase" noStats (liberateCase binds)
131 doCorePass us binds rb CoreDoFloatInwards = _scc_ "FloatInwards" noStats (floatInwards binds)
132 doCorePass us binds rb CoreDoFullLaziness = _scc_ "FloatOutwards" noStats (floatOutwards us binds)
133 doCorePass us binds rb CoreDoStaticArgs = _scc_ "StaticArgs" noStats (doStaticArgs us binds)
134 doCorePass us binds rb CoreDoStrictness = _scc_ "Stranal" noStats (saBinds binds)
135 doCorePass us binds rb CoreDoWorkerWrapper = _scc_ "WorkWrap" noStats (wwTopBinds us binds)
136 doCorePass us binds rb CoreDoSpecialising = _scc_ "Specialise" noStats (specProgram us binds)
137 doCorePass us binds rb CoreDoCPResult = _scc_ "CPResult" noStats (cprAnalyse binds)
138 doCorePass us binds rb CoreDoPrintCore = _scc_ "PrintCore" noStats (printCore binds)
139 doCorePass us binds rb CoreDoUSPInf
140 = _scc_ "CoreUsageSPInf"
141 if opt_UsageSPOn then
142 noStats (doUsageSPInf us binds)
144 trace "WARNING: ignoring requested -fusagesp pass; requires -fusagesp-on" $
145 noStats (return binds)
147 printCore binds = do dumpIfSet True "Print Core"
148 (pprCoreBindings binds)
151 noStats thing = do { result <- thing; return (zeroSimplCount, result) }
155 %************************************************************************
157 \subsection{Dealing with rules}
159 %************************************************************************
161 We must do some gentle simplifiation on the template (but not the RHS)
162 of each rule. The case that forced me to add this was the fold/build rule,
163 which without simplification looked like:
164 fold k z (build (/\a. g a)) ==> ...
165 This doesn't match unless you do eta reduction on the build argument.
168 simplRules :: UniqSupply -> [ProtoCoreRule] -> [CoreBind] -> IO [ProtoCoreRule]
169 simplRules us rules binds
170 = do let (better_rules,_) = initSmpl sw_chkr us bind_vars black_list_all (mapSmpl simplRule rules)
172 dumpIfSet opt_D_dump_rules
173 "Transformation rules"
174 (vcat (map pprProtoCoreRule better_rules))
178 black_list_all v = True -- This stops all inlining
179 sw_chkr any = SwBool False -- A bit bogus
181 -- Boringly, we need to gather the in-scope set.
182 -- Typically this thunk won't even be force, but the test in
183 -- simpVar fails if it isn't right, and it might conceivably matter
184 bind_vars = foldr (unionVarSet . mkVarSet . bindersOf) emptyVarSet binds
187 simplRule rule@(ProtoCoreRule is_local id (Rule name bndrs args rhs))
189 = returnSmpl rule -- No need to fiddle with imported rules
191 = simplBinders bndrs $ \ bndrs' ->
192 mapSmpl simplExpr args `thenSmpl` \ args' ->
193 simplExpr rhs `thenSmpl` \ rhs' ->
194 returnSmpl (ProtoCoreRule is_local id (Rule name bndrs' args' rhs'))
197 %************************************************************************
199 \subsection{The driver for the simplifier}
201 %************************************************************************
204 simplifyPgm :: RuleBase
205 -> (SimplifierSwitch -> SwitchResult)
207 -> [CoreBind] -- Input
208 -> IO (SimplCount, [CoreBind]) -- New bindings
210 simplifyPgm (imported_rule_ids, rule_lhs_fvs)
213 beginPass "Simplify";
215 -- Glom all binds together in one Rec, in case any
216 -- transformations have introduced any new dependencies
217 let { recd_binds = [Rec (flattenBinds binds)] };
219 (termination_msg, it_count, counts_out, binds') <- iteration us 1 zeroSimplCount recd_binds;
221 dumpIfSet (opt_D_verbose_core2core && opt_D_dump_simpl_stats)
222 "Simplifier statistics"
223 (vcat [text termination_msg <+> text "after" <+> ppr it_count <+> text "iterations",
225 pprSimplCount counts_out]);
228 (opt_D_verbose_core2core && not opt_D_dump_simpl_iterations)
231 return (counts_out, binds')
234 max_iterations = getSimplIntSwitch sw_chkr MaxSimplifierIterations
235 black_list_fn = blackListed rule_lhs_fvs (intSwitchSet sw_chkr SimplInlinePhase)
237 core_iter_dump binds | opt_D_verbose_core2core = pprCoreBindings binds
240 iteration us iteration_no counts binds
242 -- Occurrence analysis
243 let { tagged_binds = _scc_ "OccAnal" occurAnalyseBinds binds } ;
245 dumpIfSet opt_D_dump_occur_anal "Occurrence analysis"
246 (pprCoreBindings tagged_binds);
249 let { (binds', counts') = initSmpl sw_chkr us1 imported_rule_ids
251 (simplTopBinds tagged_binds);
252 all_counts = counts `plusSimplCount` counts'
255 -- Stop if nothing happened; don't dump output
256 if isZeroSimplCount counts' then
257 return ("Simplifier reached fixed point", iteration_no, all_counts, binds')
260 -- Dump the result of this iteration
261 dumpIfSet opt_D_dump_simpl_iterations
262 ("Simplifier iteration " ++ show iteration_no
263 ++ " out of " ++ show max_iterations)
264 (pprSimplCount counts') ;
266 if opt_D_dump_simpl_iterations then
267 endPass ("Simplifier iteration " ++ show iteration_no ++ " result")
268 opt_D_verbose_core2core
273 -- Stop if we've run out of iterations
274 if iteration_no == max_iterations then
276 if max_iterations > 2 then
277 hPutStr stderr ("NOTE: Simplifier still going after " ++
278 show max_iterations ++
279 " iterations; bailing out.\n")
282 return ("Simplifier baled out", iteration_no, all_counts, binds')
286 else iteration us2 (iteration_no + 1) all_counts binds'
289 (us1, us2) = splitUniqSupply us
293 %************************************************************************
295 \subsection{PostSimplification}
297 %************************************************************************
299 Several tasks are performed by the post-simplification pass
301 1. Make the representation of NoRep literals explicit, and
302 float their bindings to the top level. We only do the floating
303 part for NoRep lits inside a lambda (else no gain). We need to
304 take care with let x = "foo" in e
305 that we don't end up with a silly binding
307 with a floated "foo". What a bore.
309 2. *Mangle* cases involving par# in the discriminant. The unfolding
310 for par in PrelConc.lhs include case expressions with integer
311 results solely to fool the strictness analyzer, the simplifier,
312 and anyone else who might want to fool with the evaluation order.
313 At this point in the compiler our evaluation order is safe.
314 Therefore, we convert expressions of the form:
323 fork# isn't handled like this - it's an explicit IO operation now.
324 The reason is that fork# returns a ThreadId#, which gets in the
325 way of the above scheme. And anyway, IO is the only guaranteed
326 way to enforce ordering --SDM.
328 3. Mangle cases involving seq# in the discriminant. Up to this
329 point, seq# will appear like this:
335 where the 0# branch is purely to bamboozle the strictness analyser
336 (see case 4 above). This code comes from an unfolding for 'seq'
337 in Prelude.hs. We translate this into
342 Now that the evaluation order is safe.
344 4. Do eta reduction for lambda abstractions appearing in:
345 - the RHS of case alternatives
348 These will otherwise turn into local bindings during Core->STG;
349 better to nuke them if possible. (In general the simplifier does
350 eta expansion not eta reduction, up to this point. It does eta
351 on the RHSs of bindings but not the RHSs of case alternatives and
355 ------------------- NOT DONE ANY MORE ------------------------
356 [March 98] Indirections are now elimianted by the occurrence analyser
357 1. Eliminate indirections. The point here is to transform
363 [Dec 98] [Not now done because there is no penalty in the code
364 generator for using the former form]
366 case x of {...; x' -> ...x'...}
368 case x of {...; _ -> ...x... }
369 See notes in SimplCase.lhs, near simplDefault for the reasoning here.
370 --------------------------------------------------------------
375 NOT ENABLED AT THE MOMENT (because the floated Ids are global-ish
376 things, and we need local Ids for non-floated stuff):
378 Don't float stuff out of a binder that's marked as a bottoming Id.
379 Reason: it doesn't do any good, and creates more CAFs that increase
388 f' = unpackCString# "string"
391 hence f' and f become CAFs. Instead, the special case for
392 tidyTopBinding below makes sure this comes out as
394 f = let f' = unpackCString# "string" in error f'
396 and we can safely ignore f as a CAF, since it can only ever be entered once.
401 doPostSimplification :: UniqSupply -> [CoreBind] -> IO [CoreBind]
402 doPostSimplification us binds_in
404 beginPass "Post-simplification pass"
405 let binds_out = initPM us (postSimplTopBinds binds_in)
406 endPass "Post-simplification pass" opt_D_verbose_core2core binds_out
408 postSimplTopBinds :: [CoreBind] -> PostM [CoreBind]
409 postSimplTopBinds binds
410 = mapPM postSimplTopBind binds `thenPM` \ binds' ->
411 returnPM (bagToList (unionManyBags binds'))
413 postSimplTopBind :: CoreBind -> PostM (Bag CoreBind)
414 postSimplTopBind (NonRec bndr rhs)
415 | isBottomingId bndr -- Don't lift out floats for bottoming Ids
417 = getFloatsPM (postSimplExpr rhs) `thenPM` \ (rhs', floats) ->
418 returnPM (unitBag (NonRec bndr (foldrBag Let rhs' floats)))
420 postSimplTopBind bind
421 = getFloatsPM (postSimplBind bind) `thenPM` \ (bind', floats) ->
422 returnPM (floats `snocBag` bind')
424 postSimplBind (NonRec bndr rhs)
425 = postSimplExpr rhs `thenPM` \ rhs' ->
426 returnPM (NonRec bndr rhs')
428 postSimplBind (Rec pairs)
429 = mapPM postSimplExpr rhss `thenPM` \ rhss' ->
430 returnPM (Rec (bndrs `zip` rhss'))
432 (bndrs, rhss) = unzip pairs
439 postSimplExpr (Var v) = returnPM (Var v)
440 postSimplExpr (Type ty) = returnPM (Type ty)
442 postSimplExpr (App fun arg)
443 = postSimplExpr fun `thenPM` \ fun' ->
444 postSimplExpr arg `thenPM` \ arg' ->
445 returnPM (App fun' arg')
447 postSimplExpr (Con (Literal lit) args)
448 = ASSERT( null args )
449 litToRep lit `thenPM` \ (lit_ty, lit_expr) ->
450 getInsideLambda `thenPM` \ in_lam ->
451 if in_lam && not (exprIsTrivial lit_expr) then
452 -- It must have been a no-rep literal with a
453 -- non-trivial representation; and we're inside a lambda;
454 -- so float it to the top
455 addTopFloat lit_ty lit_expr `thenPM` \ v ->
460 postSimplExpr (Con con args)
461 = mapPM postSimplExpr args `thenPM` \ args' ->
462 returnPM (Con con args')
464 postSimplExpr (Lam bndr body)
465 = insideLambda bndr $
466 postSimplExpr body `thenPM` \ body' ->
467 returnPM (Lam bndr body')
469 postSimplExpr (Let bind body)
470 = postSimplBind bind `thenPM` \ bind' ->
471 postSimplExprEta body `thenPM` \ body' ->
472 returnPM (Let bind' body')
474 postSimplExpr (Note note body)
475 = postSimplExprEta body `thenPM` \ body' ->
476 returnPM (Note note body')
478 -- seq#: see notes above.
479 -- NB: seq# :: forall a. a -> Int#
480 postSimplExpr (Case scrut@(Con (PrimOp SeqOp) [Type ty, e]) bndr alts)
481 = postSimplExpr e `thenPM` \ e' ->
483 -- The old binder can't have been used, so we
484 -- can gaily re-use it (yuk!)
485 new_bndr = setIdType bndr ty
487 postSimplExprEta default_rhs `thenPM` \ rhs' ->
488 returnPM (Case e' new_bndr [(DEFAULT,[],rhs')])
490 (other_alts, maybe_default) = findDefault alts
491 Just default_rhs = maybe_default
493 -- par#: see notes above.
494 postSimplExpr (Case scrut@(Con (PrimOp op) args) bndr alts)
495 | funnyParallelOp op && maybeToBool maybe_default
496 = postSimplExpr scrut `thenPM` \ scrut' ->
497 postSimplExprEta default_rhs `thenPM` \ rhs' ->
498 returnPM (Case scrut' bndr [(DEFAULT,[],rhs')])
500 (other_alts, maybe_default) = findDefault alts
501 Just default_rhs = maybe_default
503 postSimplExpr (Case scrut case_bndr alts)
504 = postSimplExpr scrut `thenPM` \ scrut' ->
505 mapPM ps_alt alts `thenPM` \ alts' ->
506 returnPM (Case scrut' case_bndr alts')
508 ps_alt (con,bndrs,rhs) = postSimplExprEta rhs `thenPM` \ rhs' ->
509 returnPM (con, bndrs, rhs')
511 postSimplExprEta e = postSimplExpr e `thenPM` \ e' ->
512 returnPM (etaCoreExpr e')
516 funnyParallelOp ParOp = True
517 funnyParallelOp _ = False
521 %************************************************************************
523 \subsection[coreToStg-lits]{Converting literals}
525 %************************************************************************
527 Literals: the NoRep kind need to be de-no-rep'd.
528 We always replace them with a simple variable, and float a suitable
529 binding out to the top level.
532 litToRep :: Literal -> PostM (Type, CoreExpr)
534 litToRep (NoRepStr s ty)
537 rhs = if (any is_NUL (_UNPK_ s))
539 then -- Must cater for NULs in literal string
540 mkApps (Var unpackCString2Id)
542 mkLit (mkMachInt (toInteger (_LENGTH_ s)))]
544 else -- No NULs in the string
545 App (Var unpackCStringId) (mkLit (MachStr s))
550 If an Integer is small enough (Haskell implementations must support
551 Ints in the range $[-2^29+1, 2^29-1]$), wrap it up in @int2Integer@;
552 otherwise, wrap with @addr2Integer@.
555 litToRep (NoRepInteger i integer_ty)
556 = returnPM (integer_ty, rhs)
558 rhs | i > tARGET_MIN_INT && -- Small enough, so start from an Int
560 = Con (DataCon smallIntegerDataCon) [Con (Literal (mkMachInt i)) []]
562 | otherwise -- Big, so start from a string
563 = App (Var addr2IntegerId) (Con (Literal (MachStr (_PK_ (show i)))) [])
566 litToRep (NoRepRational r rational_ty)
567 = postSimplExpr (mkLit (NoRepInteger (numerator r) integer_ty)) `thenPM` \ num_arg ->
568 postSimplExpr (mkLit (NoRepInteger (denominator r) integer_ty)) `thenPM` \ denom_arg ->
569 returnPM (rational_ty, mkConApp ratio_data_con [Type integer_ty, num_arg, denom_arg])
571 (ratio_data_con, integer_ty)
572 = case (splitAlgTyConApp_maybe rational_ty) of
573 Just (tycon, [i_ty], [con])
574 -> ASSERT(isIntegerTy i_ty && getUnique tycon == ratioTyConKey)
577 _ -> (panic "ratio_data_con", panic "integer_ty")
579 litToRep other_lit = returnPM (literalType other_lit, mkLit other_lit)
583 %************************************************************************
585 \subsection{The monad}
587 %************************************************************************
590 type PostM a = Bool -- True <=> inside a *value* lambda
591 -> (UniqSupply, Bag CoreBind) -- Unique supply and Floats in
592 -> (a, (UniqSupply, Bag CoreBind))
594 initPM :: UniqSupply -> PostM a -> a
596 = case m False {- not inside lambda -} (us, emptyBag) of
597 (result, _) -> result
599 returnPM v in_lam usf = (v, usf)
600 thenPM m k in_lam usf = case m in_lam usf of
601 (r, usf') -> k r in_lam usf'
603 mapPM f [] = returnPM []
604 mapPM f (x:xs) = f x `thenPM` \ r ->
605 mapPM f xs `thenPM` \ rs ->
608 insideLambda :: CoreBndr -> PostM a -> PostM a
609 insideLambda bndr m in_lam usf | isId bndr = m True usf
610 | otherwise = m in_lam usf
612 getInsideLambda :: PostM Bool
613 getInsideLambda in_lam usf = (in_lam, usf)
615 getFloatsPM :: PostM a -> PostM (a, Bag CoreBind)
616 getFloatsPM m in_lam (us, floats)
618 (a, (us', floats')) = m in_lam (us, emptyBag)
620 ((a, floats'), (us', floats))
622 addTopFloat :: Type -> CoreExpr -> PostM Id
623 addTopFloat lit_ty lit_rhs in_lam (us, floats)
625 (us1, us2) = splitUniqSupply us
626 uniq = uniqFromSupply us1
627 lit_id = mkSysLocal SLIT("lf") uniq lit_ty
629 (lit_id, (us2, floats `snocBag` NonRec lit_id lit_rhs))