preInlineUnconditionally was, in effect, nuking an INLINE pragma, with
very bad effect on runtime in this program. Fortunately the fix is
very simple.
See Note [InlineRule and preInlineUnconditionally] in SimplUtils.
However, as usual for Gentle mode, do not inline things that are
inactive in the intial stages. See Note [Gentle mode].
However, as usual for Gentle mode, do not inline things that are
inactive in the intial stages. See Note [Gentle mode].
+Note [InlineRule and preInlineUnconditionally]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Surprisingly, do not pre-inline-unconditionally Ids with INLINE pragmas!
+Example
+
+ {-# INLINE f #-}
+ f :: Eq a => a -> a
+ f x = ...
+
+ fInt :: Int -> Int
+ fInt = f Int dEqInt
+
+ ...fInt...fInt...fInt...
+
+Here f occurs just once, in the RHS of f1. But if we inline it there
+we'll lose the opportunity to inline at each of fInt's call sites.
+The INLINE pragma will only inline when the application is saturated
+for exactly this reason; and we don't want PreInlineUnconditionally
+to second-guess it. A live example is Trac #3736.
+ c.f. Note [InlineRule and postInlineUnconditionally]
+
Note [Top-level botomming Ids]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Don't inline top-level Ids that are bottoming, even if they are used just
Note [Top-level botomming Ids]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Don't inline top-level Ids that are bottoming, even if they are used just
preInlineUnconditionally :: SimplEnv -> TopLevelFlag -> InId -> InExpr -> Bool
preInlineUnconditionally env top_lvl bndr rhs
| not active = False
preInlineUnconditionally :: SimplEnv -> TopLevelFlag -> InId -> InExpr -> Bool
preInlineUnconditionally env top_lvl bndr rhs
| not active = False
+ | isStableUnfolding (idUnfolding bndr) = False -- Note [InlineRule and preInlineUnconditionally]
| isTopLevel top_lvl && isBottomingId bndr = False -- Note [Top-level bottoming Ids]
| opt_SimplNoPreInlining = False
| otherwise = case idOccInfo bndr of
| isTopLevel top_lvl && isBottomingId bndr = False -- Note [Top-level bottoming Ids]
| opt_SimplNoPreInlining = False
| otherwise = case idOccInfo bndr of
and now postInlineUnconditionally, losing the InlineRule on f. Now f'
won't inline because 'e' is too big.
and now postInlineUnconditionally, losing the InlineRule on f. Now f'
won't inline because 'e' is too big.
+ c.f. Note [InlineRule and preInlineUnconditionally]
+
%************************************************************************
%* *
%************************************************************************
%* *