summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2022-08-13 14:58:14 +0200
committerAndreas Klebinger <klebinger.andreas@gmx.at>2022-08-13 19:25:24 +0200
commit3372c54cadb9b4fdf74c909de36d43bc2309a8c8 (patch)
tree3ce4ebcf34775d1b5ee9ad6be76160a438f3a655
parentdca43a04fb36e0ae0ed61455f215660eed2856a9 (diff)
downloadhaskell-wip/andreask/opt-calcUnfolding.tar.gz
Optimize calcUnfoldingGuidance to avoid eagerly evaluating expression size.wip/andreask/opt-calcUnfolding
There is also no point in calcUnfoldingGuidance handling Ticks since it's handlined inside sizeExpr already. So I removed that as well.
-rw-r--r--compiler/GHC/Core/Unfold.hs57
1 files changed, 27 insertions, 30 deletions
diff --git a/compiler/GHC/Core/Unfold.hs b/compiler/GHC/Core/Unfold.hs
index 017a733ec0..d68cc67120 100644
--- a/compiler/GHC/Core/Unfold.hs
+++ b/compiler/GHC/Core/Unfold.hs
@@ -57,7 +57,6 @@ import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Types.ForeignCall
import GHC.Types.Name
-import GHC.Types.Tickish
import qualified Data.ByteString as BS
import Data.List (isPrefixOf)
@@ -231,44 +230,42 @@ calcUnfoldingGuidance
-> Bool -- Definitely a top-level, bottoming binding
-> CoreExpr -- Expression to look at
-> UnfoldingGuidance
-calcUnfoldingGuidance opts is_top_bottoming (Tick t expr)
- | not (tickishIsCode t) -- non-code ticks don't matter for unfolding
- = calcUnfoldingGuidance opts is_top_bottoming expr
calcUnfoldingGuidance opts is_top_bottoming expr
- = case sizeExpr opts bOMB_OUT_SIZE val_bndrs body of
- TooBig -> UnfNever
- SizeIs size cased_bndrs scrut_discount
- | uncondInline expr n_val_bndrs size
- -> UnfWhen { ug_unsat_ok = unSaturatedOk
- , ug_boring_ok = boringCxtOk
- , ug_arity = n_val_bndrs } -- Note [INLINE for small functions]
-
- | is_top_bottoming
- -> UnfNever -- See Note [Do not inline top-level bottoming functions]
-
- | otherwise
- -> UnfIfGoodArgs { ug_args = map (mk_discount cased_bndrs) val_bndrs
- , ug_size = size
- , ug_res = scrut_discount }
-
+ -- See Note [Do not inline top-level bottoming functions]
+ | is_top_bottoming = UnfNever
+ | otherwise = calc opts expr
where
+ calc !opts !expr
+ = case sizeExpr opts bOMB_OUT_SIZE val_bndrs body of
+ TooBig -> UnfNever
+ SizeIs size cased_bndrs scrut_discount
+ | uncondInline expr n_val_bndrs size
+ -> UnfWhen { ug_unsat_ok = unSaturatedOk
+ , ug_boring_ok = boringCxtOk
+ , ug_arity = n_val_bndrs } -- Note [INLINE for small functions]
+
+ | otherwise
+ -> UnfIfGoodArgs { ug_args = map (mk_discount cased_bndrs) val_bndrs
+ , ug_size = size
+ , ug_res = scrut_discount }
+
(bndrs, body) = collectBinders expr
bOMB_OUT_SIZE = unfoldingCreationThreshold opts
- -- Bomb out if size gets bigger than this
+ -- Bomb out if size gets bigger than this
val_bndrs = filter isId bndrs
n_val_bndrs = length val_bndrs
mk_discount :: Bag (Id,Int) -> Id -> Int
mk_discount cbs bndr = foldl' combine 0 cbs
- where
- combine acc (bndr', disc)
- | bndr == bndr' = acc `plus_disc` disc
- | otherwise = acc
-
- plus_disc :: Int -> Int -> Int
- plus_disc | isFunTy (idType bndr) = max
- | otherwise = (+)
- -- See Note [Function and non-function discounts]
+ where
+ combine acc (bndr', disc)
+ | bndr == bndr' = acc `plus_disc` disc
+ | otherwise = acc
+
+ plus_disc :: Int -> Int -> Int
+ plus_disc | isFunTy (idType bndr) = max
+ | otherwise = (+)
+ -- See Note [Function and non-function discounts]
{- Note [Inline unsafeCoerce]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~