2 % (c) The AQUA Project, Glasgow University, 1993-1996
4 \section[SimplEnv]{Environment stuff for the simplifier}
7 #include "HsVersions.h"
10 nullSimplEnv, combineSimplEnv,
11 pprSimplEnv, -- debugging only
13 extendTyEnv, extendTyEnvList,
16 extendIdEnvWithAtom, extendIdEnvWithAtoms,
17 extendIdEnvWithClone, extendIdEnvWithClones,
22 lookupRhsInfo, lookupOutIdEnv, isEvaluated,
23 extendEnvGivenBinding, extendEnvGivenNewRhs,
24 extendEnvGivenRhsInfo, extendEnvGivenInlining,
28 getSwitchChecker, switchIsSet, getSimplIntSwitch,
29 switchOffInlining, setCaseScrutinee,
31 setEnclosingCC, getEnclosingCC,
34 SYN_IE(SwitchChecker),
36 SYN_IE(InIdEnv), SYN_IE(InTypeEnv),
40 SYN_IE(InId), SYN_IE(InBinder), SYN_IE(InBinding), SYN_IE(InType),
41 SYN_IE(OutId), SYN_IE(OutBinder), SYN_IE(OutBinding), SYN_IE(OutType),
43 SYN_IE(InExpr), SYN_IE(InAlts), SYN_IE(InDefault), SYN_IE(InArg),
44 SYN_IE(OutExpr), SYN_IE(OutAlts), SYN_IE(OutDefault), SYN_IE(OutArg)
49 #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201
50 IMPORT_DELOOPER(SmplLoop) -- breaks the MagicUFs / SimplEnv loop
53 import BinderInfo ( orBinderInfo, andBinderInfo, noBinderInfo, isOneOcc,
55 BinderInfo {-instances, too-}
57 import CmdLineOpts ( switchIsOn, intSwitchSet, opt_UnfoldingCreationThreshold,
58 SimplifierSwitch(..), SwitchResult(..)
61 import CoreUnfold ( mkFormSummary, couldBeSmallEnoughToInline, whnfOrBottom,
62 Unfolding(..), UfExpr, RdrName,
63 SimpleUnfolding(..), FormSummary(..),
64 calcUnfoldingGuidance, UnfoldingGuidance(..)
66 import CoreUtils ( coreExprCc, unTagBinders )
67 import CostCentre ( CostCentre, subsumedCosts, noCostCentreAttached )
68 import FiniteMap -- lots of things
69 import Id ( idType, getIdUnfolding, getIdStrictness, idWantsToBeINLINEd,
70 applyTypeEnvToId, getInlinePragma,
71 nullIdEnv, growIdEnvList, rngIdEnv, lookupIdEnv,
72 addOneToIdEnv, modifyIdEnv, mkIdSet, modifyIdEnv_Directly,
73 SYN_IE(IdEnv), SYN_IE(IdSet), GenId, SYN_IE(Id) )
74 import Literal ( isNoRepLit, Literal{-instances-} )
75 import Maybes ( maybeToBool, expectJust )
76 import Name ( isLocallyDefined )
77 import OccurAnal ( occurAnalyseExpr )
78 import Outputable ( PprStyle(..), Outputable(..){-instances-} )
79 import PprCore -- various instances
80 import PprType ( GenType, GenTyVar )
82 import Type ( eqTy, applyTypeEnvToTy, SYN_IE(Type) )
83 import TyVar ( nullTyVarEnv, addOneToTyVarEnv, growTyVarEnvList,
84 SYN_IE(TyVarEnv), GenTyVar{-instance Eq-} ,
87 import Unique ( Unique{-instance Outputable-}, Uniquable(..) )
88 import UniqFM ( addToUFM, addToUFM_C, ufmToList )
89 import Usage ( SYN_IE(UVar), GenUsage{-instances-} )
90 import Util ( SYN_IE(Eager), appEager, returnEager, runEager,
91 zipEqual, thenCmp, cmpList, panic, panic#, assertPanic, Ord3(..) )
95 %************************************************************************
97 \subsection[Simplify-types]{Type declarations}
99 %************************************************************************
102 type InId = Id -- Not yet cloned
103 type InBinder = (InId, BinderInfo)
104 type InType = Type -- Ditto
105 type InBinding = SimplifiableCoreBinding
106 type InExpr = SimplifiableCoreExpr
107 type InAlts = SimplifiableCoreCaseAlts
108 type InDefault = SimplifiableCoreCaseDefault
109 type InArg = SimplifiableCoreArg
111 type OutId = Id -- Cloned
113 type OutType = Type -- Cloned
114 type OutBinding = CoreBinding
115 type OutExpr = CoreExpr
116 type OutAlts = CoreCaseAlts
117 type OutDefault = CoreCaseDefault
118 type OutArg = CoreArg
120 type SwitchChecker = SimplifierSwitch -> SwitchResult
123 %************************************************************************
125 \subsubsection{The @SimplEnv@ type}
127 %************************************************************************
130 INVARIANT: we assume {\em no shadowing}. (ToDo: How can we ASSERT
131 this? WDP 94/06) This allows us to neglect keeping everything paired
132 with its static environment.
134 The environment contains bindings for all
136 {\em locally-defined}
139 For such things, any unfolding is found in the environment, not in the
140 Id. Unfoldings in the Id itself are used only for imported things
141 (otherwise we get trouble because we have to simplify the unfoldings
142 inside the Ids, etc.).
148 CostCentre -- The enclosing cost-centre (when profiling)
149 InTypeEnv -- Maps old type variables to new clones
150 InIdEnv -- Maps locally-bound Ids to new clones
151 OutIdEnv -- Info about the values of OutIds
152 ConAppMap -- Maps constructor applications back to OutIds
155 nullSimplEnv :: SwitchChecker -> SimplEnv
158 = SimplEnv sw_chkr subsumedCosts nullTyVarEnv nullIdEnv nullIdEnv nullConApps
160 combineSimplEnv :: SimplEnv -> SimplEnv -> SimplEnv
161 combineSimplEnv env@(SimplEnv chkr _ _ _ out_id_env con_apps)
162 new_env@(SimplEnv _ encl_cc ty_env in_id_env _ _ )
163 = SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps
165 pprSimplEnv (SimplEnv _ _ ty_env in_id_env out_id_env con_apps) = panic "pprSimplEnv"
169 %************************************************************************
171 \subsubsection{Command-line switches}
173 %************************************************************************
176 getSwitchChecker :: SimplEnv -> SwitchChecker
177 getSwitchChecker (SimplEnv chkr _ _ _ _ _) = chkr
179 switchIsSet :: SimplEnv -> SimplifierSwitch -> Bool
180 switchIsSet (SimplEnv chkr _ _ _ _ _) switch
181 = switchIsOn chkr switch
183 getSimplIntSwitch :: SwitchChecker -> (Int-> SimplifierSwitch) -> Int
184 getSimplIntSwitch chkr switch
185 = expectJust "getSimplIntSwitch" (intSwitchSet chkr switch)
188 setCaseScrutinee :: SimplEnv -> SimplEnv
189 setCaseScrutinee (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
190 = SimplEnv chkr' encl_cc ty_env in_id_env out_id_env con_apps
192 chkr' SimplCaseScrutinee = SwBool True
193 chkr' other = chkr other
196 @switchOffInlining@ is used to prepare the environment for simplifying
197 the RHS of an Id that's marked with an INLINE pragma. It is going to
198 be inlined wherever they are used, and then all the inlining will take
199 effect. Meanwhile, there isn't much point in doing anything to the
200 as-yet-un-INLINEd rhs. Furthremore, it's very important to switch off
202 (a) not doing so will inline a worker straight back into its wrapper!
204 and (b) Consider the following example
209 in ...g...g...g...g...g...
211 Now, if that's the ONLY occurrence of f, it will be inlined inside g,
212 and thence copied multiple times when g is inlined.
214 Andy disagrees! Example:
215 all xs = foldr (&&) True xs
216 any p = all . map p {-# INLINE any #-}
218 Problem: any won't get deforested, and so if it's exported and
219 the importer doesn't use the inlining, (eg passes it as an arg)
220 then we won't get deforestation at all.
221 We havn't solved this problem yet!
223 We prepare the envt by simply discarding the out_id_env, which has
224 all the unfolding info. At one point we did it by modifying the chkr so
225 that it said "EssentialUnfoldingsOnly", but that prevented legitmate, and important,
226 simplifications happening in the body of the RHS.
229 switchOffInlining :: SimplEnv -> SimplEnv
230 switchOffInlining (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
231 = SimplEnv chkr encl_cc ty_env in_id_env nullIdEnv nullConApps
234 %************************************************************************
236 \subsubsection{The ``enclosing cost-centre''}
238 %************************************************************************
241 setEnclosingCC :: SimplEnv -> CostCentre -> SimplEnv
243 setEnclosingCC (SimplEnv chkr _ ty_env in_id_env out_id_env con_apps) encl_cc
244 = SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps
246 getEnclosingCC :: SimplEnv -> CostCentre
247 getEnclosingCC (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps) = encl_cc
250 %************************************************************************
252 \subsubsection{The @TypeEnv@ part}
254 %************************************************************************
257 type TypeEnv = TyVarEnv Type
258 type InTypeEnv = TypeEnv -- Maps InTyVars to OutTypes
260 extendTyEnv :: SimplEnv -> TyVar -> Type -> SimplEnv
261 extendTyEnv (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps) tyvar ty
262 = SimplEnv chkr encl_cc new_ty_env in_id_env out_id_env con_apps
264 new_ty_env = addOneToTyVarEnv ty_env tyvar ty
266 extendTyEnvList :: SimplEnv -> [(TyVar,Type)] -> SimplEnv
267 extendTyEnvList (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps) pairs
268 = SimplEnv chkr encl_cc new_ty_env in_id_env out_id_env con_apps
270 new_ty_env = growTyVarEnvList ty_env pairs
272 simplTy (SimplEnv _ _ ty_env _ _ _) ty = returnEager (applyTypeEnvToTy ty_env ty)
273 simplTyInId (SimplEnv _ _ ty_env _ _ _) id = returnEager (applyTypeEnvToId ty_env id)
276 %************************************************************************
278 \subsubsection{The ``Id env'' part}
280 %************************************************************************
283 type InIdEnv = IdEnv OutArg -- Maps InIds to their value
284 -- Usually this is just the cloned Id, but if
285 -- if the orig defn is a let-binding, and
286 -- the RHS of the let simplifies to an atom,
287 -- we just bind the variable to that atom, and
292 lookupId :: SimplEnv -> Id -> Eager ans OutArg
294 lookupId (SimplEnv _ _ _ in_id_env _ _) id
295 = case (lookupIdEnv in_id_env id) of
296 Just atom -> returnEager atom
297 Nothing -> returnEager (VarArg id)
304 -> OutArg{-Val args only, please-}
307 extendIdEnvWithAtom (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
308 (in_id,occ_info) atom
310 LitArg _ -> SimplEnv chkr encl_cc ty_env new_in_id_env out_id_env con_apps
311 VarArg out_id -> SimplEnv chkr encl_cc ty_env new_in_id_env
312 (modifyOccInfo out_id_env (uniqueOf out_id, occ_info)) con_apps
313 --SimplEnv chkr encl_cc ty_env new_in_id_env new_out_id_env con_apps
315 new_in_id_env = addOneToIdEnv in_id_env in_id atom
317 new_out_id_env = case atom of
318 LitArg _ -> out_id_env
319 VarArg out_id -> modifyOccInfo out_id_env (uniqueOf out_id, occ_info)
322 extendIdEnvWithAtoms :: SimplEnv -> [(InBinder, OutArg)] -> SimplEnv
323 extendIdEnvWithAtoms = foldr (\ (bndr,val) env -> extendIdEnvWithAtom env bndr val)
326 extendIdEnvWithClone :: SimplEnv -> InBinder -> OutId -> SimplEnv
328 extendIdEnvWithClone (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
330 = SimplEnv chkr encl_cc ty_env new_in_id_env out_id_env con_apps
332 new_in_id_env = addOneToIdEnv in_id_env in_id (VarArg out_id)
334 extendIdEnvWithClones :: SimplEnv -> [InBinder] -> [OutId] -> SimplEnv
335 extendIdEnvWithClones (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
337 = SimplEnv chkr encl_cc ty_env new_in_id_env out_id_env con_apps
339 new_in_id_env = growIdEnvList in_id_env bindings
340 bindings = zipEqual "extendIdEnvWithClones"
341 [id | (id,_) <- in_binders]
345 %************************************************************************
347 \subsubsection{The @OutIdEnv@}
349 %************************************************************************
352 The domain of @OutIdInfo@ is some, but not necessarily all, in-scope @OutId@s;
353 both locally-bound ones, and perhaps some imported ones too.
356 type OutIdEnv = IdEnv (OutId, BinderInfo, RhsInfo)
360 The "Id" part is just so that we can recover the domain of the mapping, which
361 IdEnvs don't allow directly.
363 The @BinderInfo@ tells about the occurrences of the @OutId@.
364 Anything that isn't in here should be assumed to occur many times.
365 We keep this info so we can modify it when something changes.
367 The @RhsInfo@ part tells about the value to which the @OutId@ is bound.
370 data RhsInfo = NoRhsInfo
371 | OtherLit [Literal] -- It ain't one of these
372 | OtherCon [Id] -- It ain't one of these
374 -- InUnfolding is used for let(rec) bindings that
375 -- are *definitely* going to be inlined.
376 -- We record the un-simplified RHS and drop the binding
377 | InUnfolding SimplEnv -- Un-simplified unfolding
378 SimplifiableCoreExpr -- (need to snag envts therefore)
380 | OutUnfolding CostCentre
381 SimpleUnfolding -- Already-simplified unfolding
383 lookupOutIdEnv :: SimplEnv -> OutId -> Maybe (OutId,BinderInfo,RhsInfo)
384 lookupOutIdEnv (SimplEnv _ _ _ _ out_id_env _) id = lookupIdEnv out_id_env id
386 lookupRhsInfo :: SimplEnv -> OutId -> RhsInfo
388 = case lookupOutIdEnv env id of
389 Just (_,_,info) -> info
392 modifyOutEnvItem :: (OutId, BinderInfo, RhsInfo)
393 -> (OutId, BinderInfo, RhsInfo)
394 -> (OutId, BinderInfo, RhsInfo)
395 modifyOutEnvItem (id, occ, info1) (_, _, info2)
396 = case (info1, info2) of
397 (OtherLit ls1, OtherLit ls2) -> (id,occ, OtherLit (ls1++ls2))
398 (OtherCon cs1, OtherCon cs2) -> (id,occ, OtherCon (cs1++cs2))
399 (_, NoRhsInfo) -> (id,occ, info1)
400 other -> (id,occ, info2)
405 isEvaluated :: RhsInfo -> Bool
406 isEvaluated (OtherLit _) = True
407 isEvaluated (OtherCon _) = True
408 isEvaluated (OutUnfolding _ (SimpleUnfolding ValueForm _ expr)) = True
409 isEvaluated other = False
415 mkSimplUnfoldingGuidance chkr out_id rhs
416 = calcUnfoldingGuidance (getInlinePragma out_id) opt_UnfoldingCreationThreshold rhs
418 extendEnvGivenRhsInfo :: SimplEnv -> OutId -> BinderInfo -> RhsInfo -> SimplEnv
419 extendEnvGivenRhsInfo env@(SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
420 out_id occ_info rhs_info
421 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env con_apps
423 new_out_id_env = addToUFM_C modifyOutEnvItem out_id_env out_id
424 (out_id, occ_info, rhs_info)
429 modifyOccInfo out_id_env (uniq, new_occ)
430 = modifyIdEnv_Directly modify_fn out_id_env uniq
432 modify_fn (id,occ,rhs) = (id, orBinderInfo occ new_occ, rhs)
434 markDangerousOccs (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps) atoms
435 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env con_apps
437 new_out_id_env = foldl (modifyIdEnv modify_fn) out_id_env [v | VarArg v <- atoms]
438 modify_fn (id,occ,rhs) = (id, noBinderInfo, rhs)
443 extendEnvGivenInlining :: SimplEnv -> Id -> BinderInfo -> InExpr -> SimplEnv
444 extendEnvGivenInlining env@(SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
446 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env con_apps
448 new_out_id_env = addToUFM out_id_env id (id, occ_info, InUnfolding env rhs)
451 %************************************************************************
453 \subsubsection{The @ConAppMap@ type}
455 %************************************************************************
457 The @ConAppMap@ maps applications of constructors (to value atoms)
458 back to an association list that says "if the constructor was applied
459 to one of these lists-of-Types, then this OutId is your man (in a
460 non-gender-specific sense)". I.e., this is a reversed mapping for
461 (part of) the main OutIdEnv
464 type ConAppMap = FiniteMap UnfoldConApp [([Type], OutId)]
467 = UCA OutId -- data constructor
468 [OutArg] -- *value* arguments; see use below
472 nullConApps = emptyFM
474 extendConApps con_apps id (Con con args)
475 = addToFM_C (\old new -> new++old) con_apps (UCA con val_args) [(ty_args,id)]
477 val_args = filter isValArg args -- Literals and Ids
478 ty_args = [ty | TyArg ty <- args] -- Just types
480 extendConApps con_apps id other_rhs = con_apps
484 lookForConstructor (SimplEnv _ _ _ _ _ con_apps) con args
485 = case lookupFM con_apps (UCA con val_args) of
488 Just assocs -> case [id | (tys, id) <- assocs,
489 and (zipWith eqTy tys ty_args)]
494 val_args = filter isValArg args -- Literals and Ids
495 ty_args = [ty | TyArg ty <- args] -- Just types
499 NB: In @lookForConstructor@ we used (before Apr 94) to have a special case
500 for nullary constructors, but now we only do constructor re-use in
501 let-bindings the special case isn't necessary any more.
504 = -- Don't re-use nullary constructors; it's a waste. Consider
512 -- Here the False in the second case will get replace by "a", hardly
518 The main thing about @UnfoldConApp@ is that it has @Ord@ defined on
519 it, so we can use it for a @FiniteMap@ key.
522 instance Eq UnfoldConApp where
523 a == b = case (a `cmp` b) of { EQ_ -> True; _ -> False }
524 a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
526 instance Ord UnfoldConApp where
527 a <= b = case (a `cmp` b) of { LT_ -> True; EQ_ -> True; GT__ -> False }
528 a < b = case (a `cmp` b) of { LT_ -> True; EQ_ -> False; GT__ -> False }
529 a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True; GT__ -> True }
530 a > b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True }
531 _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
533 instance Ord3 UnfoldConApp where
536 cmp_app (UCA c1 as1) (UCA c2 as2)
537 = cmp c1 c2 `thenCmp` cmpList cmp_arg as1 as2
539 -- ToDo: make an "instance Ord3 CoreArg"???
541 cmp_arg (VarArg x) (VarArg y) = x `cmp` y
542 cmp_arg (LitArg x) (LitArg y) = x `cmp` y
543 cmp_arg (TyArg x) (TyArg y) = panic# "SimplEnv.cmp_app:TyArgs"
544 cmp_arg (UsageArg x) (UsageArg y) = panic# "SimplEnv.cmp_app:UsageArgs"
546 | tag x _LT_ tag y = LT_
549 tag (VarArg _) = ILIT(1)
550 tag (LitArg _) = ILIT(2)
551 tag (TyArg _) = panic# "SimplEnv.cmp_app:TyArg"
552 tag (UsageArg _) = panic# "SimplEnv.cmp_app:UsageArg"
556 @extendUnfoldEnvGivenRhs@ records in the UnfoldEnv info about the RHS
557 of a new binding. There is a horrid case we have to take care about,
558 due to Andr\'e Santos:
560 type Array_type b = Array Int b;
561 type Descr_type = (Int,Int);
563 tabulate :: (Int -> x) -> Descr_type -> Array_type x;
564 tabulate f (l,u) = listArray (l,u) [f i | i <- [l..u]];
568 f_aareorder::(Array_type Int) -> (Array_type t1) -> Array_type t1;
569 f_aareorder a_index a_ar=
571 f_aareorder' a_i= a_ar ! (a_index ! a_i)
572 } in tabulate f_aareorder' (bounds a_ar);
573 r_index=tabulate ((+) 1) (1,1);
574 arr = listArray (1,1) a_xs;
575 arg = f_aareorder r_index arr
578 Now, when the RHS of arg gets simplified, we inline f_aareorder to get
580 arg = let f_aareorder' a_i = arr ! (r_index ! a_i)
581 in tabulate f_aareorder' (bounds arr)
583 Note that r_index is not inlined, because it was bound to a_index which
584 occurs inside a lambda.
586 Alas, if elems is inlined, so that (elems arg) becomes (case arg of ...),
587 then arg is inlined. IF WE USE THE NEW VERSION OF arg, and re-occurrence
588 analyse it, we won't spot the inside-lambda property of r_index, so r_index
589 will get inlined inside the lambda. AARGH.
591 Solution: when we occurrence-analyse the new RHS we have to go back
592 and modify the info recorded in the UnfoldEnv for the free vars
593 of the RHS. In the example we'd go back and record that r_index is now used
597 extendEnvGivenNewRhs :: SimplEnv -> OutId -> OutExpr -> SimplEnv
598 extendEnvGivenNewRhs env out_id rhs
599 = extendEnvGivenBinding env noBinderInfo out_id rhs
601 extendEnvGivenBinding :: SimplEnv -> BinderInfo -> OutId -> OutExpr -> SimplEnv
602 extendEnvGivenBinding env@(SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
604 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env new_con_apps
606 new_out_id_env | okToInline (whnfOrBottom form)
607 (couldBeSmallEnoughToInline guidance)
609 = out_id_env_with_unfolding
612 -- Don't bother to extend the OutIdEnv unless there is some possibility
613 -- that the thing might be inlined. We check this by calling okToInline suitably.
615 new_con_apps = _scc_ "eegnr.conapps"
616 extendConApps con_apps out_id rhs
618 -- Modify the occ info for rhs's interesting free variables.
619 out_id_env_with_unfolding = _scc_ "eegnr.modify_occ"
620 foldl modifyOccInfo env1 full_fv_occ_info
621 -- NB: full_fv_occ_info *combines* the occurrence of the current binder
622 -- with the occurrences of its RHS's free variables. That's to take
624 -- let a = \x -> BIG in
626 -- in ...b...b...b...
627 -- Here "a" occurs exactly once. "b" simplifies to a small value.
628 -- So "b" will be inlined at each call site, and there's a good chance
629 -- that "a" will too. So we'd better modify "a"s occurrence info to
630 -- record the fact that it can now occur many times by virtue that "b" can.
632 full_fv_occ_info = _scc_ "eegnr.full_fv"
633 [ (uniq, fv_occ `andBinderInfo` occ_info)
634 | (uniq, fv_occ) <- ufmToList fv_occ_info
637 -- Add an unfolding and rhs_info for the new Id.
638 -- If the out_id is already in the OutIdEnv (which can happen if
639 -- the call to extendEnvGivenBinding is from extendEnvGivenNewRhs)
640 -- then just replace the unfolding, leaving occurrence info alone.
641 env1 = _scc_ "eegnr.modify_out"
642 addToUFM_C modifyOutEnvItem out_id_env out_id
643 (out_id, occ_info, rhs_info)
645 -- Occurrence-analyse the RHS
646 -- The "interesting" free variables we want occurrence info for are those
647 -- in the OutIdEnv that have only a single occurrence right now.
648 (fv_occ_info, template) = _scc_ "eegnr.occ-anal"
649 occurAnalyseExpr is_interesting rhs
651 is_interesting v = _scc_ "eegnr.mkidset"
652 case lookupIdEnv out_id_env v of
653 Just (_, occ, _) -> isOneOcc occ
656 -- Compute unfolding details
657 rhs_info = OutUnfolding unf_cc (SimpleUnfolding form guidance template)
658 form = _scc_ "eegnr.form_sum"
660 guidance = _scc_ "eegnr.guidance"
661 mkSimplUnfoldingGuidance chkr out_id rhs
663 -- Compute cost centre for thing
664 unf_cc | noCostCentreAttached expr_cc = encl_cc
665 | otherwise = expr_cc
667 expr_cc = coreExprCc rhs