2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
4 \section[CoreToStg]{Converts Core to STG Syntax}
6 And, as we have the info in hand, we may convert some lets to
10 module CoreToStg ( coreToStg, coreExprToStg ) where
12 #include "HsVersions.h"
21 import TyCon ( isAlgTyCon )
25 import CostCentre ( noCCS )
28 import DataCon ( dataConWrapId )
29 import IdInfo ( OccInfo(..) )
30 import PrimOp ( PrimOp(..), ccallMayGC )
31 import TysPrim ( foreignObjPrimTyCon )
32 import Maybes ( maybeToBool, orElse )
33 import Name ( getOccName )
34 import Module ( Module )
35 import OccName ( occNameUserString )
36 import BasicTypes ( TopLevelFlag(..), isNotTopLevel )
37 import CmdLineOpts ( DynFlags )
41 infixr 9 `thenLne`, `thenLne_`
44 %************************************************************************
46 \subsection[live-vs-free-doc]{Documentation}
48 %************************************************************************
50 (There is other relevant documentation in codeGen/CgLetNoEscape.)
52 The actual Stg datatype is decorated with {\em live variable}
53 information, as well as {\em free variable} information. The two are
54 {\em not} the same. Liveness is an operational property rather than a
55 semantic one. A variable is live at a particular execution point if
56 it can be referred to {\em directly} again. In particular, a dead
57 variable's stack slot (if it has one):
60 should be stubbed to avoid space leaks, and
62 may be reused for something else.
65 There ought to be a better way to say this. Here are some examples:
72 Just after the `in', v is live, but q is dead. If the whole of that
73 let expression was enclosed in a case expression, thus:
75 case (let v = [q] \[x] -> e in ...v...) of
78 (ie @alts@ mention @q@), then @q@ is live even after the `in'; because
79 we'll return later to the @alts@ and need it.
81 Let-no-escapes make this a bit more interesting:
83 let-no-escape v = [q] \ [x] -> e
87 Here, @q@ is still live at the `in', because @v@ is represented not by
88 a closure but by the current stack state. In other words, if @v@ is
89 live then so is @q@. Furthermore, if @e@ mentions an enclosing
90 let-no-escaped variable, then {\em its} free variables are also live
93 %************************************************************************
95 \subsection[binds-StgVarInfo]{Setting variable info: top-level, binds, RHSs}
97 %************************************************************************
100 coreToStg :: DynFlags -> Module -> [CoreBind] -> IO [StgBinding]
101 coreToStg dflags this_mod pgm
102 = return (fst (initLne (coreTopBindsToStg pgm)))
104 coreExprToStg :: CoreExpr -> StgExpr
106 = new_expr where (new_expr,_,_) = initLne (coreToStgExpr expr)
108 -- For top-level guys, we basically aren't worried about this
109 -- live-variable stuff; we do need to keep adding to the environment
110 -- as we step through the bindings (using @extendVarEnv@).
112 coreTopBindsToStg :: [CoreBind] -> LneM ([StgBinding], FreeVarsInfo)
114 coreTopBindsToStg [] = returnLne ([], emptyFVInfo)
115 coreTopBindsToStg (bind:binds)
117 binders = bindersOf bind
118 env_extension = binders `zip` repeat how_bound
119 how_bound = LetrecBound True {- top level -}
123 extendVarEnvLne env_extension (
124 coreTopBindsToStg binds `thenLne` \ (binds', fv_binds) ->
125 coreTopBindToStg binders fv_binds bind `thenLne` \ (bind', fv_bind) ->
128 (fv_binds `unionFVInfo` fv_bind) `minusFVBinders` binders
134 :: [Id] -- New binders (with correct arity)
135 -> FreeVarsInfo -- Info about the body
137 -> LneM (StgBinding, FreeVarsInfo)
139 coreTopBindToStg [binder] body_fvs (NonRec _ rhs)
140 = coreToStgRhs body_fvs TopLevel (binder,rhs) `thenLne` \ (rhs2, fvs, _) ->
141 returnLne (StgNonRec binder rhs2, fvs)
143 coreTopBindToStg binders body_fvs (Rec pairs)
144 = fixLne (\ ~(_, rec_rhs_fvs) ->
145 let scope_fvs = unionFVInfo body_fvs rec_rhs_fvs
147 mapAndUnzip3Lne (coreToStgRhs scope_fvs TopLevel) pairs
148 `thenLne` \ (rhss2, fvss, _) ->
149 let fvs = unionFVInfos fvss
151 returnLne (StgRec (binders `zip` rhss2), fvs)
157 :: FreeVarsInfo -- Free var info for the scope of the binding
160 -> LneM (StgRhs, FreeVarsInfo, EscVarsSet)
162 coreToStgRhs scope_fv_info top (binder, rhs)
163 = coreToStgExpr rhs `thenLne` \ (new_rhs, rhs_fvs, rhs_escs) ->
167 -> let binder_info = lookupFVInfo scope_fv_info binder
168 in returnLne (StgRhsClosure noCCS
178 | isNotTopLevel top || not (isDllConApp con args)
179 -> returnLne (StgRhsCon noCCS con args, rhs_fvs, rhs_escs)
182 -> let binder_info = lookupFVInfo scope_fv_info binder
183 in returnLne (StgRhsClosure noCCS
187 (updatable [] new_rhs)
193 updatable args body | null args && isPAP body = ReEntrant
194 | otherwise = Updatable
196 upd = if isOnceDem dem
197 then (if isNotTop toplev
198 then SingleEntry -- HA! Paydirt for "dem"
201 trace "WARNING: SE CAFs unsupported, forcing UPD instead" $
205 -- For now we forbid SingleEntry CAFs; they tickle the
206 -- ASSERT in rts/Storage.c line 215 at newCAF() re mut_link,
207 -- and I don't understand why. There's only one SE_CAF (well,
208 -- only one that tickled a great gaping bug in an earlier attempt
209 -- at ClosureInfo.getEntryConvention) in the whole of nofib,
210 -- specifically Main.lvl6 in spectral/cryptarithm2.
211 -- So no great loss. KSW 2000-07.
215 Detect thunks which will reduce immediately to PAPs, and make them
216 non-updatable. This has several advantages:
218 - the non-updatable thunk behaves exactly like the PAP,
220 - the thunk is more efficient to enter, because it is
221 specialised to the task.
223 - we save one update frame, one stg_update_PAP, one update
224 and lots of PAP_enters.
226 - in the case where the thunk is top-level, we save building
227 a black hole and futhermore the thunk isn't considered to
228 be a CAF any more, so it doesn't appear in any SRTs.
230 We do it here, because the arity information is accurate, and we need
231 to do it before the SRT pass to save the SRT entries associated with
235 isPAP (StgApp f args) = idArity f > length args
238 -- ---------------------------------------------------------------------------
240 -- ---------------------------------------------------------------------------
242 coreToStgAtoms :: [CoreArg] -> LneM ([StgArg], FreeVarsInfo)
244 = let val_atoms = filter isValArg atoms in
245 mapAndUnzipLne coreToStgAtom val_atoms `thenLne` \ (args', fvs_lists) ->
246 returnLne (args', unionFVInfos fvs_lists)
249 = coreToStgExpr e `thenLne` \ (expr, fvs, escs) ->
251 StgApp v [] -> returnLne (StgVarArg v, fvs)
252 StgConApp con [] -> returnLne (StgVarArg (dataConWrapId con), fvs)
253 StgLit lit -> returnLne (StgLitArg lit, fvs)
254 _ -> pprPanic "coreToStgAtom" (ppr expr)
256 -- ---------------------------------------------------------------------------
258 -- ---------------------------------------------------------------------------
261 @varsExpr@ carries in a monad-ised environment, which binds each
262 let(rec) variable (ie non top level, not imported, not lambda bound,
263 not case-alternative bound) to:
265 - its set of live vars.
266 For normal variables the set of live vars is just the variable
267 itself. For let-no-escaped variables, the set of live vars is the set
268 live at the moment the variable is entered. The set is guaranteed to
269 have no further let-no-escaped vars in it.
274 -> LneM (StgExpr, -- Decorated STG expr
275 FreeVarsInfo, -- Its free vars (NB free, not live)
276 EscVarsSet) -- Its escapees, a subset of its free vars;
277 -- also a subset of the domain of the envt
278 -- because we are only interested in the escapees
279 -- for vars which might be turned into
280 -- let-no-escaped ones.
283 The second and third components can be derived in a simple bottom up pass, not
284 dependent on any decisions about which variables will be let-no-escaped or
285 not. The first component, that is, the decorated expression, may then depend
286 on these components, but it in turn is not scrutinised as the basis for any
287 decisions. Hence no black holes.
290 coreToStgExpr (Lit l) = returnLne (StgLit l, emptyFVInfo, emptyVarSet)
292 coreToStgExpr (Var v)
293 = coreToStgApp Nothing v []
295 coreToStgExpr expr@(App _ _)
296 = let (f, args) = myCollectArgs expr
298 coreToStgApp Nothing (shouldBeVar f) args
300 coreToStgExpr expr@(Lam _ _)
301 = let (args, body) = myCollectBinders expr
302 args' = filter isId args
304 extendVarEnvLne [ (a, LambdaBound) | a <- args' ] $
305 coreToStgExpr body `thenLne` \ (body, body_fvs, body_escs) ->
307 set_of_args = mkVarSet args'
308 fvs = body_fvs `minusFVBinders` args'
309 escs = body_escs `minusVarSet` set_of_args
312 then returnLne (body, fvs, escs)
313 else returnLne (StgLam (exprType expr) args' body, fvs, escs)
315 coreToStgExpr (Note (SCC cc) expr)
316 = coreToStgExpr expr `thenLne` ( \ (expr2, fvs, escs) ->
317 returnLne (StgSCC cc expr2, fvs, escs) )
319 coreToStgExpr (Note other_note expr)
323 -- Cases require a little more real work.
325 coreToStgExpr (Case scrut bndr alts)
326 = getVarsLiveInCont `thenLne` \ live_in_cont ->
327 extendVarEnvLne [(bndr, CaseBound)] $
328 vars_alts (findDefault alts) `thenLne` \ (alts2, alts_fvs, alts_escs) ->
329 lookupLiveVarsForSet alts_fvs `thenLne` \ alts_lvs ->
331 -- determine whether the default binder is dead or not
332 bndr'= if (bndr `elementOfFVInfo` alts_fvs)
333 then bndr `setIdOccInfo` NoOccInfo
334 else bndr `setIdOccInfo` IAmDead
336 -- for a _ccall_GC_, some of the *arguments* need to live across the
337 -- call (see findLiveArgs comments.), so we annotate them as being live
338 -- in the alts to achieve the desired effect.
339 mb_live_across_case =
342 e@(App _ _) | (Var v, args) <- myCollectArgs e,
343 PrimOpId (CCallOp ccall) <- idFlavour v,
345 -> Just (filterVarSet isForeignObjArg (exprFreeVars e))
348 -- Don't consider the default binder as being 'live in alts',
349 -- since this is from the point of view of the case expr, where
350 -- the default binder is not free.
351 live_in_alts = orElse (FMAP unionVarSet mb_live_across_case) id $
352 live_in_cont `unionVarSet`
353 (alts_lvs `minusVarSet` unitVarSet bndr)
355 -- we tell the scrutinee that everything live in the alts
356 -- is live in it, too.
357 setVarsLiveInCont live_in_alts (
359 ) `thenLne` \ (scrut2, scrut_fvs, scrut_escs) ->
361 lookupLiveVarsForSet scrut_fvs `thenLne` \ scrut_lvs ->
363 live_in_whole_case = live_in_alts `unionVarSet` scrut_lvs
366 mkStgCase scrut2 live_in_whole_case live_in_alts bndr' noSRT alts2,
367 (scrut_fvs `unionFVInfo` alts_fvs) `minusFVBinders` [bndr],
368 (alts_escs `minusVarSet` unitVarSet bndr) `unionVarSet` getFVSet scrut_fvs
369 -- You might think we should have scrut_escs, not (getFVSet scrut_fvs),
370 -- but actually we can't call, and then return from, a let-no-escape thing.
373 scrut_ty = idType bndr
374 prim_case = isUnLiftedType scrut_ty && not (isUnboxedTupleType scrut_ty)
376 vars_alts (alts,deflt)
378 = mapAndUnzip3Lne vars_prim_alt alts
379 `thenLne` \ (alts2, alts_fvs_list, alts_escs_list) ->
381 alts_fvs = unionFVInfos alts_fvs_list
382 alts_escs = unionVarSets alts_escs_list
384 vars_deflt deflt `thenLne` \ (deflt2, deflt_fvs, deflt_escs) ->
386 mkStgPrimAlts scrut_ty alts2 deflt2,
387 alts_fvs `unionFVInfo` deflt_fvs,
388 alts_escs `unionVarSet` deflt_escs
392 = mapAndUnzip3Lne vars_alg_alt alts
393 `thenLne` \ (alts2, alts_fvs_list, alts_escs_list) ->
395 alts_fvs = unionFVInfos alts_fvs_list
396 alts_escs = unionVarSets alts_escs_list
398 vars_deflt deflt `thenLne` \ (deflt2, deflt_fvs, deflt_escs) ->
400 mkStgAlgAlts scrut_ty alts2 deflt2,
401 alts_fvs `unionFVInfo` deflt_fvs,
402 alts_escs `unionVarSet` deflt_escs
406 vars_prim_alt (LitAlt lit, _, rhs)
407 = coreToStgExpr rhs `thenLne` \ (rhs2, rhs_fvs, rhs_escs) ->
408 returnLne ((lit, rhs2), rhs_fvs, rhs_escs)
410 vars_alg_alt (DataAlt con, binders, rhs)
412 -- remove type variables
413 binders' = filter isId binders
415 extendVarEnvLne [(b, CaseBound) | b <- binders'] $
416 coreToStgExpr rhs `thenLne` \ (rhs2, rhs_fvs, rhs_escs) ->
418 good_use_mask = [ b `elementOfFVInfo` rhs_fvs | b <- binders' ]
419 -- records whether each param is used in the RHS
422 (con, binders', good_use_mask, rhs2),
423 rhs_fvs `minusFVBinders` binders',
424 rhs_escs `minusVarSet` mkVarSet binders'
425 -- ToDo: remove the minusVarSet;
426 -- since escs won't include any of these binders
430 = returnLne (StgNoDefault, emptyFVInfo, emptyVarSet)
432 vars_deflt (Just rhs)
433 = coreToStgExpr rhs `thenLne` \ (rhs2, rhs_fvs, rhs_escs) ->
434 returnLne (StgBindDefault rhs2, rhs_fvs, rhs_escs)
438 Lets not only take quite a bit of work, but this is where we convert
439 then to let-no-escapes, if we wish.
441 (Meanwhile, we don't expect to see let-no-escapes...)
443 coreToStgExpr (Let bind body)
444 = fixLne (\ ~(_, _, _, no_binder_escapes) ->
445 coreToStgLet no_binder_escapes bind body
446 ) `thenLne` \ (new_let, fvs, escs, _) ->
448 returnLne (new_let, fvs, escs)
451 If we've got a case containing a _ccall_GC_ primop, we need to
452 ensure that the arguments are kept live for the duration of the
453 call. This only an issue
456 isForeignObjArg :: Id -> Bool
457 isForeignObjArg x = isId x && isForeignObjPrimTy (idType x)
459 isForeignObjPrimTy ty
460 = case splitTyConApp_maybe ty of
461 Just (tycon, _) -> tycon == foreignObjPrimTyCon
466 mkStgCase scrut@(StgPrimApp ParOp _ _) lvs1 lvs2 bndr srt
467 (StgPrimAlts tycon _ deflt@(StgBindDefault _))
468 = StgCase scrut lvs1 lvs2 bndr srt (StgPrimAlts tycon [] deflt)
470 mkStgCase (StgPrimApp SeqOp [scrut] _) lvs1 lvs2 bndr srt
471 (StgPrimAlts _ _ deflt@(StgBindDefault rhs))
472 = StgCase scrut_expr lvs1 lvs2 new_bndr srt new_alts
475 | isUnLiftedType scrut_ty = WARN( True, text "mkStgCase" )
476 mkStgPrimAlts scrut_ty [] deflt
477 | otherwise = mkStgAlgAlts scrut_ty [] deflt
479 scrut_ty = stgArgType scrut
480 new_bndr = setIdType bndr scrut_ty
481 -- NB: SeqOp :: forall a. a -> Int#
482 -- So bndr has type Int#
483 -- But now we are going to scrutinise the SeqOp's argument directly,
484 -- so we must change the type of the case binder to match that
485 -- of the argument expression e.
487 scrut_expr = case scrut of
488 StgVarArg v -> StgApp v []
489 -- Others should not happen because
490 -- seq of a value should have disappeared
491 StgLitArg l -> WARN( True, text "seq on" <+> ppr l ) StgLit l
493 mkStgCase scrut lvs1 lvs2 bndr srt alts
494 = StgCase scrut lvs1 lvs2 bndr srt alts
497 mkStgAlgAlts ty alts deflt
499 -- Get the tycon from the data con
500 (dc, _, _, _) : _rest
501 -> StgAlgAlts (Just (dataConTyCon dc)) alts deflt
503 -- Otherwise just do your best
504 [] -> case splitTyConApp_maybe (repType ty) of
505 Just (tc,_) | isAlgTyCon tc
506 -> StgAlgAlts (Just tc) alts deflt
508 -> StgAlgAlts Nothing alts deflt
510 mkStgPrimAlts ty alts deflt
511 = StgPrimAlts (tyConAppTyCon ty) alts deflt
518 :: Maybe UpdateFlag -- Just upd <=> this application is
519 -- the rhs of a thunk binding
520 -- x = [...] \upd [] -> the_app
521 -- with specified update flag
523 -> [CoreArg] -- Arguments
524 -> LneM (StgExpr, FreeVarsInfo, EscVarsSet)
526 coreToStgApp maybe_thunk_body f args
527 = getVarsLiveInCont `thenLne` \ live_in_cont ->
528 coreToStgAtoms args `thenLne` \ (args', args_fvs) ->
529 lookupVarLne f `thenLne` \ how_bound ->
533 not_letrec_bound = not (isLetrecBound how_bound)
535 fun_fvs = singletonFVInfo f how_bound fun_occ
538 | not_letrec_bound = NoStgBinderInfo -- Uninteresting variable
540 -- Otherwise it is letrec bound; must have its arity
541 | n_args == 0 = stgFakeFunAppOcc -- Function Application
542 -- with no arguments.
543 -- used by the lambda lifter.
544 | f_arity > n_args = stgUnsatOcc -- Unsaturated
546 | f_arity == n_args &&
547 maybeToBool maybe_thunk_body -- Exactly saturated,
549 = case maybe_thunk_body of
550 Just Updatable -> stgStdHeapOcc
551 Just SingleEntry -> stgNoUpdHeapOcc
552 other -> panic "coreToStgApp"
554 | otherwise = stgNormalOcc
555 -- Record only that it occurs free
557 myself = unitVarSet f
559 fun_escs | not_letrec_bound = emptyVarSet
560 -- Only letrec-bound escapees are interesting
561 | f_arity == n_args = emptyVarSet
562 -- Function doesn't escape
564 -- Inexact application; it does escape
566 -- At the moment of the call:
568 -- either the function is *not* let-no-escaped, in which case
569 -- nothing is live except live_in_cont
570 -- or the function *is* let-no-escaped in which case the
571 -- variables it uses are live, but still the function
572 -- itself is not. PS. In this case, the function's
573 -- live vars should already include those of the
574 -- continuation, but it does no harm to just union the
579 -- = live_in_cont `unionVarSet` case how_bound of
580 -- LetrecBound _ lvs -> lvs `minusVarSet` myself
581 -- other -> emptyVarSet
583 app = case idFlavour f of
584 DataConId dc -> StgConApp dc args'
585 PrimOpId op -> StgPrimApp op args' (exprType (mkApps (Var f) args))
586 _other -> StgApp f args'
591 fun_fvs `unionFVInfo` args_fvs,
592 fun_escs `unionVarSet` (getFVSet args_fvs)
593 -- All the free vars of the args are disqualified
594 -- from being let-no-escaped.
598 -- ---------------------------------------------------------------------------
599 -- The magic for lets:
600 -- ---------------------------------------------------------------------------
603 :: Bool -- True <=> yes, we are let-no-escaping this let
604 -> CoreBind -- bindings
606 -> LneM (StgExpr, -- new let
607 FreeVarsInfo, -- variables free in the whole let
608 EscVarsSet, -- variables that escape from the whole let
609 Bool) -- True <=> none of the binders in the bindings
610 -- is among the escaping vars
612 coreToStgLet let_no_escape bind body
613 = fixLne (\ ~(_, _, _, rec_bind_lvs, _, rec_body_fvs, _, _) ->
615 -- Do the bindings, setting live_in_cont to empty if
616 -- we ain't in a let-no-escape world
617 getVarsLiveInCont `thenLne` \ live_in_cont ->
619 (if let_no_escape then live_in_cont else emptyVarSet)
620 (vars_bind rec_bind_lvs rec_body_fvs bind)
621 `thenLne` \ (bind2, bind_fvs, bind_escs, env_ext) ->
623 -- The live variables of this binding are the ones which are live
624 -- by virtue of being accessible via the free vars of the binding (lvs_from_fvs)
625 -- together with the live_in_cont ones
626 lookupLiveVarsForSet (bind_fvs `minusFVBinders` binders)
627 `thenLne` \ lvs_from_fvs ->
629 bind_lvs = lvs_from_fvs `unionVarSet` live_in_cont
632 -- bind_fvs and bind_escs still include the binders of the let(rec)
633 -- but bind_lvs does not
636 extendVarEnvLne env_ext (
637 coreToStgExpr body `thenLne` \ (body2, body_fvs, body_escs) ->
638 lookupLiveVarsForSet body_fvs `thenLne` \ body_lvs ->
640 returnLne (bind2, bind_fvs, bind_escs, bind_lvs,
641 body2, body_fvs, body_escs, body_lvs)
643 )) `thenLne` (\ (bind2, bind_fvs, bind_escs, bind_lvs,
644 body2, body_fvs, body_escs, body_lvs) ->
647 -- Compute the new let-expression
649 new_let | let_no_escape = StgLetNoEscape live_in_whole_let bind_lvs bind2 body2
650 | otherwise = StgLet bind2 body2
653 = (bind_fvs `unionFVInfo` body_fvs) `minusFVBinders` binders
656 = bind_lvs `unionVarSet` (body_lvs `minusVarSet` set_of_binders)
658 real_bind_escs = if let_no_escape then
662 -- Everything escapes which is free in the bindings
664 let_escs = (real_bind_escs `unionVarSet` body_escs) `minusVarSet` set_of_binders
666 all_escs = bind_escs `unionVarSet` body_escs -- Still includes binders of
669 no_binder_escapes = isEmptyVarSet (set_of_binders `intersectVarSet` all_escs)
672 -- Debugging code as requested by Andrew Kennedy
673 checked_no_binder_escapes
674 | not no_binder_escapes && any is_join_var binders
675 = pprTrace "Interesting! A join var that isn't let-no-escaped" (ppr binders)
677 | otherwise = no_binder_escapes
679 checked_no_binder_escapes = no_binder_escapes
682 -- Mustn't depend on the passed-in let_no_escape flag, since
683 -- no_binder_escapes is used by the caller to derive the flag!
689 checked_no_binder_escapes
692 set_of_binders = mkVarSet binders
693 binders = case bind of
694 NonRec binder rhs -> [binder]
695 Rec pairs -> map fst pairs
697 mk_binding bind_lvs binder
698 = (binder, LetrecBound False -- Not top level
702 live_vars = if let_no_escape then
703 extendVarSet bind_lvs binder
707 vars_bind :: StgLiveVars
708 -> FreeVarsInfo -- Free var info for body of binding
711 FreeVarsInfo, EscVarsSet, -- free vars; escapee vars
713 -- extension to environment
715 vars_bind rec_bind_lvs rec_body_fvs (NonRec binder rhs)
716 = coreToStgRhs rec_body_fvs NotTopLevel (binder,rhs)
717 `thenLne` \ (rhs2, fvs, escs) ->
719 env_ext_item@(binder', _) = mk_binding rec_bind_lvs binder
721 returnLne (StgNonRec binder' rhs2, fvs, escs, [env_ext_item])
723 vars_bind rec_bind_lvs rec_body_fvs (Rec pairs)
725 binders = map fst pairs
726 env_ext = map (mk_binding rec_bind_lvs) binders
728 extendVarEnvLne env_ext (
729 fixLne (\ ~(_, rec_rhs_fvs, _, _) ->
731 rec_scope_fvs = unionFVInfo rec_body_fvs rec_rhs_fvs
733 mapAndUnzip3Lne (coreToStgRhs rec_scope_fvs NotTopLevel) pairs
734 `thenLne` \ (rhss2, fvss, escss) ->
736 fvs = unionFVInfos fvss
737 escs = unionVarSets escss
739 returnLne (StgRec (binders `zip` rhss2), fvs, escs, env_ext)
742 is_join_var :: Id -> Bool
743 -- A hack (used only for compiler debuggging) to tell if
744 -- a variable started life as a join point ($j)
745 is_join_var j = occNameUserString (getOccName j) == "$j"
748 %************************************************************************
750 \subsection[LNE-monad]{A little monad for this let-no-escaping pass}
752 %************************************************************************
754 There's a lot of stuff to pass around, so we use this @LneM@ monad to
755 help. All the stuff here is only passed {\em down}.
758 type LneM a = IdEnv HowBound
759 -> StgLiveVars -- vars live in continuation
767 Bool -- True <=> bound at top level
768 StgLiveVars -- Live vars... see notes below
770 isLetrecBound (LetrecBound _ _) = True
771 isLetrecBound other = False
774 For a let(rec)-bound variable, x, we record what varibles are live if
775 x is live. For "normal" variables that is just x alone. If x is
776 a let-no-escaped variable then x is represented by a code pointer and
777 a stack pointer (well, one for each stack). So all of the variables
778 needed in the execution of x are live if x is, and are therefore recorded
779 in the LetrecBound constructor; x itself *is* included.
781 The std monad functions:
783 initLne :: LneM a -> a
784 initLne m = m emptyVarEnv emptyVarSet
786 {-# INLINE thenLne #-}
787 {-# INLINE thenLne_ #-}
788 {-# INLINE returnLne #-}
790 returnLne :: a -> LneM a
791 returnLne e env lvs_cont = e
793 thenLne :: LneM a -> (a -> LneM b) -> LneM b
794 thenLne m k env lvs_cont
795 = case (m env lvs_cont) of
796 m_result -> k m_result env lvs_cont
798 thenLne_ :: LneM a -> LneM b -> LneM b
799 thenLne_ m k env lvs_cont
800 = case (m env lvs_cont) of
803 mapLne :: (a -> LneM b) -> [a] -> LneM [b]
804 mapLne f [] = returnLne []
806 = f x `thenLne` \ r ->
807 mapLne f xs `thenLne` \ rs ->
810 mapAndUnzipLne :: (a -> LneM (b,c)) -> [a] -> LneM ([b],[c])
812 mapAndUnzipLne f [] = returnLne ([],[])
813 mapAndUnzipLne f (x:xs)
814 = f x `thenLne` \ (r1, r2) ->
815 mapAndUnzipLne f xs `thenLne` \ (rs1, rs2) ->
816 returnLne (r1:rs1, r2:rs2)
818 mapAndUnzip3Lne :: (a -> LneM (b,c,d)) -> [a] -> LneM ([b],[c],[d])
820 mapAndUnzip3Lne f [] = returnLne ([],[],[])
821 mapAndUnzip3Lne f (x:xs)
822 = f x `thenLne` \ (r1, r2, r3) ->
823 mapAndUnzip3Lne f xs `thenLne` \ (rs1, rs2, rs3) ->
824 returnLne (r1:rs1, r2:rs2, r3:rs3)
826 fixLne :: (a -> LneM a) -> LneM a
827 fixLne expr env lvs_cont = result
829 result = expr result env lvs_cont
830 -- ^^^^^^ ------ ^^^^^^
833 Functions specific to this monad:
835 getVarsLiveInCont :: LneM StgLiveVars
836 getVarsLiveInCont env lvs_cont = lvs_cont
838 setVarsLiveInCont :: StgLiveVars -> LneM a -> LneM a
839 setVarsLiveInCont new_lvs_cont expr env lvs_cont
840 = expr env new_lvs_cont
842 extendVarEnvLne :: [(Id, HowBound)] -> LneM a -> LneM a
843 extendVarEnvLne ids_w_howbound expr env lvs_cont
844 = expr (extendVarEnvList env ids_w_howbound) lvs_cont
846 lookupVarLne :: Id -> LneM HowBound
847 lookupVarLne v env lvs_cont
849 case (lookupVarEnv env v) of
851 Nothing -> ImportBound
854 -- The result of lookupLiveVarsForSet, a set of live variables, is
855 -- only ever tacked onto a decorated expression. It is never used as
856 -- the basis of a control decision, which might give a black hole.
858 lookupLiveVarsForSet :: FreeVarsInfo -> LneM StgLiveVars
860 lookupLiveVarsForSet fvs env lvs_cont
861 = returnLne (unionVarSets (map do_one (getFVs fvs)))
865 = if isLocalId v then
866 case (lookupVarEnv env v) of
867 Just (LetrecBound _ lvs) -> extendVarSet lvs v
868 Just _ -> unitVarSet v
869 Nothing -> pprPanic "lookupVarEnv/do_one:" (ppr v)
875 %************************************************************************
877 \subsection[Free-var info]{Free variable information}
879 %************************************************************************
882 type FreeVarsInfo = IdEnv (Id, Bool, StgBinderInfo)
883 -- If f is mapped to NoStgBinderInfo, that means
884 -- that f *is* mentioned (else it wouldn't be in the
885 -- IdEnv at all), but only in a saturated applications.
887 -- All case/lambda-bound things are also mapped to
888 -- NoStgBinderInfo, since we aren't interested in their
891 -- The Bool is True <=> the Id is top level letrec bound
893 type EscVarsSet = IdSet
897 emptyFVInfo :: FreeVarsInfo
898 emptyFVInfo = emptyVarEnv
900 singletonFVInfo :: Id -> HowBound -> StgBinderInfo -> FreeVarsInfo
901 singletonFVInfo id ImportBound info = emptyVarEnv
902 singletonFVInfo id (LetrecBound top_level _) info = unitVarEnv id (id, top_level, info)
903 singletonFVInfo id other info = unitVarEnv id (id, False, info)
905 unionFVInfo :: FreeVarsInfo -> FreeVarsInfo -> FreeVarsInfo
906 unionFVInfo fv1 fv2 = plusVarEnv_C plusFVInfo fv1 fv2
908 unionFVInfos :: [FreeVarsInfo] -> FreeVarsInfo
909 unionFVInfos fvs = foldr unionFVInfo emptyFVInfo fvs
911 minusFVBinders :: FreeVarsInfo -> [Id] -> FreeVarsInfo
912 minusFVBinders fv ids = fv `delVarEnvList` ids
914 elementOfFVInfo :: Id -> FreeVarsInfo -> Bool
915 elementOfFVInfo id fvs = maybeToBool (lookupVarEnv fvs id)
917 lookupFVInfo :: FreeVarsInfo -> Id -> StgBinderInfo
918 lookupFVInfo fvs id = case lookupVarEnv fvs id of
919 Nothing -> NoStgBinderInfo
920 Just (_,_,info) -> info
922 getFVs :: FreeVarsInfo -> [Id] -- Non-top-level things only
923 getFVs fvs = [id | (id,False,_) <- rngVarEnv fvs]
925 getFVSet :: FreeVarsInfo -> IdSet
926 getFVSet fvs = mkVarSet (getFVs fvs)
928 plusFVInfo (id1,top1,info1) (id2,top2,info2)
929 = ASSERT (id1 == id2 && top1 == top2)
930 (id1, top1, combineStgBinderInfo info1 info2)
936 shouldBeVar (Note _ e) = shouldBeVar e
937 shouldBeVar (Var v) = v
938 shouldBeVar e = pprPanic "shouldBeVar" (ppr e)
940 -- ignore all notes except SCC
941 myCollectBinders expr
944 go bs (Lam b e) = go (b:bs) e
945 go bs e@(Note (SCC _) _) = (reverse bs, e)
946 go bs (Note _ e) = go bs e
947 go bs e = (reverse bs, e)
949 myCollectArgs :: Expr b -> (Expr b, [Arg b])
953 go (App f a) as = go f (a:as)
954 go (Note (SCC _) e) as = panic "CoreToStg.myCollectArgs"
955 go (Note n e) as = go e as