diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2022-11-14 17:40:01 +0100 |
---|---|---|
committer | Sebastian Graf <sebastian.graf@kit.edu> | 2023-01-12 13:23:32 +0100 |
commit | 0f67ccdd1dc5aa9e04f9fd777705bc76ddd1ae05 (patch) | |
tree | 75b9dba22cc7c892df1251ab0126541e0429ce8e /compiler/GHC/Utils/Misc.hs | |
parent | b3be0d185b6e597fa517859430cf6d54df04ca46 (diff) | |
download | haskell-wip/T22428.tar.gz |
Fix contification with stable unfoldings (#22428)wip/T22428
Many functions now return a `TailUsageDetails` that adorns a `UsageDetails` with
a `JoinArity` that reflects the number of join point binders around the body
for which the `UsageDetails` was computed. `TailUsageDetails` is now returned by
`occAnalLamTail` as well as `occAnalUnfolding` and `occAnalRules`.
I adjusted `Note [Join points and unfoldings/rules]` and
`Note [Adjusting right-hand sides]` to account for the new machinery.
I also wrote a new `Note [Join arity prediction based on joinRhsArity]`
and refer to it when we combine `TailUsageDetails` for a recursive RHS.
I also renamed
* `occAnalLam` to `occAnalLamTail`
* `adjustRhsUsage` to `adjustTailUsage`
* a few other less important functions
and properly documented the that each call of `occAnalLamTail` must pair up with
`adjustTailUsage`.
I removed `Note [Unfoldings and join points]` because it was redundant with
`Note [Occurrences in stable unfoldings]`.
While in town, I refactored `mkLoopBreakerNodes` so that it returns a condensed
`NodeDetails` called `SimpleNodeDetails`.
Fixes #22428.
The refactoring seems to have quite beneficial effect on ghc/alloc performance:
```
CoOpt_Read(normal) ghc/alloc 784,778,420 768,091,176 -2.1% GOOD
T12150(optasm) ghc/alloc 77,762,270 75,986,720 -2.3% GOOD
T12425(optasm) ghc/alloc 85,740,186 84,641,712 -1.3% GOOD
T13056(optasm) ghc/alloc 306,104,656 299,811,632 -2.1% GOOD
T13253(normal) ghc/alloc 350,233,952 346,004,008 -1.2%
T14683(normal) ghc/alloc 2,800,514,792 2,754,651,360 -1.6%
T15304(normal) ghc/alloc 1,230,883,318 1,215,978,336 -1.2%
T15630(normal) ghc/alloc 153,379,590 151,796,488 -1.0%
T16577(normal) ghc/alloc 7,356,797,056 7,244,194,416 -1.5%
T17516(normal) ghc/alloc 1,718,941,448 1,692,157,288 -1.6%
T19695(normal) ghc/alloc 1,485,794,632 1,458,022,112 -1.9%
T21839c(normal) ghc/alloc 437,562,314 431,295,896 -1.4% GOOD
T21839r(normal) ghc/alloc 446,927,580 440,615,776 -1.4% GOOD
geo. mean -0.6%
minimum -2.4%
maximum -0.0%
```
Metric Decrease:
CoOpt_Read
T10421
T12150
T12425
T13056
T18698a
T18698b
T21839c
T21839r
T9961
Diffstat (limited to 'compiler/GHC/Utils/Misc.hs')
-rw-r--r-- | compiler/GHC/Utils/Misc.hs | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/compiler/GHC/Utils/Misc.hs b/compiler/GHC/Utils/Misc.hs index a115c61336..09111ccc47 100644 --- a/compiler/GHC/Utils/Misc.hs +++ b/compiler/GHC/Utils/Misc.hs @@ -35,7 +35,7 @@ module GHC.Utils.Misc ( equalLength, compareLength, leLength, ltLength, isSingleton, only, expectOnly, GHC.Utils.Misc.singleton, - notNull, snocView, + notNull, expectNonEmpty, snocView, chunkList, @@ -481,7 +481,6 @@ expectOnly _ (a:_) = a #endif expectOnly msg _ = panic ("expectOnly: " ++ msg) - -- | Split a list into chunks of /n/ elements chunkList :: Int -> [a] -> [[a]] chunkList _ [] = [] @@ -500,6 +499,16 @@ changeLast [] _ = panic "changeLast" changeLast [_] x = [x] changeLast (x:xs) x' = x : changeLast xs x' +-- | Like @expectJust msg . nonEmpty@; a better alternative to 'NE.fromList'. +expectNonEmpty :: HasCallStack => String -> [a] -> NonEmpty a +{-# INLINE expectNonEmpty #-} +expectNonEmpty _ (x:xs) = x:|xs +expectNonEmpty msg [] = expectNonEmptyPanic msg + +expectNonEmptyPanic :: String -> a +expectNonEmptyPanic msg = panic ("expectNonEmpty: " ++ msg) +{-# NOINLINE expectNonEmptyPanic #-} + -- | Apply an effectful function to the last list element. mapLastM :: Functor f => (a -> f a) -> NonEmpty a -> f (NonEmpty a) mapLastM f (x:|[]) = NE.singleton <$> f x |