-\begin{code}
-completeTrivialBinding old_bndr new_bndr black_listed loop_breaker new_rhs thing_inside
- -- We're looking at a binding with a trivial RHS, so
- -- perhaps we can discard it altogether!
- --
- -- NB: a loop breaker never has postInlineUnconditionally True
- -- and non-loop-breakers only have *forward* references
- -- Hence, it's safe to discard the binding
- --
- -- NB: You might think that postInlineUnconditionally is an optimisation,
- -- but if we have
- -- let x = f Bool in (x, y)
- -- then because of the constructor, x will not be *inlined* in the pair,
- -- so the trivial binding will stay. But in this postInlineUnconditionally
- -- gag we use the *substitution* to substitute (f Bool) for x, and that *will*
- -- happen.
-
- -- NOTE: This isn't our last opportunity to inline.
- -- We're at the binding site right now, and
- -- we'll get another opportunity when we get to the ocurrence(s)
-
- -- Note that we do this unconditional inlining only for trival RHSs.
- -- Don't inline even WHNFs inside lambdas; doing so may
- -- simply increase allocation when the function is called
- -- This isn't the last chance; see NOTE above.
- --
- -- NB: Even inline pragmas (e.g. IMustBeINLINEd) are ignored here
- -- Why? Because we don't even want to inline them into the
- -- RHS of constructor arguments. See NOTE above
- --
- -- NB: Even NOINLINEis ignored here: if the rhs is trivial
- -- it's best to inline it anyway. We often get a=E; b=a
- -- from desugaring, with both a and b marked NOINLINE.
-
- | not keep_binding -- Can discard binding, inlining everywhere
- = extendSubst old_bndr (DoneEx new_rhs) $
- tick (PostInlineUnconditionally old_bndr) `thenSmpl_`
- thing_inside
-
- | otherwise -- We must keep the binding, but we may still inline
- = getSubst `thenSmpl` \ subst ->
- let
- new_bndr_info = substIdInfo subst (idInfo old_bndr) (idInfo new_bndr)
- final_id = new_bndr `setIdInfo` new_bndr_info
- in
- addLetBind (NonRec final_id new_rhs) $
- if dont_inline then
- modifyInScope new_bndr final_id thing_inside
- else
- extendSubst old_bndr (DoneEx new_rhs) thing_inside
- where
- dont_inline = black_listed || loop_breaker
- keep_binding = dont_inline || isExportedId old_bndr
-\end{code}
-