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(..)
48 IMPORT_DELOOPER(SmplLoop) -- breaks the MagicUFs / SimplEnv loop
50 import BinderInfo ( orBinderInfo, oneSafeOcc,
51 BinderInfo(..){-instances, too-}, FunOrArg, DuplicationDanger, InsideSCC
53 import CgCompInfo ( uNFOLDING_CREATION_THRESHOLD )
54 import CmdLineOpts ( switchIsOn, intSwitchSet, SimplifierSwitch(..), SwitchResult )
56 import CoreUnfold ( UnfoldingDetails(..), mkGenForm, mkConForm,
57 calcUnfoldingGuidance, UnfoldingGuidance(..),
58 mkFormSummary, FormSummary(..)
60 import CoreUtils ( manifestlyWHNF, exprSmallEnoughToDup )
61 import FiniteMap -- lots of things
62 import Id ( idType, getIdUnfolding, getIdStrictness,
64 nullIdEnv, growIdEnvList, rngIdEnv, lookupIdEnv,
65 addOneToIdEnv, modifyIdEnv, mkIdSet,
66 IdEnv(..), IdSet(..), GenId )
67 import IdInfo ( bottomIsGuaranteed, StrictnessInfo )
68 import Literal ( isNoRepLit, Literal{-instances-} )
69 import Maybes ( maybeToBool )
70 import Name ( isLocallyDefined )
71 import OccurAnal ( occurAnalyseExpr )
72 import Outputable ( Outputable(..){-instances-} )
73 import PprCore -- various instances
74 import PprStyle ( PprStyle(..) )
75 import PprType ( GenType, GenTyVar )
77 import Type ( eqTy, getAppDataTyConExpandingDicts, applyTypeEnvToTy )
78 import TyVar ( nullTyVarEnv, addOneToIdEnv, addOneToTyVarEnv,
80 TyVarEnv(..), GenTyVar{-instance Eq-}
82 import Unique ( Unique{-instance Outputable-} )
83 import UniqFM ( addToUFM_Directly, lookupUFM_Directly, delFromUFM_Directly,
86 --import UniqSet -- lots of things
87 import Usage ( UVar(..), GenUsage{-instances-} )
88 import Util ( zipEqual, thenCmp, cmpList, panic, panic#, assertPanic )
90 type TypeEnv = TyVarEnv Type
91 cmpType = panic "cmpType (SimplEnv)"
94 %************************************************************************
96 \subsection[Simplify-types]{Type declarations}
98 %************************************************************************
101 %************************************************************************
103 \subsubsection{The @SimplEnv@ type}
105 %************************************************************************
108 INVARIANT: we assume {\em no shadowing}. (ToDo: How can we ASSERT
109 this? WDP 94/06) This allows us to neglect keeping everything paired
110 with its static environment.
112 The environment contains bindings for all
114 {\em locally-defined}
117 For such things, any unfolding is found in the environment, not in the
118 Id. Unfoldings in the Id itself are used only for imported things
119 (otherwise we get trouble because we have to simplify the unfoldings
120 inside the Ids, etc.).
127 EnclosingCcDetails -- the enclosing cost-centre (when profiling)
129 InTypeEnv -- For cloning types
130 -- Domain is all in-scope type variables
138 -- (Could omit the exported top-level guys,
139 -- since their names mustn't change; and ditto
140 -- the non-exported top-level guys which you
141 -- don't want to macro-expand, since their
142 -- names need not change.)
146 UnfoldEnv -- Domain is any *OutIds*, including imports
147 -- where we know something more than the
148 -- interface file tells about their value (see
151 nullSimplEnv :: SwitchChecker -> SimplEnv
154 = SimplEnv sw_chkr NoEnclosingCcDetails nullTyVarEnv nullIdEnv null_unfold_env
156 pprSimplEnv (SimplEnv _ _ ty_env id_env (UFE unfold_env _ _))
158 ppStr "** Type Env ** ????????", -- ppr PprDebug ty_env,
159 ppSP, ppStr "** Id Env ** ?????????",
160 -- ppAboves [ pp_id_entry x | x <- getIdEnvMapping id_env ],
161 ppSP, ppStr "** Unfold Env **",
162 ppAboves [ pp_uf_entry x | x <- rngIdEnv unfold_env ]
165 pp_id_entry (v, idval)
166 = ppCat [ppr PprDebug v, ppStr "=>",
168 InlineIt _ _ e -> ppCat [ppStr "InlineIt:", ppr PprDebug e]
169 ItsAnAtom a -> ppCat [ppStr "Atom:", ppr PprDebug a]
172 pp_uf_entry (UnfoldItem v form encl_cc)
173 = ppCat [ppr PprDebug v, ppStr "=>",
175 NoUnfoldingDetails -> ppStr "NoUnfoldingDetails"
176 OtherLitForm ls -> ppCat [ppStr "Other lit:", ppInterleave (ppStr ", ")
177 [ppr PprDebug l | l <- ls]]
178 OtherConForm cs -> ppCat [ppStr "OtherCon:", ppInterleave (ppStr ", ")
179 [ppr PprDebug c | c <- cs]]
180 GenForm w e g -> ppCat [ppStr "UF:", ppr PprDebug w,
181 ppr PprDebug g, ppr PprDebug e]
182 MagicForm s _ -> ppCat [ppStr "Magic:", ppr PprDebug s]
186 %************************************************************************
188 \subsubsection{The @IdVal@ type (for the ``IdEnv'')}
190 %************************************************************************
192 The unfoldings for imported things are mostly kept within the Id
193 itself; nevertheless, they {\em can} get into the @UnfoldEnv@. For
194 example, suppose \tr{x} is imported, and we have
199 Then within \tr{<body>}, we know that \tr{x} is a pair with components
203 type InIdEnv = IdEnv IdVal -- Maps InIds to their value
206 = InlineIt InIdEnv InTypeEnv InExpr
207 -- No binding of the Id is left;
208 -- You *have* to replace any occurences
209 -- of the id with this expression.
210 -- Rather like a macro, really
211 -- NB: the InIdEnv/InTypeEnv is necessary to prevent
212 -- name caputure. Consider:
217 -- If x gets an InlineIt, we must remember
218 -- the correct binding for y.
220 | ItsAnAtom OutArg -- Used either (a) to record the cloned Id
221 -- or (b) if the orig defn is a let-binding, and
222 -- the RHS of the let simplifies to an atom,
223 -- we just bind the variable to that atom, and
227 %************************************************************************
229 \subsubsection{The @UnfoldEnv@ type}
231 %************************************************************************
233 The @UnfoldEnv@ contains information about the value of some of the
234 in-scope identifiers. It obeys the following invariant:
236 If the @UnfoldEnv@ contains information, it is safe to use it!
238 In particular, if the @UnfoldEnv@ contains details of an unfolding of
239 an Id, then it's safe to use the unfolding. If, for example, the Id
240 is used many times, then its unfolding won't be put in the UnfoldEnv
243 The @UnfoldEnv@ (used to be [WDP 94/06]) a simple association list
244 because (a)~it's small, and (b)~we need to search its {\em range} as
248 data UnfoldItem -- a glorified triple...
249 = UnfoldItem OutId -- key: used in lookForConstructor
250 UnfoldingDetails -- for that Id
251 EnclosingCcDetails -- so that if we do an unfolding,
252 -- we can "wrap" it in the CC
253 -- that was in force.
255 data UnfoldConApp -- yet another glorified pair
256 = UCA OutId -- data constructor
257 [OutArg] -- *value* arguments; see use below
259 data UnfoldEnv -- yup, a glorified triple...
260 = UFE (IdEnv UnfoldItem) -- Maps an OutId => its UnfoldItem
262 (IdEnv (Id,BinderInfo)) -- Occurrence info for some (but not necessarily all)
263 -- in-scope ids. The "Id" part is just so that
264 -- we can recover the domain of the mapping, which
265 -- IdEnvs don't allow directly.
267 -- Anything that isn't in here
268 -- should be assumed to occur many times.
269 -- The things in here all occur once, and the
270 -- binder-info tells about whether that "once"
271 -- is inside a lambda, or perhaps once in each branch
273 -- We keep this info so we can modify it when
274 -- something changes.
276 (FiniteMap UnfoldConApp [([Type], OutId)])
277 -- Maps applications of constructors (to
278 -- value atoms) back to an association list
279 -- that says "if the constructor was applied
280 -- to one of these lists-of-Types, then
281 -- this OutId is your man (in a non-gender-specific
282 -- sense)". I.e., this is a reversed
283 -- mapping for (part of) the main IdEnv
286 null_unfold_env = UFE nullIdEnv nullIdEnv emptyFM
289 The @UnfoldEnv@ type. We expect on the whole that an @UnfoldEnv@ will
290 be small, because it contains bindings only for those things whose
291 form or unfolding is known. Basically it maps @Id@ to their
292 @UnfoldingDetails@ (and @EnclosingCcDetails@---boring...), but we also
293 need to search it associatively, to look for @Id@s which have a given
296 We implement it with @IdEnvs@, possibly overkill, but sometimes these
297 things silently grow quite big.... Here are some local functions used
298 elsewhere in the module:
301 grow_unfold_env :: UnfoldEnv -> OutId -> BinderInfo -> UnfoldingDetails -> EnclosingCcDetails -> UnfoldEnv
302 lookup_unfold_env :: UnfoldEnv -> OutId -> UnfoldingDetails
303 lookup_unfold_env_encl_cc
304 :: UnfoldEnv -> OutId -> EnclosingCcDetails
306 grow_unfold_env full_u_env _ _ NoUnfoldingDetails _ = full_u_env
308 grow_unfold_env (UFE u_env occ_env con_apps) id occ_info uf_details encl_cc
309 = UFE (addOneToIdEnv u_env id (UnfoldItem id uf_details encl_cc))
313 new_occ_env = modify_occ_info occ_env id occ_info
317 GenForm WhnfForm (Con con args) UnfoldAlways -> snd (lookup_conapp_help con_apps con args id)
318 not_a_constructor -> con_apps -- unchanged
320 addto_unfold_env (UFE u_env occ_env con_apps) extra_items
321 = ASSERT(not (any constructor_form_in_those extra_items))
322 -- otherwise, we'd need to change con_apps
323 UFE (growIdEnvList u_env extra_items) occ_env con_apps
325 constructor_form_in_those (_, UnfoldItem _ (GenForm WhnfForm (Con _ _) UnfoldAlways) _) = True
326 constructor_form_in_those _ = False
328 rng_unfold_env (UFE u_env _ _) = rngIdEnv u_env
330 get_interesting_ids (UFE _ occ_env _)
331 = mkIdSet [ i | (_,(i,_)) <- ufmToList occ_env ]
333 foldr_occ_env fun (UFE u_env occ_env con_apps) stuff
334 = UFE u_env (foldr fun occ_env stuff) con_apps
336 lookup_unfold_env (UFE u_env _ _) id
337 = case (lookupIdEnv u_env id) of
338 Nothing -> NoUnfoldingDetails
339 Just (UnfoldItem _ uf _) -> uf
341 lookup_unfold_env_encl_cc (UFE u_env _ _) id
342 = case (lookupIdEnv u_env id) of
343 Nothing -> NoEnclosingCcDetails
344 Just (UnfoldItem _ _ encl_cc) -> encl_cc
346 lookup_conapp (UFE _ _ con_apps) con args
347 = fst (lookup_conapp_help con_apps con args (panic "lookup_conapp"))
349 -- Returns two things; we just fst or snd the one we want:
350 lookup_conapp_help con_apps con args outid
351 = case (span notValArg args) of { (ty_args, val_args) ->
353 entry = UCA con val_args
354 arg_tys = [ t | TyArg t <- ty_args ]
356 case (lookupFM con_apps entry) of
358 addToFM con_apps entry [(arg_tys, outid)])
360 -> ASSERT(not (null assocs))
361 case [ oid | (ts,oid) <- assocs, ts `eq_tys` arg_tys ] of
363 con_apps) -- unchanged; we hang onto what we have
365 addToFM con_apps entry ((arg_tys, outid) : assocs))
366 _ -> panic "grow_unfold_env:dup in assoc list"
370 = case (cmpList cmp_ty ts1 ts2) of { EQ_ -> True; _ -> False }
372 cmp_ty ty1 ty2 -- NB: we really only know how to do *equality* on types
373 = if (ty1 `eqTy` ty2) then EQ_ else LT_{-random choice-}
375 modify_occ_info occ_env id new_occ@(OneOcc _ _ _ _ _)
376 = modifyIdEnv occ_env (\ (i,o) -> (i, orBinderInfo o new_occ)) id
378 modify_occ_info occ_env id other_new_occ
379 = -- Many or Dead occurrence, just delete from occ_env
380 delFromUFM occ_env id
383 The main thing about @UnfoldConApp@ is that it has @Ord@ defined on
384 it, so we can use it for a @FiniteMap@ key.
386 instance Eq UnfoldConApp where
387 a == b = case (a `cmp` b) of { EQ_ -> True; _ -> False }
388 a /= b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
390 instance Ord UnfoldConApp where
391 a <= b = case (a `cmp` b) of { LT_ -> True; EQ_ -> True; GT__ -> False }
392 a < b = case (a `cmp` b) of { LT_ -> True; EQ_ -> False; GT__ -> False }
393 a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True; GT__ -> True }
394 a > b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True }
395 _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
397 instance Ord3 UnfoldConApp where
400 cmp_app (UCA c1 as1) (UCA c2 as2)
401 = cmp c1 c2 `thenCmp` cmpList cmp_arg as1 as2
403 -- ToDo: make an "instance Ord3 CoreArg"???
405 cmp_arg (VarArg x) (VarArg y) = x `cmp` y
406 cmp_arg (LitArg x) (LitArg y) = x `cmp` y
407 cmp_arg (TyArg x) (TyArg y) = panic# "SimplEnv.cmp_app:TyArgs"
408 cmp_arg (UsageArg x) (UsageArg y) = panic# "SimplEnv.cmp_app:UsageArgs"
410 | tag x _LT_ tag y = LT_
413 tag (VarArg _) = ILIT(1)
414 tag (LitArg _) = ILIT(2)
415 tag (TyArg _) = panic# "SimplEnv.cmp_app:TyArg"
416 tag (UsageArg _) = panic# "SimplEnv.cmp_app:UsageArg"
419 %************************************************************************
421 \subsubsection{The @EnclosingCcDetails@ type}
423 %************************************************************************
426 data EnclosingCcDetails
427 = NoEnclosingCcDetails
428 | EnclosingCC CostCentre
431 %************************************************************************
433 \subsubsection{The ``InXXX'' and ``OutXXX'' type synonyms}
435 %************************************************************************
438 type InId = Id -- Not yet cloned
439 type InBinder = (InId, BinderInfo)
440 type InType = Type -- Ditto
441 type InBinding = SimplifiableCoreBinding
442 type InExpr = SimplifiableCoreExpr
443 type InAlts = SimplifiableCoreCaseAlts
444 type InDefault = SimplifiableCoreCaseDefault
445 type InArg = SimplifiableCoreArg
447 type OutId = Id -- Cloned
449 type OutType = Type -- Cloned
450 type OutBinding = CoreBinding
451 type OutExpr = CoreExpr
452 type OutAlts = CoreCaseAlts
453 type OutDefault = CoreCaseDefault
454 type OutArg = CoreArg
459 type SwitchChecker = SimplifierSwitch -> SwitchResult
462 %************************************************************************
464 \subsection{@SimplEnv@ handling}
466 %************************************************************************
468 %************************************************************************
470 \subsubsection{Command-line switches}
472 %************************************************************************
475 getSwitchChecker :: SimplEnv -> SwitchChecker
476 getSwitchChecker (SimplEnv chkr _ _ _ _) = chkr
478 switchIsSet :: SimplEnv -> SimplifierSwitch -> Bool
479 switchIsSet (SimplEnv chkr _ _ _ _) switch
480 = switchIsOn chkr switch
483 %************************************************************************
485 \subsubsection{The ``enclosing cost-centre''}
487 %************************************************************************
490 setEnclosingCC :: SimplEnv -> EnclosingCcDetails -> SimplEnv
492 setEnclosingCC (SimplEnv chkr _ ty_env id_env unfold_env) encl_cc
493 = SimplEnv chkr encl_cc ty_env id_env unfold_env
496 %************************************************************************
498 \subsubsection{The @TypeEnv@ part}
500 %************************************************************************
503 type InTypeEnv = TypeEnv -- Maps InTyVars to OutTypes
505 extendTyEnv :: SimplEnv -> TyVar -> Type -> SimplEnv
506 extendTyEnv (SimplEnv chkr encl_cc ty_env id_env unfold_env) tyvar ty
507 = SimplEnv chkr encl_cc new_ty_env id_env unfold_env
509 new_ty_env = addOneToTyVarEnv ty_env tyvar ty
511 extendTyEnvList :: SimplEnv -> [(TyVar,Type)] -> SimplEnv
512 extendTyEnvList (SimplEnv chkr encl_cc ty_env id_env unfold_env) pairs
513 = SimplEnv chkr encl_cc new_ty_env id_env unfold_env
515 new_ty_env = growTyVarEnvList ty_env pairs
517 simplTy (SimplEnv _ _ ty_env _ _) ty = applyTypeEnvToTy ty_env ty
518 simplTyInId (SimplEnv _ _ ty_env _ _) id = applyTypeEnvToId ty_env id
521 @replaceInEnvs@ is used to install saved type and id envs
522 when pulling an un-simplified expression out of the environment, which
523 was saved with its environments.
526 nullInEnvs = (nullTyVarEnv, nullIdEnv) :: (InTypeEnv,InIdEnv)
528 replaceInEnvs :: SimplEnv -> (InTypeEnv,InIdEnv) -> SimplEnv
530 replaceInEnvs (SimplEnv chkr encl_cc ty_env id_env unfold_env)
531 (new_ty_env, new_id_env)
532 = SimplEnv chkr encl_cc new_ty_env new_id_env unfold_env
535 %************************************************************************
537 \subsubsection{The ``Id env'' part}
539 %************************************************************************
544 -> InBinder -> OutArg{-Val args only, please-}
547 extendIdEnvWithAtom (SimplEnv chkr encl_cc ty_env id_env unfold_env)
548 (in_id,occ_info) atom@(LitArg lit)
549 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
551 new_id_env = addOneToIdEnv id_env in_id (ItsAnAtom atom)
553 extendIdEnvWithAtom (SimplEnv chkr encl_cc ty_env id_env (UFE u_env occ_env con_apps))
554 (in_id, occ_info) atom@(VarArg out_id)
555 = SimplEnv chkr encl_cc ty_env new_id_env new_unfold_env
557 new_id_env = addOneToIdEnv id_env in_id (ItsAnAtom atom)
558 new_unfold_env = UFE u_env (modify_occ_info occ_env out_id occ_info) con_apps
559 -- Modify occ info for out_id
562 extendIdEnvWithAtom _ _ _ = panic "extendIdEnvWithAtom: non-Val arg!"
565 extendIdEnvWithAtomList
567 -> [(InBinder, OutArg)]
569 extendIdEnvWithAtomList = foldr (\ (bndr,val) env -> extendIdEnvWithAtom env bndr val)
571 extendIdEnvWithInlining
572 :: SimplEnv -- The Env to modify
573 -> SimplEnv -- The Env to record in the inlining. Usually the
574 -- same as the previous one, except in the recursive case
575 -> InBinder -> InExpr
578 extendIdEnvWithInlining (SimplEnv chkr encl_cc ty_env id_env unfold_env)
579 ~(SimplEnv _ _ inline_ty_env inline_id_env _ )
582 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
584 new_id_env = addOneToIdEnv id_env in_id (InlineIt inline_id_env inline_ty_env expr)
588 -> InBinder -- Old binder; binderinfo ignored
589 -> OutId -- Its new clone, as an Id
592 extendIdEnvWithClone (SimplEnv chkr encl_cc ty_env id_env unfold_env)
594 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
596 new_id_env = addOneToIdEnv id_env in_id (ItsAnAtom (VarArg out_id))
598 extendIdEnvWithClones -- Like extendIdEnvWithClone
604 extendIdEnvWithClones (SimplEnv chkr encl_cc ty_env id_env unfold_env)
606 = SimplEnv chkr encl_cc ty_env new_id_env unfold_env
608 new_id_env = growIdEnvList id_env (zipEqual "extendIdEnvWithClones" in_ids out_vals)
609 in_ids = [id | (id,_) <- in_binders]
610 out_vals = [ItsAnAtom (VarArg out_id) | out_id <- out_ids]
612 lookupId :: SimplEnv -> Id -> Maybe IdVal
614 lookupId (SimplEnv _ _ _ id_env _) id
616 = lookupIdEnv id_env id
618 = case (lookupIdEnv id_env id) of
620 xxx -> --false!: ASSERT(not (isLocallyDefined id))
625 %************************************************************************
627 \subsubsection{The @UnfoldEnv@}
629 %************************************************************************
632 extendUnfoldEnvGivenFormDetails
638 extendUnfoldEnvGivenFormDetails
639 env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
642 NoUnfoldingDetails -> env
643 good_details -> SimplEnv chkr encl_cc ty_env id_env new_unfold_env
645 new_unfold_env = grow_unfold_env unfold_env id fake_occ_info good_details encl_cc
646 fake_occ_info = {-ToDo!-} ManyOcc 0 -- generally paranoid
648 extendUnfoldEnvGivenConstructor -- specialised variant
650 -> OutId -- bind this to...
651 -> Id -> [OutId] -- "con <tys-to-be-invented> args"
654 extendUnfoldEnvGivenConstructor env var con args
656 -- conjure up the types to which the con should be applied
657 scrut_ty = idType var
658 (_, ty_args, _) = getAppDataTyConExpandingDicts scrut_ty
660 extendUnfoldEnvGivenFormDetails
661 env var (mkConForm con (map TyArg ty_args ++ map VarArg args))
665 @extendUnfoldEnvGivenRhs@ records in the UnfoldEnv info about the RHS
666 of a new binding. There is a horrid case we have to take care about,
667 due to Andr\'e Santos:
669 type Array_type b = Array Int b;
670 type Descr_type = (Int,Int);
672 tabulate :: (Int -> x) -> Descr_type -> Array_type x;
673 tabulate f (l,u) = listArray (l,u) [f i | i <- [l..u]];
677 f_aareorder::(Array_type Int) -> (Array_type t1) -> Array_type t1;
678 f_aareorder a_index a_ar=
680 f_aareorder' a_i= a_ar ! (a_index ! a_i)
681 } in tabulate f_aareorder' (bounds a_ar);
682 r_index=tabulate ((+) 1) (1,1);
683 arr = listArray (1,1) a_xs;
684 arg = f_aareorder r_index arr
687 Now, when the RHS of arg gets simplified, we inline f_aareorder to get
689 arg = let f_aareorder' a_i = arr ! (r_index ! a_i)
690 in tabulate f_aareorder' (bounds arr)
692 Note that r_index is not inlined, because it was bound to a_index which
693 occurs inside a lambda.
695 Alas, if elems is inlined, so that (elems arg) becomes (case arg of ...),
696 then arg is inlined. IF WE USE THE NEW VERSION OF arg, and re-occurrence
697 analyse it, we won't spot the inside-lambda property of r_index, so r_index
698 will get inlined inside the lambda. AARGH.
700 Solution: when we occurrence-analyse the new RHS we have to go back
701 and modify the info recorded in the UnfoldEnv for the free vars
702 of the RHS. In the example we'd go back and record that r_index is now used
706 extendUnfoldEnvGivenRhs
709 -> OutId -- Note: *must* be an "out" Id (post-cloning)
710 -> OutExpr -- Its rhs (*simplified*)
713 extendUnfoldEnvGivenRhs env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
714 binder@(_,occ_info) out_id rhs
715 = SimplEnv chkr encl_cc ty_env id_env new_unfold_env
717 -- Occurrence-analyse the RHS
718 (fv_occ_info, template) = occurAnalyseExpr interesting_fvs rhs
720 interesting_fvs = get_interesting_ids unfold_env -- Ids in dom of OccEnv
722 -- Compute unfolding details
723 details = mkGenForm (mkFormSummary (getIdStrictness out_id) rhs)
726 -- Compute resulting unfold env
727 new_unfold_env = case details of
728 NoUnfoldingDetails -> unfold_env
731 -- Add unfolding to unfold env
732 unfold_env1 = grow_unfold_env unfold_env out_id occ_info details encl_cc
734 {- OLD: done in grow_unfold_env
735 -- Modify unfoldings of free vars of rhs, based on their
736 -- occurrence info in the rhs [see notes above]
738 = foldr_occ_env modify unfold_env1 (ufmToList fv_occ_info)
740 modify :: (Unique, (Id,BinderInfo)) -> IdEnv (Id,BinderInfo) -> IdEnv (Id,BinderInfo)
741 modify (u, item@(i,occ_info)) env
742 = if maybeToBool (lookupUFM_Directly env u) then
743 -- it occurred before, so now it occurs multiple times;
744 -- therefore, *delete* it from the occ(urs once) env.
745 delFromUFM_Directly env u
747 else if not (oneSafeOcc ok_to_dup occ_info) then
748 env -- leave it alone
750 addToUFM_Directly env u item
753 -- Compute unfolding guidance
754 guidance = if simplIdWantsToBeINLINEd out_id env
756 else calcUnfoldingGuidance True{-sccs OK-} bOMB_OUT_SIZE rhs
758 bOMB_OUT_SIZE = case (intSwitchSet chkr SimplUnfoldingCreationThreshold) of
759 Nothing -> uNFOLDING_CREATION_THRESHOLD
762 ok_to_dup = switchIsOn chkr SimplOkToDupCode
763 --NO: || exprSmallEnoughToDup rhs
764 -- -- [Andy] added, Jun 95
766 {- Reinstated AJG Jun 95; This is needed
767 --example that does not (currently) work
768 --without this extention
781 Omitted SLPJ Feb 95; should, I claim, be unnecessary
782 -- is_really_small looks for things like f a b c
783 -- but making sure there are not *too* many arguments.
784 -- (This is brought to you by *ANDY* Magic Constants, Inc.)
786 = case collectArgs new_rhs of
787 (Var _, _, _, xs) -> length xs < 10
793 lookupUnfolding :: SimplEnv -> Id -> UnfoldingDetails
795 lookupUnfolding (SimplEnv _ _ _ _ unfold_env) var
796 | not (isLocallyDefined var) -- Imported, so look inside the id
799 | otherwise -- Locally defined, so look in the envt.
800 -- There'll be nothing inside the Id.
801 = lookup_unfold_env unfold_env var
804 We need to remove any @GenForm@ bindings from the UnfoldEnv for
805 the RHS of an Id which has an INLINE pragma.
808 filterUnfoldEnvForInlines :: SimplEnv -> SimplEnv
810 filterUnfoldEnvForInlines env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
811 = SimplEnv chkr encl_cc ty_env id_env new_unfold_env
813 new_unfold_env = null_unfold_env
814 -- This version is really simple. INLINEd things are going to
815 -- be inlined wherever they are used, and then all the
816 -- UnfoldEnv stuff will take effect. Meanwhile, there isn't
817 -- much point in doing anything to the as-yet-un-INLINEd rhs.
819 -- Andy disagrees! Example:
820 -- all xs = foldr (&&) True xs
821 -- any p = all . map p {-# INLINE any #-}
823 -- Problem: any won't get deforested, and so if it's exported and
824 -- the importer doesn't use the inlining, (eg passes it as an arg)
825 -- then we won't get deforestation at all.
827 -- So he'd like not to filter the unfold env at all. But that's a disaster:
830 -- let f = \pq -> BIG
832 -- let g = \y -> f y y
834 -- in ...g...g...g...g...g...
836 -- Now, if that's the ONLY occurrence of f, it will be inlined inside g,
837 -- and thence copied multiple times when g is inlined.
840 ======================
842 In @lookForConstructor@ we used (before Apr 94) to have a special case
843 for nullary constructors:
846 = -- Don't re-use nullary constructors; it's a waste. Consider
854 -- Here the False in the second case will get replace by "a", hardly
859 but now we only do constructor re-use in let-bindings the special
860 case isn't necessary any more.
863 lookForConstructor (SimplEnv _ _ _ _ unfold_env) con args
864 = lookup_conapp unfold_env con args