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,
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,
54 BinderInfo(..){-instances, too-}, FunOrArg, DuplicationDanger, InsideSCC
56 import CmdLineOpts ( switchIsOn, intSwitchSet, opt_UnfoldingCreationThreshold,
57 SimplifierSwitch(..), SwitchResult(..)
60 import CoreUnfold ( mkFormSummary, okToInline, couldBeSmallEnoughToInline,
61 Unfolding(..), UfExpr, RdrName,
62 SimpleUnfolding(..), FormSummary(..),
63 calcUnfoldingGuidance, UnfoldingGuidance(..)
65 import CoreUtils ( coreExprCc, unTagBinders )
66 import CostCentre ( CostCentre, subsumedCosts, noCostCentreAttached )
67 import FiniteMap -- lots of things
68 import Id ( idType, getIdUnfolding, getIdStrictness, idWantsToBeINLINEd,
69 applyTypeEnvToId, getInlinePragma,
70 nullIdEnv, growIdEnvList, rngIdEnv, lookupIdEnv,
71 addOneToIdEnv, modifyIdEnv, mkIdSet, modifyIdEnv_Directly,
72 SYN_IE(IdEnv), SYN_IE(IdSet), GenId, SYN_IE(Id) )
73 import Literal ( isNoRepLit, Literal{-instances-} )
74 import Maybes ( maybeToBool, expectJust )
75 import Name ( isLocallyDefined )
76 import OccurAnal ( occurAnalyseExpr )
77 import Outputable ( PprStyle(..), Outputable(..){-instances-} )
78 import PprCore -- various instances
79 import PprType ( GenType, GenTyVar )
81 import Type ( eqTy, applyTypeEnvToTy, SYN_IE(Type) )
82 import TyVar ( nullTyVarEnv, addOneToTyVarEnv, growTyVarEnvList,
83 SYN_IE(TyVarEnv), GenTyVar{-instance Eq-} ,
86 import Unique ( Unique{-instance Outputable-} )
87 import UniqFM ( addToUFM_C, ufmToList, Uniquable(..)
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 SimplEnv -- Un-simplified unfolding
375 SimpleUnfolding -- (need to snag envts therefore)
377 | OutUnfolding CostCentre
378 SimpleUnfolding -- Already-simplified unfolding
380 lookupOutIdEnv :: SimplEnv -> OutId -> Maybe (OutId,BinderInfo,RhsInfo)
381 lookupOutIdEnv (SimplEnv _ _ _ _ out_id_env _) id = lookupIdEnv out_id_env id
383 lookupRhsInfo :: SimplEnv -> OutId -> RhsInfo
385 = case lookupOutIdEnv env id of
386 Just (_,_,info) -> info
389 modifyOutEnvItem :: (OutId, BinderInfo, RhsInfo)
390 -> (OutId, BinderInfo, RhsInfo)
391 -> (OutId, BinderInfo, RhsInfo)
392 modifyOutEnvItem (id, occ, info1) (_, _, info2)
393 = case (info1, info2) of
394 (OtherLit ls1, OtherLit ls2) -> (id,occ, OtherLit (ls1++ls2))
395 (OtherCon cs1, OtherCon cs2) -> (id,occ, OtherCon (cs1++cs2))
396 (_, NoRhsInfo) -> (id,occ, info1)
397 other -> (id,occ, info2)
402 isEvaluated :: RhsInfo -> Bool
403 isEvaluated (OtherLit _) = True
404 isEvaluated (OtherCon _) = True
405 isEvaluated (InUnfolding _ (SimpleUnfolding ValueForm _ expr)) = True
406 isEvaluated (OutUnfolding _ (SimpleUnfolding ValueForm _ expr)) = True
407 isEvaluated other = False
413 mkSimplUnfoldingGuidance chkr out_id rhs
414 = calcUnfoldingGuidance (getInlinePragma out_id) opt_UnfoldingCreationThreshold rhs
416 extendEnvGivenRhsInfo :: SimplEnv -> OutId -> BinderInfo -> RhsInfo -> SimplEnv
417 extendEnvGivenRhsInfo env@(SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
418 out_id occ_info rhs_info
419 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env con_apps
421 new_out_id_env = addToUFM_C modifyOutEnvItem out_id_env out_id
422 (out_id, occ_info, rhs_info)
427 modifyOccInfo out_id_env (uniq, new_occ)
428 = modifyIdEnv_Directly modify_fn out_id_env uniq
430 modify_fn (id,occ,rhs) = (id, orBinderInfo occ new_occ, rhs)
432 markDangerousOccs (SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps) atoms
433 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env con_apps
435 new_out_id_env = foldl (modifyIdEnv modify_fn) out_id_env [v | VarArg v <- atoms]
436 modify_fn (id,occ,rhs) = (id, noBinderInfo, rhs)
441 %************************************************************************
443 \subsubsection{The @ConAppMap@ type}
445 %************************************************************************
447 The @ConAppMap@ maps applications of constructors (to value atoms)
448 back to an association list that says "if the constructor was applied
449 to one of these lists-of-Types, then this OutId is your man (in a
450 non-gender-specific sense)". I.e., this is a reversed mapping for
451 (part of) the main OutIdEnv
454 type ConAppMap = FiniteMap UnfoldConApp [([Type], OutId)]
457 = UCA OutId -- data constructor
458 [OutArg] -- *value* arguments; see use below
462 nullConApps = emptyFM
464 extendConApps con_apps id (Con con args)
465 = addToFM_C (\old new -> new++old) con_apps (UCA con val_args) [(ty_args,id)]
467 val_args = filter isValArg args -- Literals and Ids
468 ty_args = [ty | TyArg ty <- args] -- Just types
470 extendConApps con_apps id other_rhs = con_apps
474 lookForConstructor (SimplEnv _ _ _ _ _ con_apps) con args
475 = case lookupFM con_apps (UCA con val_args) of
478 Just assocs -> case [id | (tys, id) <- assocs,
479 and (zipWith eqTy tys ty_args)]
484 val_args = filter isValArg args -- Literals and Ids
485 ty_args = [ty | TyArg ty <- args] -- Just types
489 NB: In @lookForConstructor@ we used (before Apr 94) to have a special case
490 for nullary constructors, but now we only do constructor re-use in
491 let-bindings the special case isn't necessary any more.
494 = -- Don't re-use nullary constructors; it's a waste. Consider
502 -- Here the False in the second case will get replace by "a", hardly
508 The main thing about @UnfoldConApp@ is that it has @Ord@ defined on
509 it, so we can use it for a @FiniteMap@ key.
512 instance Eq UnfoldConApp where
513 a == b = case (a `cmp` b) of { EQ_ -> True; _ -> False }
514 a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
516 instance Ord UnfoldConApp where
517 a <= b = case (a `cmp` b) of { LT_ -> True; EQ_ -> True; GT__ -> False }
518 a < b = case (a `cmp` b) of { LT_ -> True; EQ_ -> False; GT__ -> False }
519 a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True; GT__ -> True }
520 a > b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True }
521 _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
523 instance Ord3 UnfoldConApp where
526 cmp_app (UCA c1 as1) (UCA c2 as2)
527 = cmp c1 c2 `thenCmp` cmpList cmp_arg as1 as2
529 -- ToDo: make an "instance Ord3 CoreArg"???
531 cmp_arg (VarArg x) (VarArg y) = x `cmp` y
532 cmp_arg (LitArg x) (LitArg y) = x `cmp` y
533 cmp_arg (TyArg x) (TyArg y) = panic# "SimplEnv.cmp_app:TyArgs"
534 cmp_arg (UsageArg x) (UsageArg y) = panic# "SimplEnv.cmp_app:UsageArgs"
536 | tag x _LT_ tag y = LT_
539 tag (VarArg _) = ILIT(1)
540 tag (LitArg _) = ILIT(2)
541 tag (TyArg _) = panic# "SimplEnv.cmp_app:TyArg"
542 tag (UsageArg _) = panic# "SimplEnv.cmp_app:UsageArg"
549 ============================ OLD ================================
550 This version was used when we use the *simplified* RHS of a
551 let as the thing's unfolding. The has the nasty property described
552 in the following comments. Much worse, it can fail to terminate
553 on recursive things. Consider
555 letrec f = \x -> let z = f x' in ...
562 If we bind n to its *simplified* RHS, we then *re-simplify* it when
563 we inline n. Then we may well inline f; and then the same thing
567 @extendUnfoldEnvGivenRhs@ records in the UnfoldEnv info about the RHS
568 of a new binding. There is a horrid case we have to take care about,
569 due to Andr\'e Santos:
571 type Array_type b = Array Int b;
572 type Descr_type = (Int,Int);
574 tabulate :: (Int -> x) -> Descr_type -> Array_type x;
575 tabulate f (l,u) = listArray (l,u) [f i | i <- [l..u]];
579 f_aareorder::(Array_type Int) -> (Array_type t1) -> Array_type t1;
580 f_aareorder a_index a_ar=
582 f_aareorder' a_i= a_ar ! (a_index ! a_i)
583 } in tabulate f_aareorder' (bounds a_ar);
584 r_index=tabulate ((+) 1) (1,1);
585 arr = listArray (1,1) a_xs;
586 arg = f_aareorder r_index arr
589 Now, when the RHS of arg gets simplified, we inline f_aareorder to get
591 arg = let f_aareorder' a_i = arr ! (r_index ! a_i)
592 in tabulate f_aareorder' (bounds arr)
594 Note that r_index is not inlined, because it was bound to a_index which
595 occurs inside a lambda.
597 Alas, if elems is inlined, so that (elems arg) becomes (case arg of ...),
598 then arg is inlined. IF WE USE THE NEW VERSION OF arg, and re-occurrence
599 analyse it, we won't spot the inside-lambda property of r_index, so r_index
600 will get inlined inside the lambda. AARGH.
602 Solution: when we occurrence-analyse the new RHS we have to go back
603 and modify the info recorded in the UnfoldEnv for the free vars
604 of the RHS. In the example we'd go back and record that r_index is now used
608 extendEnvGivenNewRhs :: SimplEnv -> OutId -> OutExpr -> SimplEnv
609 extendEnvGivenNewRhs env out_id rhs
610 = extendEnvGivenBinding env noBinderInfo out_id rhs
612 extendEnvGivenBinding :: SimplEnv -> BinderInfo -> OutId -> OutExpr -> SimplEnv
613 extendEnvGivenBinding env@(SimplEnv chkr encl_cc ty_env in_id_env out_id_env con_apps)
615 = SimplEnv chkr encl_cc ty_env in_id_env new_out_id_env new_con_apps
617 new_out_id_env | okToInline form occ_info (couldBeSmallEnoughToInline guidance)
618 = out_id_env_with_unfolding
621 -- Don't bother to extend the OutIdEnv unless there is some possibility
622 -- that the thing might be inlined. We check this by calling okToInline suitably.
624 new_con_apps = _scc_ "eegnr.conapps"
625 extendConApps con_apps out_id rhs
627 -- Modify the occ info for rhs's interesting free variables.
628 out_id_env_with_unfolding = _scc_ "eegnr.modify_occ"
629 foldl modifyOccInfo env1 full_fv_occ_info
630 -- NB: full_fv_occ_info *combines* the occurrence of the current binder
631 -- with the occurrences of its RHS's free variables. That's to take
633 -- let a = \x -> BIG in
635 -- in ...b...b...b...
636 -- Here "a" occurs exactly once. "b" simplifies to a small value.
637 -- So "b" will be inlined at each call site, and there's a good chance
638 -- that "a" will too. So we'd better modify "a"s occurrence info to
639 -- record the fact that it can now occur many times by virtue that "b" can.
641 full_fv_occ_info = _scc_ "eegnr.full_fv"
642 [ (uniq, fv_occ `andBinderInfo` occ_info)
643 | (uniq, fv_occ) <- ufmToList fv_occ_info
646 -- Add an unfolding and rhs_info for the new Id.
647 -- If the out_id is already in the OutIdEnv (which can happen if
648 -- the call to extendEnvGivenBinding is from extendEnvGivenNewRhs)
649 -- then just replace the unfolding, leaving occurrence info alone.
650 env1 = _scc_ "eegnr.modify_out"
651 addToUFM_C modifyOutEnvItem out_id_env out_id
652 (out_id, occ_info, rhs_info)
654 -- Occurrence-analyse the RHS
655 -- The "interesting" free variables we want occurrence info for are those
656 -- in the OutIdEnv that have only a single occurrence right now.
657 (fv_occ_info, template) = _scc_ "eegnr.occ-anal"
658 occurAnalyseExpr is_interesting rhs
660 is_interesting v = _scc_ "eegnr.mkidset"
661 case lookupIdEnv out_id_env v of
662 Just (_, OneOcc _ _ _ _ _, _) -> True
665 -- Compute unfolding details
666 rhs_info = OutUnfolding unf_cc (SimpleUnfolding form guidance template)
667 form = _scc_ "eegnr.form_sum"
669 guidance = _scc_ "eegnr.guidance"
670 mkSimplUnfoldingGuidance chkr out_id rhs
672 -- Compute cost centre for thing
673 unf_cc | noCostCentreAttached expr_cc = encl_cc
674 | otherwise = expr_cc
676 expr_cc = coreExprCc rhs