postInlineUnconditionally
    :: DynFlags -> SimplEnv -> TopLevelFlag
    -> OutId            -- The binder (an InId would be fine too)
                        --            (*not* a CoVar)
    -> OccInfo          -- From the InId
    -> OutExpr
    -> Unfolding
    -> Bool
-- Precondition: rhs satisfies the let/app invariant
-- See Note [CoreSyn let/app invariant] in CoreSyn
-- Reason: we don't want to inline single uses, or discard dead bindings,
--         for unlifted, side-effect-full bindings
postInlineUnconditionally dflags env top_lvl bndr occ_info rhs unfolding
  | not active                  = False
  | isWeakLoopBreaker occ_info  = False -- If it's a loop-breaker of any kind, don't inline
                                        -- because it might be referred to "earlier"
  | isExportedId bndr           = False
  | isStableUnfolding unfolding = False -- Note [Stable unfoldings and postInlineUnconditionally]
  | isTopLevel top_lvl          = False -- Note [Top level and postInlineUnconditionally]
  | exprIsTrivial rhs           = True
  | otherwise
  = case occ_info of
        -- The point of examining occ_info here is that for *non-values*
        -- that occur outside a lambda, the call-site inliner won't have
        -- a chance (because it doesn't know that the thing
        -- only occurs once).   The pre-inliner won't have gotten
        -- it either, if the thing occurs in more than one branch
        -- So the main target is things like
        --      let x = f y in
        --      case v of
        --         True  -> case x of ...
        --         False -> case x of ...
        -- This is very important in practice; e.g. wheel-seive1 doubles
        -- in allocation if you miss this out
      OneOcc in_lam _one_br int_cxt     -- OneOcc => no code-duplication issue
        ->     smallEnoughToInline dflags unfolding     -- Small enough to dup
                        -- ToDo: consider discount on smallEnoughToInline if int_cxt is true
                        --
                        -- NB: Do NOT inline arbitrarily big things, even if one_br is True
                        -- Reason: doing so risks exponential behaviour.  We simplify a big
                        --         expression, inline it, and simplify it again.  But if the
                        --         very same thing happens in the big expression, we get
                        --         exponential cost!
                        -- PRINCIPLE: when we've already simplified an expression once,
                        -- make sure that we only inline it if it's reasonably small.

           && (not in_lam ||
                        -- Outside a lambda, we want to be reasonably aggressive
                        -- about inlining into multiple branches of case
                        -- e.g. let x = <non-value>
                        --      in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... }
                        -- Inlining can be a big win if C3 is the hot-spot, even if
                        -- the uses in C1, C2 are not 'interesting'
                        -- An example that gets worse if you add int_cxt here is 'clausify'

                (isCheapUnfolding unfolding && int_cxt))
                        -- isCheap => acceptable work duplication; in_lam may be true
                        -- int_cxt to prevent us inlining inside a lambda without some
                        -- good reason.  See the notes on int_cxt in preInlineUnconditionally

      IAmDead -> True   -- This happens; for example, the case_bndr during case of
                        -- known constructor:  case (a,b) of x { (p,q) -> ... }
                        -- Here x isn't mentioned in the RHS, so we don't want to
                        -- create the (dead) let-binding  let x = (a,b) in ...

      _ -> False

-- Here's an example that we don't handle well:
--      let f = if b then Left (\x.BIG) else Right (\y.BIG)
--      in \y. ....case f of {...} ....
-- Here f is used just once, and duplicating the case work is fine (exprIsCheap).
-- But
--  - We can't preInlineUnconditionally because that woud invalidate
--    the occ info for b.
--  - We can't postInlineUnconditionally because the RHS is big, and
--    that risks exponential behaviour
--  - We can't call-site inline, because the rhs is big
-- Alas!

  where
    active = isActive (sm_phase (getMode env)) (idInlineActivation bndr)
        -- See Note [pre/postInlineUnconditionally in gentle mode]

{-
Note [Top level and postInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We don't do postInlineUnconditionally for top-level things (even for
ones that are trivial):

  * Doing so will inline top-level error expressions that have been
    carefully floated out by FloatOut.  More generally, it might
    replace static allocation with dynamic.

  * Even for trivial expressions there's a problem.  Consider
      {-# RULE "foo" forall (xs::[T]). reverse xs = ruggle xs #-}
      blah xs = reverse xs
      ruggle = sort
    In one simplifier pass we might fire the rule, getting
      blah xs = ruggle xs
    but in *that* simplifier pass we must not do postInlineUnconditionally
    on 'ruggle' because then we'll have an unbound occurrence of 'ruggle'

    If the rhs is trivial it'll be inlined by callSiteInline, and then
    the binding will be dead and discarded by the next use of OccurAnal

  * There is less point, because the main goal is to get rid of local
    bindings used in multiple case branches.

  * The inliner should inline trivial things at call sites anyway.

Note [Stable unfoldings and postInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do not do postInlineUnconditionally if the Id has an stable unfolding,
otherwise we lose the unfolding.  Example

     -- f has stable unfolding with rhs (e |> co)
     --   where 'e' is big
     f = e |> co

Then there's a danger we'll optimise to

     f' = e
     f = f' |> co

and now postInlineUnconditionally, losing the stable unfolding on f.  Now f'
won't inline because 'e' is too big.

    c.f. Note [Stable unfoldings and preInlineUnconditionally]


************************************************************************
*                                                                      *
        Rebuilding a lambda
*                                                                      *
************************************************************************
-}
postInlineUnconditionally
    :: DynFlags -> SimplEnv -> TopLevelFlag
    -> OutId            -- The binder (an InId would be fine too)
                        --            (*not* a CoVar)
    -> OccInfo          -- From the InId
    -> OutExpr
    -> Unfolding
    -> Bool
postInlineUnconditionally dflags env top_lvl bndr occ_info rhs unfolding
  | not active                  = False
  | isWeakLoopBreaker occ_info  = False -- If it's a loop-breaker of any kind, don't inline
                                        -- because it might be referred to "earlier"
  | isExportedId bndr           = False
  | isStableUnfolding unfolding = False -- Note [Stable unfoldings and postInlineUnconditionally]
  | isTopLevel top_lvl          = False -- Note [Top level and postInlineUnconditionally]
  | exprIsTrivial rhs           = True
  | otherwise
  = case occ_info of
        -- The point of examining occ_info here is that for *non-values*
        -- that occur outside a lambda, the call-site inliner won't have
        -- a chance (because it doesn't know that the thing
        -- only occurs once).   The pre-inliner won't have gotten
        -- it either, if the thing occurs in more than one branch
        -- So the main target is things like
        --      let x = f y in
        --      case v of
        --         True  -> case x of ...
        --         False -> case x of ...
        -- This is very important in practice; e.g. wheel-seive1 doubles
        -- in allocation if you miss this out
      OneOcc in_lam _one_br int_cxt     -- OneOcc => no code-duplication issue
        ->     smallEnoughToInline dflags unfolding     -- Small enough to dup
                        -- ToDo: consider discount on smallEnoughToInline if int_cxt is true
                        --
                        -- NB: Do NOT inline arbitrarily big things, even if one_br is True
                        -- Reason: doing so risks exponential behaviour.  We simplify a big
                        --         expression, inline it, and simplify it again.  But if the
                        --         very same thing happens in the big expression, we get
                        --         exponential cost!
                        -- PRINCIPLE: when we've already simplified an expression once,
                        -- make sure that we only inline it if it's reasonably small.

           && (not in_lam ||
                        -- Outside a lambda, we want to be reasonably aggressive
                        -- about inlining into multiple branches of case
                        -- e.g. let x = <non-value>
                        --      in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... }
                        -- Inlining can be a big win if C3 is the hot-spot, even if
                        -- the uses in C1, C2 are not 'interesting'
                        -- An example that gets worse if you add int_cxt here is 'clausify'

                (isCheapUnfolding unfolding && int_cxt))
                        -- isCheap => acceptable work duplication; in_lam may be true
                        -- int_cxt to prevent us inlining inside a lambda without some
                        -- good reason.  See the notes on int_cxt in preInlineUnconditionally

      IAmDead -> True   -- This happens; for example, the case_bndr during case of
                        -- known constructor:  case (a,b) of x { (p,q) -> ... }
                        -- Here x isn't mentioned in the RHS, so we don't want to
                        -- create the (dead) let-binding  let x = (a,b) in ...

      _ -> False

-- Here's an example that we don't handle well:
--      let f = if b then Left (\x.BIG) else Right (\y.BIG)
--      in \y. ....case f of {...} ....
-- Here f is used just once, and duplicating the case work is fine (exprIsCheap).
-- But
--  - We can't preInlineUnconditionally because that woud invalidate
--    the occ info for b.
--  - We can't postInlineUnconditionally because the RHS is big, and
--    that risks exponential behaviour
--  - We can't call-site inline, because the rhs is big
-- Alas!

  where
    active = isActive (sm_phase (getMode env)) (idInlineActivation bndr)
        -- See Note [pre/postInlineUnconditionally in gentle mode]

{-
Note [Top level and postInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We don't do postInlineUnconditionally for top-level things (even for
ones that are trivial):

  * Doing so will inline top-level error expressions that have been
    carefully floated out by FloatOut.  More generally, it might
    replace static allocation with dynamic.

  * Even for trivial expressions there's a problem.  Consider
      {-# RULE "foo" forall (xs::[T]). reverse xs = ruggle xs #-}
      blah xs = reverse xs
      ruggle = sort
    In one simplifier pass we might fire the rule, getting
      blah xs = ruggle xs
    but in *that* simplifier pass we must not do postInlineUnconditionally
    on 'ruggle' because then we'll have an unbound occurrence of 'ruggle'

    If the rhs is trivial it'll be inlined by callSiteInline, and then
    the binding will be dead and discarded by the next use of OccurAnal

  * There is less point, because the main goal is to get rid of local
    bindings used in multiple case branches.

  * The inliner should inline trivial things at call sites anyway.

Note [Stable unfoldings and postInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do not do postInlineUnconditionally if the Id has an stable unfolding,
otherwise we lose the unfolding.  Example

     -- f has stable unfolding with rhs (e |> co)
     --   where 'e' is big
     f = e |> co

Then there's a danger we'll optimise to

     f' = e
     f = f' |> co

and now postInlineUnconditionally, losing the stable unfolding on f.  Now f'
won't inline because 'e' is too big.

    c.f. Note [Stable unfoldings and preInlineUnconditionally]


************************************************************************
*                                                                      *
        Rebuilding a lambda
*                                                                      *
************************************************************************
-}
postInlineUnconditionally dflags env top_lvl bndr occ_info rhs unfolding
  | not active                  = False
  | isWeakLoopBreaker occ_info  = False -- If it's a loop-breaker of any kind, don't inline
                                        -- because it might be referred to "earlier"
  | isExportedId bndr           = False
  | isStableUnfolding unfolding = False -- Note [Stable unfoldings and postInlineUnconditionally]
  | isTopLevel top_lvl          = False -- Note [Top level and postInlineUnconditionally]
  | exprIsTrivial rhs           = True
  | otherwise
  = case occ_info of
        -- The point of examining occ_info here is that for *non-values*
        -- that occur outside a lambda, the call-site inliner won't have
        -- a chance (because it doesn't know that the thing
        -- only occurs once).   The pre-inliner won't have gotten
        -- it either, if the thing occurs in more than one branch
        -- So the main target is things like
        --      let x = f y in
        --      case v of
        --         True  -> case x of ...
        --         False -> case x of ...
        -- This is very important in practice; e.g. wheel-seive1 doubles
        -- in allocation if you miss this out
      OneOcc in_lam _one_br int_cxt     -- OneOcc => no code-duplication issue
        ->     smallEnoughToInline dflags unfolding     -- Small enough to dup
                        -- ToDo: consider discount on smallEnoughToInline if int_cxt is true
                        --
                        -- NB: Do NOT inline arbitrarily big things, even if one_br is True
                        -- Reason: doing so risks exponential behaviour.  We simplify a big
                        --         expression, inline it, and simplify it again.  But if the
                        --         very same thing happens in the big expression, we get
                        --         exponential cost!
                        -- PRINCIPLE: when we've already simplified an expression once,
                        -- make sure that we only inline it if it's reasonably small.

           && (not in_lam ||
                        -- Outside a lambda, we want to be reasonably aggressive
                        -- about inlining into multiple branches of case
                        -- e.g. let x = <non-value>
                        --      in case y of { C1 -> ..x..; C2 -> ..x..; C3 -> ... }
                        -- Inlining can be a big win if C3 is the hot-spot, even if
                        -- the uses in C1, C2 are not 'interesting'
                        -- An example that gets worse if you add int_cxt here is 'clausify'

                (isCheapUnfolding unfolding && int_cxt))
                        -- isCheap => acceptable work duplication; in_lam may be true
                        -- int_cxt to prevent us inlining inside a lambda without some
                        -- good reason.  See the notes on int_cxt in preInlineUnconditionally

      IAmDead -> True   -- This happens; for example, the case_bndr during case of
                        -- known constructor:  case (a,b) of x { (p,q) -> ... }
                        -- Here x isn't mentioned in the RHS, so we don't want to
                        -- create the (dead) let-binding  let x = (a,b) in ...

      _ -> False

-- Here's an example that we don't handle well:
--      let f = if b then Left (\x.BIG) else Right (\y.BIG)
--      in \y. ....case f of {...} ....
-- Here f is used just once, and duplicating the case work is fine (exprIsCheap).
-- But
--  - We can't preInlineUnconditionally because that woud invalidate
--    the occ info for b.
--  - We can't postInlineUnconditionally because the RHS is big, and
--    that risks exponential behaviour
--  - We can't call-site inline, because the rhs is big
-- Alas!

  where
    active = isActive (sm_phase (getMode env)) (idInlineActivation bndr)
        -- See Note [pre/postInlineUnconditionally in gentle mode]

{-
Note [Top level and postInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We don't do postInlineUnconditionally for top-level things (even for
ones that are trivial):

  * Doing so will inline top-level error expressions that have been
    carefully floated out by FloatOut.  More generally, it might
    replace static allocation with dynamic.

  * Even for trivial expressions there's a problem.  Consider
      {-# RULE "foo" forall (xs::[T]). reverse xs = ruggle xs #-}
      blah xs = reverse xs
      ruggle = sort
    In one simplifier pass we might fire the rule, getting
      blah xs = ruggle xs
    but in *that* simplifier pass we must not do postInlineUnconditionally
    on 'ruggle' because then we'll have an unbound occurrence of 'ruggle'

    If the rhs is trivial it'll be inlined by callSiteInline, and then
    the binding will be dead and discarded by the next use of OccurAnal

  * There is less point, because the main goal is to get rid of local
    bindings used in multiple case branches.

  * The inliner should inline trivial things at call sites anyway.

Note [Stable unfoldings and postInlineUnconditionally]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do not do postInlineUnconditionally if the Id has an stable unfolding,
otherwise we lose the unfolding.  Example

     -- f has stable unfolding with rhs (e |> co)
     --   where 'e' is big
     f = e |> co

Then there's a danger we'll optimise to

     f' = e
     f = f' |> co

and now postInlineUnconditionally, losing the stable unfolding on f.  Now f'
won't inline because 'e' is too big.

    c.f. Note [Stable unfoldings and preInlineUnconditionally]


************************************************************************
*                                                                      *
        Rebuilding a lambda
*                                                                      *
************************************************************************
-}