2 % (c) The AQUA Project, Glasgow University, 1993-1996
4 \section[SimplEnv]{Environment stuff for the simplifier}
7 #include "HsVersions.h"
11 pprSimplEnv, -- debugging only
13 replaceInEnvs, nullInEnvs,
15 extendTyEnv, extendTyEnvList,
18 extendIdEnvWithAtom, extendIdEnvWithAtomList,
19 extendIdEnvWithInlining,
20 extendIdEnvWithClone, extendIdEnvWithClones,
23 extendUnfoldEnvGivenRhs,
24 extendUnfoldEnvGivenFormDetails,
25 extendUnfoldEnvGivenConstructor,
27 lookupUnfolding, filterUnfoldEnvForInlines,
29 getSwitchChecker, switchIsSet,
35 SimplEnv, EnclosingCcDetails(..),
36 InIdEnv(..), IdVal(..), InTypeEnv(..),
37 UnfoldEnv, UnfoldItem, UnfoldConApp,
39 InId(..), InBinder(..), InBinding(..), InType(..),
40 OutId(..), OutBinder(..), OutBinding(..), OutType(..),
42 InExpr(..), InAlts(..), InDefault(..), InArg(..),
43 OutExpr(..), OutAlts(..), OutDefault(..), OutArg(..)
45 -- and to make the interface self-sufficient...
50 import SmplLoop -- breaks the MagicUFs / SimplEnv loop
52 import BinderInfo ( BinderInfo{-instances-} )
53 import CmdLineOpts ( switchIsOn, intSwitchSet, SimplifierSwitch(..), SwitchResult )
55 import CoreUnfold ( UnfoldingDetails(..), mkGenForm, modifyUnfoldingDetails,
56 calcUnfoldingGuidance, UnfoldingGuidance(..),
57 mkFormSummary, FormSummary
59 import FiniteMap -- lots of things
60 import Id ( idType, getIdUnfolding, getIdStrictness,
61 nullIdEnv, growIdEnvList, rngIdEnv, lookupIdEnv,
62 addOneToIdEnv, modifyIdEnv,
63 IdEnv(..), IdSet(..), GenId )
64 import IdInfo ( StrictnessInfo )
65 import Literal ( isNoRepLit, Literal{-instances-} )
66 import Outputable ( Outputable(..){-instances-} )
67 import PprCore -- various instances
68 import PprStyle ( PprStyle(..) )
69 import PprType ( GenType, GenTyVar )
71 import Type ( getAppDataTyCon )
72 import TyVar ( nullTyVarEnv, addOneToIdEnv, addOneToTyVarEnv,
74 TyVarEnv(..), GenTyVar )
75 import Unique ( Unique )
76 import UniqSet -- lots of things
77 import Usage ( UVar(..), GenUsage{-instances-} )
78 import Util ( zipEqual, panic, assertPanic )
80 type TypeEnv = TyVarEnv Type
81 addToUFM_Directly = panic "addToUFM_Directly (SimplEnv)"
82 applyTypeEnvToId = panic "applyTypeEnvToId (SimplEnv)"
83 applyTypeEnvToTy = panic "applyTypeEnvToTy (SimplEnv)"
84 bottomIsGuaranteed = panic "bottomIsGuaranteed (SimplEnv)"
85 cmpType = panic "cmpType (SimplEnv)"
86 exprSmallEnoughToDup = panic "exprSmallEnoughToDup (SimplEnv)"
87 lookupDirectlyUFM = panic "lookupDirectlyUFM (SimplEnv)"
88 manifestlyWHNF = panic "manifestlyWHNF (SimplEnv)"
89 occurAnalyseExpr = panic "occurAnalyseExpr (SimplEnv)"
90 oneSafeOcc = panic "oneSafeOcc (SimplEnv)"
91 oneTextualOcc = panic "oneTextualOcc (SimplEnv)"
92 simplIdWantsToBeINLINEd = panic "simplIdWantsToBeINLINEd (SimplEnv)"
93 uNFOLDING_CREATION_THRESHOLD = panic "uNFOLDING_CREATION_THRESHOLD (SimplEnv)"
94 ufmToList = panic "ufmToList (SimplEnv)"
97 %************************************************************************
99 \subsection[Simplify-types]{Type declarations}
101 %************************************************************************
104 %************************************************************************
106 \subsubsection{The @SimplEnv@ type}
108 %************************************************************************
111 INVARIANT: we assume {\em no shadowing}. (ToDo: How can we ASSERT
112 this? WDP 94/06) This allows us to neglect keeping everything paired
113 with its static environment.
115 The environment contains bindings for all
117 {\em locally-defined}
120 For such things, any unfolding is found in the environment, not in the
121 Id. Unfoldings in the Id itself are used only for imported things
122 (otherwise we get trouble because we have to simplify the unfoldings
123 inside the Ids, etc.).
130 EnclosingCcDetails -- the enclosing cost-centre (when profiling)
132 InTypeEnv -- For cloning types
133 -- Domain is all in-scope type variables
141 -- (Could omit the exported top-level guys,
142 -- since their names mustn't change; and ditto
143 -- the non-exported top-level guys which you
144 -- don't want to macro-expand, since their
145 -- names need not change.)
149 UnfoldEnv -- Domain is any *OutIds*, including imports
150 -- where we know something more than the
151 -- interface file tells about their value (see
154 nullSimplEnv :: SwitchChecker -> SimplEnv
157 = SimplEnv sw_chkr NoEnclosingCcDetails nullTyVarEnv nullIdEnv null_unfold_env
159 pprSimplEnv (SimplEnv _ _ ty_env id_env (UFE unfold_env _ _))
161 ppStr "** Type Env ** ????????", -- ppr PprDebug ty_env,
162 ppSP, ppStr "** Id Env ** ?????????",
163 -- ppAboves [ pp_id_entry x | x <- getIdEnvMapping id_env ],
164 ppSP, ppStr "** Unfold Env **",
165 ppAboves [ pp_uf_entry x | x <- rngIdEnv unfold_env ]
168 pp_id_entry (v, idval)
169 = ppCat [ppr PprDebug v, ppStr "=>",
171 InlineIt _ _ e -> ppCat [ppStr "InlineIt:", ppr PprDebug e]
172 ItsAnAtom a -> ppCat [ppStr "Atom:", ppr PprDebug a]
175 pp_uf_entry (UnfoldItem v form encl_cc)
176 = ppCat [ppr PprDebug v, ppStr "=>",
178 NoUnfoldingDetails -> ppStr "NoUnfoldingDetails"
179 LitForm l -> ppCat [ppStr "Lit:", ppr PprDebug l]
180 OtherLitForm ls -> ppCat [ppStr "Other lit:", ppInterleave (ppStr ", ")
181 [ppr PprDebug l | l <- ls]]
182 ConForm c a -> ppCat [ppStr "Con:", ppr PprDebug c, ppr PprDebug a]
183 OtherConForm cs -> ppCat [ppStr "OtherCon:", ppInterleave (ppStr ", ")
184 [ppr PprDebug c | c <- cs]]
185 GenForm t w e g -> ppCat [ppStr "UF:", ppr PprDebug t, ppr PprDebug w,
186 ppr PprDebug g, ppr PprDebug e]
187 MagicForm s _ -> ppCat [ppStr "Magic:", ppr PprDebug s]
191 %************************************************************************
193 \subsubsection{The @IdVal@ type (for the ``IdEnv'')}
195 %************************************************************************
197 The unfoldings for imported things are mostly kept within the Id
198 itself; nevertheless, they {\em can} get into the @UnfoldEnv@. For
199 example, suppose \tr{x} is imported, and we have
204 Then within \tr{<body>}, we know that \tr{x} is a pair with components
208 type InIdEnv = IdEnv IdVal -- Maps InIds to their value
211 = InlineIt InIdEnv InTypeEnv InExpr
212 -- No binding of the Id is left;
213 -- You *have* to replace any occurences
214 -- of the id with this expression.
215 -- Rather like a macro, really
216 -- NB: the InIdEnv/InTypeEnv is necessary to prevent
217 -- name caputure. Consider:
222 -- If x gets an InlineIt, we must remember
223 -- the correct binding for y.
225 | ItsAnAtom OutArg -- Used either (a) to record the cloned Id
226 -- or (b) if the orig defn is a let-binding, and
227 -- the RHS of the let simplifies to an atom,
228 -- we just bind the variable to that atom, and
232 %************************************************************************
234 \subsubsection{The @UnfoldEnv@ type}
236 %************************************************************************
238 The @UnfoldEnv@ contains information about the value of some of the
239 in-scope identifiers. It obeys the following invariant:
241 If the @UnfoldEnv@ contains information, it is safe to use it!
243 In particular, if the @UnfoldEnv@ contains details of an unfolding of
244 an Id, then it's safe to use the unfolding. If, for example, the Id
245 is used many times, then its unfolding won't be put in the UnfoldEnv
248 The @UnfoldEnv@ (used to be [WDP 94/06]) a simple association list
249 because (a)~it's small, and (b)~we need to search its {\em range} as
253 data UnfoldItem -- a glorified triple...
254 = UnfoldItem OutId -- key: used in lookForConstructor
255 UnfoldingDetails -- for that Id
256 EnclosingCcDetails -- so that if we do an unfolding,
257 -- we can "wrap" it in the CC
258 -- that was in force.
260 data UnfoldConApp -- yet another glorified triple
261 = UCA OutId -- same fields as ConForm
264 data UnfoldEnv -- yup, a glorified triple...
265 = UFE (IdEnv UnfoldItem) -- Maps an OutId => its UnfoldItem
266 IdSet -- The Ids in the domain of the env
267 -- which have details (GenForm True ...)
268 -- i.e., they claim they are duplicatable.
269 -- These are the ones we have to worry
270 -- about when adding new items to the
272 (FiniteMap UnfoldConApp OutId)
273 -- Maps applications of constructors (to
274 -- types & atoms) back to OutIds that are
275 -- bound to them; i.e., this is a reversed
276 -- mapping for (part of) the main IdEnv
279 null_unfold_env = UFE nullIdEnv emptyUniqSet emptyFM
282 The @UnfoldEnv@ type. We expect on the whole that an @UnfoldEnv@ will
283 be small, because it contains bindings only for those things whose
284 form or unfolding is known. Basically it maps @Id@ to their
285 @UnfoldingDetails@ (and @EnclosingCcDetails@---boring...), but we also
286 need to search it associatively, to look for @Id@s which have a given
289 We implement it with @IdEnvs@, possibly overkill, but sometimes these
290 things silently grow quite big.... Here are some local functions used
291 elsewhere in the module:
294 grow_unfold_env :: UnfoldEnv -> OutId -> UnfoldingDetails -> EnclosingCcDetails -> UnfoldEnv
295 lookup_unfold_env :: UnfoldEnv -> OutId -> UnfoldingDetails
296 lookup_unfold_env_encl_cc
297 :: UnfoldEnv -> OutId -> EnclosingCcDetails
299 grow_unfold_env full_u_env id NoUnfoldingDetails _ = full_u_env
301 grow_unfold_env (UFE u_env interesting_ids con_apps) id
302 uf_details@(GenForm True _ _ _) encl_cc
303 -- Only interested in Ids which have a "dangerous" unfolding; that is
304 -- one that claims to have a single occurrence.
305 = UFE (addOneToIdEnv u_env id (UnfoldItem id uf_details encl_cc))
306 (interesting_ids `unionUniqSets` singletonUniqSet id)
309 grow_unfold_env (UFE u_env interesting_ids con_apps) id uf_details encl_cc
310 = UFE (addOneToIdEnv u_env id (UnfoldItem id uf_details encl_cc))
317 -> case (lookupFM con_apps entry) of
318 Just _ -> con_apps -- unchanged; we hang onto what we have
319 Nothing -> addToFM con_apps entry id
321 entry = UCA con vargs
323 not_a_constructor -> con_apps -- unchanged
325 addto_unfold_env (UFE u_env interesting_ids con_apps) extra_items
326 = ASSERT(not (any constructor_form_in_those extra_items))
327 -- otherwise, we'd need to change con_apps
328 UFE (growIdEnvList u_env extra_items) interesting_ids con_apps
330 constructor_form_in_those (_, UnfoldItem _ (ConForm _ _) _) = True
331 constructor_form_in_those _ = False
333 rng_unfold_env (UFE u_env _ _) = rngIdEnv u_env
335 get_interesting_ids (UFE _ interesting_ids _) = interesting_ids
337 foldr_unfold_env fun (UFE u_env interesting_ids con_apps) stuff
338 = UFE (foldr fun u_env stuff) interesting_ids con_apps
340 lookup_unfold_env (UFE u_env _ _) id
341 = case (lookupIdEnv u_env id) of
342 Nothing -> NoUnfoldingDetails
343 Just (UnfoldItem _ uf _) -> uf
345 lookup_unfold_env_encl_cc (UFE u_env _ _) id
346 = case (lookupIdEnv u_env id) of
347 Nothing -> NoEnclosingCcDetails
348 Just (UnfoldItem _ _ encl_cc) -> encl_cc
350 lookup_conapp (UFE _ _ con_apps) con args
351 = lookupFM con_apps (UCA con args)
353 modify_unfold_env (UFE u_env interesting_ids con_apps) zapper id
354 = UFE (modifyIdEnv u_env zapper id) interesting_ids con_apps
356 -- If the current binding claims to be a "unique" one, then
358 modifyItem :: Bool -> BinderInfo -> UnfoldItem -> UnfoldItem
360 modifyItem ok_to_dup occ_info (UnfoldItem id details enc_cc)
361 = UnfoldItem id (modifyUnfoldingDetails ok_to_dup occ_info details) enc_cc
364 The main thing about @UnfoldConApp@ is that it has @Ord@ defined on
365 it, so we can use it for a @FiniteMap@ key.
367 instance Eq UnfoldConApp where
368 a == b = case cmp_app a b of { EQ_ -> True; _ -> False }
369 a /= b = case cmp_app a b of { EQ_ -> False; _ -> True }
371 instance Ord UnfoldConApp where
372 a <= b = case cmp_app a b of { LT_ -> True; EQ_ -> True; GT__ -> False }
373 a < b = case cmp_app a b of { LT_ -> True; EQ_ -> False; GT__ -> False }
374 a >= b = case cmp_app a b of { LT_ -> False; EQ_ -> True; GT__ -> True }
375 a > b = case cmp_app a b of { LT_ -> False; EQ_ -> False; GT__ -> True }
376 _tagCmp a b = case cmp_app a b of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
378 instance Ord3 UnfoldConApp where
381 cmp_app (UCA c1 as1) (UCA c2 as2)
382 = case (c1 `cmp` c2) of
385 _ -> cmp_lists cmp_atom as1 as2
387 cmp_lists cmp_item [] [] = EQ_
388 cmp_lists cmp_item (x:xs) [] = GT_
389 cmp_lists cmp_item [] (y:ys) = LT_
390 cmp_lists cmp_item (x:xs) (y:ys)
391 = case cmp_item x y of { EQ_ -> cmp_lists cmp_item xs ys; other -> other }
393 cmp_atom (VarArg x) (VarArg y) = x `cmp` y
394 cmp_atom (VarArg _) _ = LT_
395 cmp_atom (LitArg x) (LitArg y)
396 = case _tagCmp x y of { _LT -> LT_; _EQ -> EQ_; GT__ -> GT_ }
397 cmp_atom (LitArg _) _ = GT_
400 %************************************************************************
402 \subsubsection{The @EnclosingCcDetails@ type}
404 %************************************************************************
407 data EnclosingCcDetails
408 = NoEnclosingCcDetails
409 | EnclosingCC CostCentre
412 %************************************************************************
414 \subsubsection{The ``InXXX'' and ``OutXXX'' type synonyms}
416 %************************************************************************
419 type InId = Id -- Not yet cloned
420 type InBinder = (InId, BinderInfo)
421 type InType = Type -- Ditto
422 type InBinding = SimplifiableCoreBinding
423 type InExpr = SimplifiableCoreExpr
424 type InAlts = SimplifiableCoreCaseAlts
425 type InDefault = SimplifiableCoreCaseDefault
426 type InArg = SimplifiableCoreArg
428 type OutId = Id -- Cloned
430 type OutType = Type -- Cloned
431 type OutBinding = CoreBinding
432 type OutExpr = CoreExpr
433 type OutAlts = CoreCaseAlts
434 type OutDefault = CoreCaseDefault
435 type OutArg = CoreArg
440 type SwitchChecker = SimplifierSwitch -> SwitchResult
443 %************************************************************************
445 \subsection{@SimplEnv@ handling}
447 %************************************************************************
449 %************************************************************************
451 \subsubsection{Command-line switches}
453 %************************************************************************
456 getSwitchChecker :: SimplEnv -> SwitchChecker
457 getSwitchChecker (SimplEnv chkr _ _ _ _) = chkr
459 switchIsSet :: SimplEnv -> SimplifierSwitch -> Bool
460 switchIsSet (SimplEnv chkr _ _ _ _) switch
461 = switchIsOn chkr switch
464 %************************************************************************
466 \subsubsection{The ``enclosing cost-centre''}
468 %************************************************************************
471 setEnclosingCC :: SimplEnv -> EnclosingCcDetails -> SimplEnv
473 setEnclosingCC (SimplEnv chkr _ ty_env id_env unfold_env) encl_cc
474 = SimplEnv chkr encl_cc ty_env id_env unfold_env
477 %************************************************************************
479 \subsubsection{The @TypeEnv@ part}
481 %************************************************************************
484 type InTypeEnv = TypeEnv -- Maps InTyVars to OutTypes
486 extendTyEnv :: SimplEnv -> TyVar -> Type -> SimplEnv
487 extendTyEnv (SimplEnv chkr encl_cc ty_env id_env unfold_env) tyvar ty
488 = SimplEnv chkr encl_cc new_ty_env id_env unfold_env
490 new_ty_env = addOneToTyVarEnv ty_env tyvar ty
492 extendTyEnvList :: SimplEnv -> [(TyVar,Type)] -> SimplEnv
493 extendTyEnvList (SimplEnv chkr encl_cc ty_env id_env unfold_env) pairs
494 = SimplEnv chkr encl_cc new_ty_env id_env unfold_env
496 new_ty_env = growTyVarEnvList ty_env pairs
498 simplTy (SimplEnv _ _ ty_env _ _) ty = applyTypeEnvToTy ty_env ty
500 simplTyInId (SimplEnv _ _ ty_env _ _) id = applyTypeEnvToId ty_env id
503 @replaceInEnvs@ is used to install saved type and id envs
504 when pulling an un-simplified expression out of the environment, which
505 was saved with its environments.
508 nullInEnvs = (nullTyVarEnv, nullIdEnv) :: (InTypeEnv,InIdEnv)
510 replaceInEnvs :: SimplEnv -> (InTypeEnv,InIdEnv) -> SimplEnv
512 replaceInEnvs (SimplEnv chkr encl_cc ty_env id_env unfold_env)
513 (new_ty_env, new_id_env)
514 = SimplEnv chkr encl_cc new_ty_env new_id_env unfold_env
517 %************************************************************************
519 \subsubsection{The ``Id env'' part}
521 %************************************************************************
526 -> InBinder -> OutArg
529 extendIdEnvWithAtom (SimplEnv chkr encl_cc ty_env id_env unfold_env) (in_id,occ_info) atom@(LitArg lit)
530 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
532 new_id_env = addOneToIdEnv id_env in_id (ItsAnAtom atom)
534 extendIdEnvWithAtom (SimplEnv chkr encl_cc ty_env id_env unfold_env)
535 (in_id, occ_info) atom@(VarArg out_id)
536 = SimplEnv chkr encl_cc ty_env new_id_env new_unfold_env
538 new_id_env = addOneToIdEnv id_env in_id (ItsAnAtom atom)
540 new_unfold_env = modify_unfold_env
542 (modifyItem ok_to_dup occ_info)
544 -- Modify binding for in_id
545 -- NO! modify out_id, because its the info on the
546 -- atom that interest's us.
548 ok_to_dup = switchIsOn chkr SimplOkToDupCode
550 extendIdEnvWithAtomList
552 -> [(InBinder, OutArg)]
554 extendIdEnvWithAtomList = foldr (\ (bndr,val) env -> extendIdEnvWithAtom env bndr val)
556 extendIdEnvWithInlining
557 :: SimplEnv -- The Env to modify
558 -> SimplEnv -- The Env to record in the inlining. Usually the
559 -- same as the previous one, except in the recursive case
560 -> InBinder -> InExpr
563 extendIdEnvWithInlining (SimplEnv chkr encl_cc ty_env id_env unfold_env)
564 ~(SimplEnv _ _ inline_ty_env inline_id_env _ )
567 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
569 new_id_env = addOneToIdEnv id_env in_id (InlineIt inline_id_env inline_ty_env expr)
573 -> InBinder -- Old binder; binderinfo ignored
574 -> OutId -- Its new clone, as an Id
577 extendIdEnvWithClone (SimplEnv chkr encl_cc ty_env id_env unfold_env)
579 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
581 new_id_env = addOneToIdEnv id_env in_id (ItsAnAtom (VarArg out_id))
583 extendIdEnvWithClones -- Like extendIdEnvWithClone
589 extendIdEnvWithClones (SimplEnv chkr encl_cc ty_env id_env unfold_env)
591 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
593 new_id_env = growIdEnvList id_env (in_ids `zipEqual` out_vals)
594 in_ids = [id | (id,_) <- in_binders]
595 out_vals = [ItsAnAtom (VarArg out_id) | out_id <- out_ids]
597 lookupId :: SimplEnv -> Id -> Maybe IdVal
599 lookupId (SimplEnv _ _ _ id_env _) id
601 = lookupIdEnv id_env id
603 = case (lookupIdEnv id_env id) of
605 xxx -> --false!: ASSERT(not (isLocallyDefined id))
610 %************************************************************************
612 \subsubsection{The @UnfoldEnv@}
614 %************************************************************************
617 extendUnfoldEnvGivenFormDetails
623 extendUnfoldEnvGivenFormDetails
624 env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
627 NoUnfoldingDetails -> env
628 good_details -> SimplEnv chkr encl_cc ty_env id_env new_unfold_env
630 new_unfold_env = grow_unfold_env unfold_env id good_details encl_cc
632 extendUnfoldEnvGivenConstructor -- specialised variant
634 -> OutId -- bind this to...
635 -> Id -> [OutId] -- "con <tys-to-be-invented> args"
638 extendUnfoldEnvGivenConstructor env var con args
640 -- conjure up the types to which the con should be applied
641 scrut_ty = idType var
642 (_, ty_args, _) = getAppDataTyCon scrut_ty
644 extendUnfoldEnvGivenFormDetails
645 env var (ConForm con (map VarArg args))
649 @extendUnfoldEnvGivenRhs@ records in the UnfoldEnv info about the RHS
650 of a new binding. There is a horrid case we have to take care about,
651 due to Andr\'e Santos:
653 type Array_type b = Array Int b;
654 type Descr_type = (Int,Int);
656 tabulate :: (Int -> x) -> Descr_type -> Array_type x;
657 tabulate f (l,u) = listArray (l,u) [f i | i <- [l..u]];
661 f_aareorder::(Array_type Int) -> (Array_type t1) -> Array_type t1;
662 f_aareorder a_index a_ar=
664 f_aareorder' a_i= a_ar ! (a_index ! a_i)
665 } in tabulate f_aareorder' (bounds a_ar);
666 r_index=tabulate ((+) 1) (1,1);
667 arr = listArray (1,1) a_xs;
668 arg = f_aareorder r_index arr
671 Now, when the RHS of arg gets simplified, we inline f_aareorder to get
673 arg = let f_aareorder' a_i = arr ! (r_index ! a_i)
674 in tabulate f_aareorder' (bounds arr)
676 Note that r_index is not inlined, because it was bound to a_index which
677 occurs inside a lambda.
679 Alas, if elems is inlined, so that (elems arg) becomes (case arg of ...),
680 then arg is inlined. IF WE USE THE NEW VERSION OF arg, and re-occurrence
681 analyse it, we won't spot the inside-lambda property of r_index, so r_index
682 will get inlined inside the lambda. AARGH.
684 Solution: when we occurrence-analyse the new RHS we have to go back
685 and modify the info recorded in the UnfoldEnv for the free vars
686 of the RHS. In the example we'd go back and record that r_index is now used
690 extendUnfoldEnvGivenRhs
693 -> OutId -- Note: *must* be an "out" Id (post-cloning)
694 -> OutExpr -- Its rhs (*simplified*)
697 extendUnfoldEnvGivenRhs env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
698 binder@(_,occ_info) out_id rhs
699 = SimplEnv chkr encl_cc ty_env id_env new_unfold_env
701 -- Occurrence-analyse the RHS
702 (fv_occ_info, template) = occurAnalyseExpr {-test:nullIdEnv-} interesting_fvs rhs
704 interesting_fvs = get_interesting_ids unfold_env
706 -- Compute unfolding details
707 details = case rhs of
708 Var v -> panic "Vars already dealt with"
709 Lit lit | isNoRepLit lit -> LitForm lit
710 | otherwise -> panic "non-noRep Lits already dealt with"
712 Con con args -> ConForm con args
714 other -> mkGenForm ok_to_dup occ_info
715 (mkFormSummary (getIdStrictness out_id) rhs)
718 -- Compute resulting unfold env
719 new_unfold_env = case details of
720 NoUnfoldingDetails -> unfold_env
721 GenForm _ _ _ _ -> unfold_env2{-test: unfold_env1 -}
724 -- Add unfolding to unfold env
725 unfold_env1 = grow_unfold_env unfold_env out_id details encl_cc
727 -- Modify unfoldings of free vars of rhs, based on their
728 -- occurrence info in the rhs [see notes above]
729 unfold_env2 = foldr_unfold_env modify unfold_env1 (ufmToList fv_occ_info)
731 modify :: (Unique, BinderInfo) -> IdEnv UnfoldItem -> IdEnv UnfoldItem
732 modify (u, occ_info) env
733 = case (lookupDirectlyUFM env u) of
734 Nothing -> env -- ToDo: can this happen?
735 Just xx -> addToUFM_Directly env u (modifyItem ok_to_dup occ_info xx)
737 -- Compute unfolding guidance
738 guidance = if simplIdWantsToBeINLINEd out_id env
740 else calcUnfoldingGuidance True{-sccs OK-} bOMB_OUT_SIZE rhs
742 bOMB_OUT_SIZE = case (intSwitchSet chkr SimplUnfoldingCreationThreshold) of
743 Nothing -> uNFOLDING_CREATION_THRESHOLD
746 ok_to_dup = switchIsOn chkr SimplOkToDupCode
747 || exprSmallEnoughToDup rhs
748 -- [Andy] added, Jun 95
750 {- Reinstated AJG Jun 95; This is needed
751 --example that does not (currently) work
752 --without this extention
765 Omitted SLPJ Feb 95; should, I claim, be unnecessary
766 -- is_really_small looks for things like f a b c
767 -- but making sure there are not *too* many arguments.
768 -- (This is brought to you by *ANDY* Magic Constants, Inc.)
770 = case collectArgs new_rhs of
771 (Var _, xs) -> length xs < 10
777 lookupUnfolding :: SimplEnv -> Id -> UnfoldingDetails
779 lookupUnfolding (SimplEnv _ _ _ _ unfold_env) var
780 | not (isLocallyDefined var) -- Imported, so look inside the id
783 | otherwise -- Locally defined, so look in the envt.
784 -- There'll be nothing inside the Id.
785 = lookup_unfold_env unfold_env var
788 We need to remove any @GenForm@ bindings from the UnfoldEnv for
789 the RHS of an Id which has an INLINE pragma.
792 filterUnfoldEnvForInlines :: SimplEnv -> SimplEnv
794 filterUnfoldEnvForInlines env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
795 = SimplEnv chkr encl_cc ty_env id_env new_unfold_env
797 new_unfold_env = null_unfold_env
798 -- This version is really simple. INLINEd things are going to
799 -- be inlined wherever they are used, and then all the
800 -- UnfoldEnv stuff will take effect. Meanwhile, there isn't
801 -- much point in doing anything to the as-yet-un-INLINEd rhs.
803 -- Andy disagrees! Example:
804 -- all xs = foldr (&&) True xs
805 -- any p = all . map p {-# INLINE any #-}
807 -- Problem: any won't get deforested, and so if it's exported and
808 -- the importer doesn't use the inlining, (eg passes it as an arg)
809 -- then we won't get deforestation at all.
811 -- So he'd like not to filter the unfold env at all. But that's a disaster:
814 -- let f = \pq -> BIG
816 -- let g = \y -> f y y
818 -- in ...g...g...g...g...g...
820 -- Now, if that's the ONLY occurrence of f, it will be inlined inside g,
821 -- and thence copied multiple times when g is inlined.
824 ======================
826 In @lookForConstructor@ we used (before Apr 94) to have a special case
827 for nullary constructors:
830 = -- Don't re-use nullary constructors; it's a waste. Consider
838 -- Here the False in the second case will get replace by "a", hardly
843 but now we only do constructor re-use in let-bindings the special
844 case isn't necessary any more.
847 lookForConstructor (SimplEnv _ _ _ _ unfold_env) con args
848 = lookup_conapp unfold_env con args