diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-01-03 19:55:09 +0000 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-01-03 20:02:30 +0000 |
commit | f0fb2004a8a60d270c72cce259461649ae769732 (patch) | |
tree | b21b1224cc0ba9cf4fe24012df80913c7eab449f | |
parent | 83edba07e4fe23eb29158d4ddd6f6e25773d6f9a (diff) | |
download | haskell-wip/workaround-T17615.tar.gz |
CoreUnfold: Temporary workaround for #17615wip/workaround-T17615
This is an awful but temporary workaround for #17615, where the case
analysis from the 'ufVeryAggressive' selector causes the entire
'DynFlags' to be unpacked into local bindings (due to binder swap). This
results in a tremendous amount of stack spillage, severely bloating the
code generated for 'callSiteInline'.
The right solution here is likely to fix binder swap to avoid this
terrible behavior (since there are likely other instances of this as
well) but this case was serious enough that it showed up in a CPU
profile and consequently I wanted to fix it for 8.10.
-rw-r--r-- | compiler/coreSyn/CoreUnfold.hs | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/compiler/coreSyn/CoreUnfold.hs b/compiler/coreSyn/CoreUnfold.hs index 6535d37307..2bb2b598f3 100644 --- a/compiler/coreSyn/CoreUnfold.hs +++ b/compiler/coreSyn/CoreUnfold.hs @@ -1287,6 +1287,23 @@ traceInline dflags inline_id str doc result | otherwise = result +-- | This is an awful but temporary workaround for #17615, where the +-- case analysis from the 'ufVeryAggressive' selector causes the entire +-- 'DynFlags' to be unpacked into local bindings (due to binder swap). This +-- results in a tremendous amount of stack spillage, severely bloating the code +-- generated for 'callSiteInline'. +-- +-- The right solution here is likely to fix binder swap to avoid this terrible +-- behavior (since there are likely other instances of this as well) but this +-- case was serious enough that it showed up in a CPU profile and consequently +-- I wanted to fix it for 8.10. +-- +-- The workaround avoids the binder swap transformation by preventing +-- 'ufVeryAggressive' from inlining into 'callSiteInline'. +very_aggressive :: DynFlags -> Bool +very_aggressive = ufVeryAggressive +{-# NOINLINE very_aggressive #-} + tryUnfolding :: DynFlags -> Id -> Bool -> [ArgSummary] -> CallCtxt -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance -> Maybe CoreExpr @@ -1297,7 +1314,7 @@ tryUnfolding dflags id lone_variable UnfNever -> traceInline dflags id str (text "UnfNever") Nothing UnfWhen { ug_arity = uf_arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok } - | enough_args && (boring_ok || some_benefit || ufVeryAggressive dflags) + | enough_args && (boring_ok || some_benefit || very_aggressive dflags) -- See Note [INLINE for small functions (3)] -> traceInline dflags id str (mk_doc some_benefit empty True) (Just unf_template) | otherwise @@ -1307,7 +1324,7 @@ tryUnfolding dflags id lone_variable enough_args = (n_val_args >= uf_arity) || (unsat_ok && n_val_args > 0) UnfIfGoodArgs { ug_args = arg_discounts, ug_res = res_discount, ug_size = size } - | ufVeryAggressive dflags + | very_aggressive dflags -> traceInline dflags id str (mk_doc some_benefit extra_doc True) (Just unf_template) | is_wf && some_benefit && small_enough -> traceInline dflags id str (mk_doc some_benefit extra_doc True) (Just unf_template) |