diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2020-03-09 10:20:42 +0000 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2021-02-12 15:54:08 -0500 |
commit | 9a98ecc1a44d5cc200e57db8752de18b2fc3fc6f (patch) | |
tree | 6619931f635291041c064fb618a66df48a7c4f53 /compiler/GHC/Core/Unfold.hs | |
parent | 40983d2331fe34c0af6925db7588d5ac6a19ae36 (diff) | |
download | haskell-wip/T17917.tar.gz |
Avoid useless w/w splitwip/T17917
This patch is just a tidy-up for the post-strictness-analysis
worker wrapper split. Consider
f x = x
Strictnesss analysis does not lead to a w/w split, so the
obvious thing is to leave it 100% alone. But actually, because
the RHS is small, we ended up adding a StableUnfolding for it.
There is some reason to do this if we choose /not/ do to w/w
on the grounds that the function is small. See
Note [Don't w/w inline small non-loop-breaker things]
But there is no reason if we would not have done w/w anyway.
This patch just moves the conditional to later. Easy.
This does move some -ddump-simpl printouts around a bit.
I also discovered that the previous code was overwritten an
InlineCompulsory with InlineStable, which is utterly wrong. That in
turn meant that some default methods (marked InlineCompulsory)
were getting their InlineCompulsory squashed. This patch fixes
that bug --- but of course that does mean a bit more inlining!
Metric Decrease:
T9233
T9675
Metric Increase:
T12707
T11374
T3064
T4029
T9872b
T9872d
haddock.Cabal
Diffstat (limited to 'compiler/GHC/Core/Unfold.hs')
-rw-r--r-- | compiler/GHC/Core/Unfold.hs | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/compiler/GHC/Core/Unfold.hs b/compiler/GHC/Core/Unfold.hs index 8a61eec3c7..27510cf1ab 100644 --- a/compiler/GHC/Core/Unfold.hs +++ b/compiler/GHC/Core/Unfold.hs @@ -956,11 +956,21 @@ certainlyWillInline :: UnfoldingOpts -> IdInfo -> Maybe Unfolding -- ^ Sees if the unfolding is pretty certain to inline. -- If so, return a *stable* unfolding for it, that will always inline. certainlyWillInline opts fn_info - = case unfoldingInfo fn_info of - CoreUnfolding { uf_tmpl = e, uf_guidance = g } - | loop_breaker -> Nothing -- Won't inline, so try w/w - | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] - | otherwise -> do_cunf e g -- Depends on size, so look at that + = case fn_unf of + CoreUnfolding { uf_tmpl = expr, uf_guidance = guidance, uf_src = src } + | loop_breaker -> Nothing -- Won't inline, so try w/w + | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] + | otherwise + -> case guidance of + UnfNever -> Nothing + UnfWhen {} -> Just (fn_unf { uf_src = src' }) + -- INLINE functions have UnfWhen + UnfIfGoodArgs { ug_size = size, ug_args = args } + -> do_cunf expr size args src' + where + src' = case src of + InlineRhs -> InlineStable + _ -> src -- Do not change InlineCompulsory! DFunUnfolding {} -> Just fn_unf -- Don't w/w DFuns; it never makes sense -- to do so, and even if it is currently a @@ -973,17 +983,12 @@ certainlyWillInline opts fn_info noinline = inlinePragmaSpec (inlinePragInfo fn_info) == NoInline fn_unf = unfoldingInfo fn_info - do_cunf :: CoreExpr -> UnfoldingGuidance -> Maybe Unfolding - do_cunf _ UnfNever = Nothing - do_cunf _ (UnfWhen {}) = Just (fn_unf { uf_src = InlineStable }) - -- INLINE functions have UnfWhen - -- The UnfIfGoodArgs case seems important. If we w/w small functions -- binary sizes go up by 10%! (This is with SplitObjs.) -- I'm not totally sure why. -- INLINABLE functions come via this path -- See Note [certainlyWillInline: INLINABLE] - do_cunf expr (UnfIfGoodArgs { ug_size = size, ug_args = args }) + do_cunf expr size args src' | arityInfo fn_info > 0 -- See Note [certainlyWillInline: be careful of thunks] , not (isDeadEndSig (strictnessInfo fn_info)) -- Do not unconditionally inline a bottoming functions even if @@ -991,7 +996,7 @@ certainlyWillInline opts fn_info -- so we don't want to re-inline it. , let unf_arity = length args , size - (10 * (unf_arity + 1)) <= unfoldingUseThreshold opts - = Just (fn_unf { uf_src = InlineStable + = Just (fn_unf { uf_src = src' , uf_guidance = UnfWhen { ug_arity = unf_arity , ug_unsat_ok = unSaturatedOk , ug_boring_ok = inlineBoringOk expr } }) |