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,
13 opt_D_dump_occur_anal,
14 opt_D_dump_simpl_iterations,
15 opt_D_simplifier_stats,
17 opt_D_verbose_core2core,
20 import CoreLint ( beginPass, endPass )
22 import PprCore ( pprCoreBindings )
23 import OccurAnal ( occurAnalyseBinds )
24 import CoreUtils ( exprIsTrivial, coreExprType )
25 import Simplify ( simplBind )
26 import SimplUtils ( etaCoreExpr, findDefault )
29 import Const ( Con(..), Literal(..), literalType, mkMachInt )
30 import ErrUtils ( dumpIfSet )
31 import FloatIn ( floatInwards )
32 import FloatOut ( floatOutwards )
33 import Id ( Id, mkSysLocal, mkUserId, isBottomingId,
34 idType, setIdType, idName, idInfo, idDetails
36 import IdInfo ( InlinePragInfo(..), specInfo, setSpecInfo,
37 inlinePragInfo, setInlinePragInfo,
42 import Module ( Module )
43 import Name ( mkLocalName, tidyOccName, tidyTopName, initTidyOccEnv, isExported,
44 NamedThing(..), OccName
46 import TyCon ( TyCon, isDataTyCon )
47 import PrimOp ( PrimOp(..) )
48 import PrelInfo ( unpackCStringId, unpackCString2Id, addr2IntegerId )
49 import Type ( Type, splitAlgTyConApp_maybe,
51 tidyType, tidyTypes, tidyTopType, tidyTyVar, tidyTyVars,
54 import Class ( Class, classSelIds )
55 import TysWiredIn ( smallIntegerDataCon, isIntegerTy )
56 import LiberateCase ( liberateCase )
57 import SAT ( doStaticArgs )
58 import Specialise ( specProgram)
59 import SpecEnv ( specEnvToList, specEnvFromList )
60 import StrictAnal ( saBinds )
61 import WorkWrap ( wwTopBinds )
62 import CprAnalyse ( cprAnalyse )
64 import Var ( TyVar, mkId )
65 import Unique ( Unique, Uniquable(..),
66 ratioTyConKey, mkUnique, incrUnique, initTidyUniques
68 import UniqSupply ( UniqSupply, splitUniqSupply, uniqFromSupply )
69 import Constants ( tARGET_MIN_INT, tARGET_MAX_INT )
70 import Util ( mapAccumL )
71 import SrcLoc ( noSrcLoc )
74 import IO ( hPutStr, stderr )
77 import Ratio ( numerator, denominator )
81 core2core :: [CoreToDo] -- Spec of what core-to-core passes to do
82 -> Module -- Module name (profiling only)
83 -> [Class] -- Local classes
84 -> UniqSupply -- A name supply
85 -> [CoreBind] -- Input
86 -> IO [CoreBind] -- Result
88 core2core core_todos module_name classes us binds
90 let (us1, us2) = splitUniqSupply us
92 -- Do the main business
93 processed_binds <- doCorePasses us1 binds core_todos
95 -- Do the post-simplification business
96 post_simpl_binds <- doPostSimplification us2 processed_binds
98 -- Do the final tidy-up
99 final_binds <- tidyCorePgm module_name classes post_simpl_binds
104 doCorePasses us binds []
107 doCorePasses us binds (to_do : to_dos)
109 let (us1, us2) = splitUniqSupply us
110 binds1 <- doCorePass us1 binds to_do
111 doCorePasses us2 binds1 to_dos
113 doCorePass us binds (CoreDoSimplify sw_chkr) = _scc_ "Simplify" simplifyPgm sw_chkr us binds
114 doCorePass us binds CoreLiberateCase = _scc_ "LiberateCase" liberateCase binds
115 doCorePass us binds CoreDoFloatInwards = _scc_ "FloatInwards" floatInwards binds
116 doCorePass us binds CoreDoFullLaziness = _scc_ "CoreFloating" floatOutwards us binds
117 doCorePass us binds CoreDoStaticArgs = _scc_ "CoreStaticArgs" doStaticArgs us binds
118 doCorePass us binds CoreDoStrictness = _scc_ "CoreStranal" saBinds binds
119 doCorePass us binds CoreDoWorkerWrapper = _scc_ "CoreWorkWrap" wwTopBinds us binds
120 doCorePass us binds CoreDoSpecialising = _scc_ "Specialise" specProgram us binds
121 doCorePass us binds CoreDoCPResult = _scc_ "CPResult" cprAnalyse binds
122 doCorePass us binds CoreDoPrintCore = _scc_ "PrintCore" do
123 putStr (showSDoc $ pprCoreBindings binds)
128 %************************************************************************
130 \subsection{The driver for the simplifier}
132 %************************************************************************
135 simplifyPgm :: (SimplifierSwitch -> SwitchResult)
137 -> [CoreBind] -- Input
138 -> IO [CoreBind] -- New bindings
140 simplifyPgm sw_chkr us binds
142 beginPass "Simplify";
144 (termination_msg, it_count, counts, binds') <- iteration us 1 zeroSimplCount binds;
146 dumpIfSet opt_D_simplifier_stats "Simplifier statistics"
147 (vcat [text termination_msg <+> text "after" <+> ppr it_count <+> text "iterations",
149 pprSimplCount counts]);
152 (opt_D_verbose_core2core && not opt_D_dump_simpl_iterations)
156 max_iterations = getSimplIntSwitch sw_chkr MaxSimplifierIterations
157 simpl_switch_is_on = switchIsOn sw_chkr
159 core_iter_dump binds | opt_D_verbose_core2core = pprCoreBindings binds
162 iteration us iteration_no counts binds
164 -- Occurrence analysis
165 let { tagged_binds = _scc_ "OccAnal" occurAnalyseBinds simpl_switch_is_on binds };
166 dumpIfSet opt_D_dump_occur_anal "Occurrence analysis"
167 (pprCoreBindings tagged_binds);
170 let { (binds', counts') = initSmpl sw_chkr us1 (simplTopBinds tagged_binds);
171 all_counts = counts `plusSimplCount` counts'
174 -- Stop if nothing happened; don't dump output
175 if isZeroSimplCount counts' then
176 return ("Simplifier reached fixed point", iteration_no, all_counts, binds')
179 -- Dump the result of this iteration
180 dumpIfSet opt_D_dump_simpl_iterations
181 ("Simplifier iteration " ++ show iteration_no
182 ++ " out of " ++ show max_iterations)
183 (vcat[pprSimplCount counts',
185 core_iter_dump binds']) ;
187 -- Stop if we've run out of iterations
188 if iteration_no == max_iterations then
190 if max_iterations > 1 then
191 hPutStr stderr ("NOTE: Simplifier still going after " ++
192 show max_iterations ++
193 " iterations; bailing out.\n")
196 return ("Simplifier baled out", iteration_no, all_counts, binds')
200 else iteration us2 (iteration_no + 1) all_counts binds'
203 (us1, us2) = splitUniqSupply us
206 simplTopBinds binds = go binds `thenSmpl` \ (binds', _) ->
209 go [] = returnSmpl ([], ())
210 go (bind1 : binds) = simplBind bind1 (go binds)
214 %************************************************************************
216 \subsection{Tidying core}
218 %************************************************************************
220 Several tasks are done by @tidyCorePgm@
222 1. Make certain top-level bindings into Globals. The point is that
223 Global things get externally-visible labels at code generation
227 2. Give all binders a nice print-name. Their uniques aren't changed;
228 rather we give them lexically unique occ-names, so that we can
229 safely print the OccNae only in the interface file. [Bad idea to
230 change the uniques, because the code generator makes global labels
231 from the uniques for local thunks etc.]
235 tidyCorePgm :: Module -> [Class] -> [CoreBind] -> IO [CoreBind]
236 tidyCorePgm mod local_classes binds_in
238 beginPass "Tidy Core"
239 let (_, binds_out) = mapAccumL (tidyBind (Just mod)) init_tidy_env binds_in
240 endPass "Tidy Core" (opt_D_dump_simpl || opt_D_verbose_core2core) binds_out
242 -- Make sure to avoid the names of class operations
243 -- They don't have top-level bindings, so we won't see them
244 -- in binds_in; so we must initialise the tidy_env appropriately
246 -- We also make sure to avoid any exported binders. Consider
247 -- f{-u1-} = 1 -- Local decl
249 -- f{-u2-} = 2 -- Exported decl
251 -- The second exported decl must 'get' the name 'f', so we
252 -- have to put 'f' in the avoids list before we get to the first
253 -- decl. Name.tidyName then does a no-op on exported binders.
254 init_tidy_env = (initTidyOccEnv avoids, emptyVarEnv)
255 avoids = [getOccName sel_id | cls <- local_classes,
256 sel_id <- classSelIds cls]
258 [getOccName bndr | bind <- binds_in,
259 bndr <- bindersOf bind,
262 tidyBind :: Maybe Module -- (Just m) for top level, Nothing for nested
265 -> (TidyEnv, CoreBind)
266 tidyBind maybe_mod env (NonRec bndr rhs)
268 (env', bndr') = tidyBndr maybe_mod env bndr
269 rhs' = tidyExpr env rhs
271 (env', NonRec bndr' rhs')
273 tidyBind maybe_mod env (Rec pairs)
275 -- We use env' when tidying the rhss
276 -- When tidying the binder itself we may tidy it's
277 -- specialisations; if any of these mention other binders
278 -- in the group we should really feed env' to them too;
279 -- but that seems (a) unlikely and (b) a bit tiresome.
280 -- So I left it out for now
282 (bndrs, rhss) = unzip pairs
283 (env', bndrs') = mapAccumL (tidyBndr maybe_mod) env bndrs
284 rhss' = map (tidyExpr env') rhss
286 (env', Rec (zip bndrs' rhss'))
288 tidyExpr env (Type ty) = Type (tidyType env ty)
289 tidyExpr env (Con con args) = Con con (map (tidyExpr env) args)
290 tidyExpr env (App f a) = App (tidyExpr env f) (tidyExpr env a)
291 tidyExpr env (Note n e) = Note (tidyNote env n) (tidyExpr env e)
293 tidyExpr env (Let b e) = Let b' (tidyExpr env' e)
295 (env', b') = tidyBind Nothing env b
297 tidyExpr env (Case e b alts) = Case (tidyExpr env e) b' (map (tidyAlt env') alts)
299 (env', b') = tidyNestedBndr env b
301 tidyExpr env (Var v) = case lookupVarEnv var_env v of
307 tidyExpr env (Lam b e) = Lam b' (tidyExpr env' e)
309 (env', b') = tidyNestedBndr env b
311 tidyAlt env (con, vs, rhs) = (con, vs', tidyExpr env' rhs)
313 (env', vs') = mapAccumL tidyNestedBndr env vs
315 tidyNote env (Coerce t1 t2) = Coerce (tidyType env t1) (tidyType env t2)
317 tidyNote env note = note
321 tidyBndr (Just mod) env id = tidyTopBndr mod env id
322 tidyBndr Nothing env var = tidyNestedBndr env var
324 tidyNestedBndr env tyvar
326 = tidyTyVar env tyvar
328 tidyNestedBndr env@(tidy_env, var_env) id
329 = -- Non-top-level variables
331 -- Give the Id a fresh print-name, *and* rename its type
332 -- The SrcLoc isn't important now, though we could extract it from the Id
333 name' = mkLocalName (getUnique id) occ' noSrcLoc
334 (tidy_env', occ') = tidyOccName tidy_env (getOccName id)
335 ty' = tidyType env (idType id)
336 id' = mkUserId name' ty'
337 -- NB: This throws away the IdInfo of the Id, which we
338 -- no longer need. That means we don't need to
339 -- run over it with env, nor renumber it.
340 var_env' = extendVarEnv var_env id id'
342 ((tidy_env', var_env'), id')
344 tidyTopBndr mod env@(tidy_env, var_env) id
345 = -- Top level variables
347 (tidy_env', name') = tidyTopName mod tidy_env (idName id)
348 ty' = tidyTopType (idType id)
349 idinfo' = tidyIdInfo env (idInfo id)
350 id' = mkId name' ty' (idDetails id) idinfo'
351 var_env' = extendVarEnv var_env id id'
353 ((tidy_env', var_env'), id')
355 -- tidyIdInfo does these things:
356 -- a) tidy the specialisation info (if any)
357 -- b) zap a complicated ICanSafelyBeINLINEd pragma,
358 -- c) zap the unfolding
359 -- The latter two are to avoid space leaks
364 spec_items = specEnvToList (specInfo info)
365 spec_env' = specEnvFromList (map tidy_item spec_items)
366 info1 | null spec_items = info
367 | otherwise = spec_env' `setSpecInfo` info
369 info2 = case inlinePragInfo info of
370 ICanSafelyBeINLINEd _ _ -> NoInlinePragInfo `setInlinePragInfo` info1
373 info3 = noUnfolding `setUnfoldingInfo` info2
375 tidy_item (tyvars, tys, rhs)
376 = (tyvars', tidyTypes env' tys, tidyExpr env' rhs)
378 (env', tyvars') = tidyTyVars env tyvars
383 %************************************************************************
385 \subsection{PostSimplification}
387 %************************************************************************
389 Several tasks are performed by the post-simplification pass
391 1. Make the representation of NoRep literals explicit, and
392 float their bindings to the top level. We only do the floating
393 part for NoRep lits inside a lambda (else no gain). We need to
394 take care with let x = "foo" in e
395 that we don't end up with a silly binding
397 with a floated "foo". What a bore.
399 2. *Mangle* cases involving par# in the discriminant. The unfolding
400 for par in PrelConc.lhs include case expressions with integer
401 results solely to fool the strictness analyzer, the simplifier,
402 and anyone else who might want to fool with the evaluation order.
403 At this point in the compiler our evaluation order is safe.
404 Therefore, we convert expressions of the form:
413 fork# isn't handled like this - it's an explicit IO operation now.
414 The reason is that fork# returns a ThreadId#, which gets in the
415 way of the above scheme. And anyway, IO is the only guaranteed
416 way to enforce ordering --SDM.
418 3. Mangle cases involving seq# in the discriminant. Up to this
419 point, seq# will appear like this:
425 where the 0# branch is purely to bamboozle the strictness analyser
426 (see case 4 above). This code comes from an unfolding for 'seq'
427 in Prelude.hs. We translate this into
432 Now that the evaluation order is safe.
434 4. Do eta reduction for lambda abstractions appearing in:
435 - the RHS of case alternatives
438 These will otherwise turn into local bindings during Core->STG;
439 better to nuke them if possible. (In general the simplifier does
440 eta expansion not eta reduction, up to this point. It does eta
441 on the RHSs of bindings but not the RHSs of case alternatives and
445 ------------------- NOT DONE ANY MORE ------------------------
446 [March 98] Indirections are now elimianted by the occurrence analyser
447 1. Eliminate indirections. The point here is to transform
453 [Dec 98] [Not now done because there is no penalty in the code
454 generator for using the former form]
456 case x of {...; x' -> ...x'...}
458 case x of {...; _ -> ...x... }
459 See notes in SimplCase.lhs, near simplDefault for the reasoning here.
460 --------------------------------------------------------------
465 NOT ENABLED AT THE MOMENT (because the floated Ids are global-ish
466 things, and we need local Ids for non-floated stuff):
468 Don't float stuff out of a binder that's marked as a bottoming Id.
469 Reason: it doesn't do any good, and creates more CAFs that increase
478 f' = unpackCString# "string"
481 hence f' and f become CAFs. Instead, the special case for
482 tidyTopBinding below makes sure this comes out as
484 f = let f' = unpackCString# "string" in error f'
486 and we can safely ignore f as a CAF, since it can only ever be entered once.
491 doPostSimplification :: UniqSupply -> [CoreBind] -> IO [CoreBind]
492 doPostSimplification us binds_in
494 beginPass "Post-simplification pass"
495 let binds_out = initPM us (postSimplTopBinds binds_in)
496 endPass "Post-simplification pass" opt_D_verbose_core2core binds_out
498 postSimplTopBinds :: [CoreBind] -> PostM [CoreBind]
499 postSimplTopBinds binds
500 = mapPM postSimplTopBind binds `thenPM` \ binds' ->
501 returnPM (bagToList (unionManyBags binds'))
503 postSimplTopBind :: CoreBind -> PostM (Bag CoreBind)
504 postSimplTopBind (NonRec bndr rhs)
505 | isBottomingId bndr -- Don't lift out floats for bottoming Ids
507 = getFloatsPM (postSimplExpr rhs) `thenPM` \ (rhs', floats) ->
508 returnPM (unitBag (NonRec bndr (foldrBag Let rhs' floats)))
510 postSimplTopBind bind
511 = getFloatsPM (postSimplBind bind) `thenPM` \ (bind', floats) ->
512 returnPM (floats `snocBag` bind')
514 postSimplBind (NonRec bndr rhs)
515 = postSimplExpr rhs `thenPM` \ rhs' ->
516 returnPM (NonRec bndr rhs')
518 postSimplBind (Rec pairs)
519 = mapPM postSimplExpr rhss `thenPM` \ rhss' ->
520 returnPM (Rec (bndrs `zip` rhss'))
522 (bndrs, rhss) = unzip pairs
529 postSimplExpr (Var v) = returnPM (Var v)
530 postSimplExpr (Type ty) = returnPM (Type ty)
532 postSimplExpr (App fun arg)
533 = postSimplExpr fun `thenPM` \ fun' ->
534 postSimplExpr arg `thenPM` \ arg' ->
535 returnPM (App fun' arg')
537 postSimplExpr (Con (Literal lit) args)
538 = ASSERT( null args )
539 litToRep lit `thenPM` \ (lit_ty, lit_expr) ->
540 getInsideLambda `thenPM` \ in_lam ->
541 if in_lam && not (exprIsTrivial lit_expr) then
542 -- It must have been a no-rep literal with a
543 -- non-trivial representation; and we're inside a lambda;
544 -- so float it to the top
545 addTopFloat lit_ty lit_expr `thenPM` \ v ->
550 postSimplExpr (Con con args)
551 = mapPM postSimplExpr args `thenPM` \ args' ->
552 returnPM (Con con args')
554 postSimplExpr (Lam bndr body)
555 = insideLambda bndr $
556 postSimplExpr body `thenPM` \ body' ->
557 returnPM (Lam bndr body')
559 postSimplExpr (Let bind body)
560 = postSimplBind bind `thenPM` \ bind' ->
561 postSimplExprEta body `thenPM` \ body' ->
562 returnPM (Let bind' body')
564 postSimplExpr (Note note body)
565 = postSimplExprEta body `thenPM` \ body' ->
566 returnPM (Note note body')
568 -- seq#: see notes above.
569 -- NB: seq# :: forall a. a -> Int#
570 postSimplExpr (Case scrut@(Con (PrimOp SeqOp) [Type ty, e]) bndr alts)
571 = postSimplExpr e `thenPM` \ e' ->
573 -- The old binder can't have been used, so we
574 -- can gaily re-use it (yuk!)
575 new_bndr = setIdType bndr ty
577 postSimplExprEta default_rhs `thenPM` \ rhs' ->
578 returnPM (Case e' new_bndr [(DEFAULT,[],rhs')])
580 (other_alts, maybe_default) = findDefault alts
581 Just default_rhs = maybe_default
583 -- par#: see notes above.
584 postSimplExpr (Case scrut@(Con (PrimOp op) args) bndr alts)
585 | funnyParallelOp op && maybeToBool maybe_default
586 = postSimplExpr scrut `thenPM` \ scrut' ->
587 postSimplExprEta default_rhs `thenPM` \ rhs' ->
588 returnPM (Case scrut' bndr [(DEFAULT,[],rhs')])
590 (other_alts, maybe_default) = findDefault alts
591 Just default_rhs = maybe_default
593 postSimplExpr (Case scrut case_bndr alts)
594 = postSimplExpr scrut `thenPM` \ scrut' ->
595 mapPM ps_alt alts `thenPM` \ alts' ->
596 returnPM (Case scrut' case_bndr alts')
598 ps_alt (con,bndrs,rhs) = postSimplExprEta rhs `thenPM` \ rhs' ->
599 returnPM (con, bndrs, rhs')
601 postSimplExprEta e = postSimplExpr e `thenPM` \ e' ->
602 returnPM (etaCoreExpr e')
606 funnyParallelOp ParOp = True
607 funnyParallelOp _ = False
611 %************************************************************************
613 \subsection[coreToStg-lits]{Converting literals}
615 %************************************************************************
617 Literals: the NoRep kind need to be de-no-rep'd.
618 We always replace them with a simple variable, and float a suitable
619 binding out to the top level.
622 litToRep :: Literal -> PostM (Type, CoreExpr)
624 litToRep (NoRepStr s ty)
627 rhs = if (any is_NUL (_UNPK_ s))
629 then -- Must cater for NULs in literal string
630 mkApps (Var unpackCString2Id)
632 mkLit (mkMachInt (toInteger (_LENGTH_ s)))]
634 else -- No NULs in the string
635 App (Var unpackCStringId) (mkLit (MachStr s))
640 If an Integer is small enough (Haskell implementations must support
641 Ints in the range $[-2^29+1, 2^29-1]$), wrap it up in @int2Integer@;
642 otherwise, wrap with @addr2Integer@.
645 litToRep (NoRepInteger i integer_ty)
646 = returnPM (integer_ty, rhs)
648 rhs | i > tARGET_MIN_INT && -- Small enough, so start from an Int
650 = Con (DataCon smallIntegerDataCon) [Con (Literal (mkMachInt i)) []]
652 | otherwise -- Big, so start from a string
653 = App (Var addr2IntegerId) (Con (Literal (MachStr (_PK_ (show i)))) [])
656 litToRep (NoRepRational r rational_ty)
657 = postSimplExpr (mkLit (NoRepInteger (numerator r) integer_ty)) `thenPM` \ num_arg ->
658 postSimplExpr (mkLit (NoRepInteger (denominator r) integer_ty)) `thenPM` \ denom_arg ->
659 returnPM (rational_ty, mkConApp ratio_data_con [Type integer_ty, num_arg, denom_arg])
661 (ratio_data_con, integer_ty)
662 = case (splitAlgTyConApp_maybe rational_ty) of
663 Just (tycon, [i_ty], [con])
664 -> ASSERT(isIntegerTy i_ty && getUnique tycon == ratioTyConKey)
667 _ -> (panic "ratio_data_con", panic "integer_ty")
669 litToRep other_lit = returnPM (literalType other_lit, mkLit other_lit)
673 %************************************************************************
675 \subsection{The monad}
677 %************************************************************************
680 type PostM a = Bool -- True <=> inside a *value* lambda
681 -> (UniqSupply, Bag CoreBind) -- Unique supply and Floats in
682 -> (a, (UniqSupply, Bag CoreBind))
684 initPM :: UniqSupply -> PostM a -> a
686 = case m False {- not inside lambda -} (us, emptyBag) of
687 (result, _) -> result
689 returnPM v in_lam usf = (v, usf)
690 thenPM m k in_lam usf = case m in_lam usf of
691 (r, usf') -> k r in_lam usf'
693 mapPM f [] = returnPM []
694 mapPM f (x:xs) = f x `thenPM` \ r ->
695 mapPM f xs `thenPM` \ rs ->
698 insideLambda :: CoreBndr -> PostM a -> PostM a
699 insideLambda bndr m in_lam usf | isId bndr = m True usf
700 | otherwise = m in_lam usf
702 getInsideLambda :: PostM Bool
703 getInsideLambda in_lam usf = (in_lam, usf)
705 getFloatsPM :: PostM a -> PostM (a, Bag CoreBind)
706 getFloatsPM m in_lam (us, floats)
708 (a, (us', floats')) = m in_lam (us, emptyBag)
710 ((a, floats'), (us', floats))
712 addTopFloat :: Type -> CoreExpr -> PostM Id
713 addTopFloat lit_ty lit_rhs in_lam (us, floats)
715 (us1, us2) = splitUniqSupply us
716 uniq = uniqFromSupply us1
717 lit_id = mkSysLocal SLIT("lf") uniq lit_ty
719 (lit_id, (us2, floats `snocBag` NonRec lit_id lit_rhs))