diff options
| author | simonpj@microsoft.com <unknown> | 2010-03-05 17:27:59 +0000 |
|---|---|---|
| committer | simonpj@microsoft.com <unknown> | 2010-03-05 17:27:59 +0000 |
| commit | 1b0259ee4fef03155482db050ae22ec93272e5fa (patch) | |
| tree | 1a305918fda3927b667b95488f49405635f806b8 /compiler | |
| parent | b4556cace1b420341c3e3bc6c1d7a7f693c655e4 (diff) | |
| download | haskell-1b0259ee4fef03155482db050ae22ec93272e5fa.tar.gz | |
Fix Trac #3736: do not preInlineUnconditionally with INLINE
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.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/simplCore/SimplUtils.lhs | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/compiler/simplCore/SimplUtils.lhs b/compiler/simplCore/SimplUtils.lhs index 1c08d6bf28..500f28678d 100644 --- a/compiler/simplCore/SimplUtils.lhs +++ b/compiler/simplCore/SimplUtils.lhs @@ -697,6 +697,27 @@ let-float if you inline windowToViewport 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 @@ -707,6 +728,7 @@ Inlining them won't make the program run faster! 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 @@ -971,6 +993,8 @@ Then there's a danger we'll optimise to and now postInlineUnconditionally, losing the InlineRule on f. Now f' won't inline because 'e' is too big. + c.f. Note [InlineRule and preInlineUnconditionally] + %************************************************************************ %* * |
