diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2020-10-30 17:20:37 +0100 |
---|---|---|
committer | Sebastian Graf <sebastian.graf@kit.edu> | 2020-11-20 09:48:01 +0100 |
commit | c90df9e3b0d7551e2de1e1571ad358e91f625ccc (patch) | |
tree | 17387b83d903a5495eaa5d55431e6b807e079326 /docs/users_guide/using-optimisation.rst | |
parent | 802e9180dd9a9a88c4e8869f0de1048e1edd6343 (diff) | |
download | haskell-wip/T18885.tar.gz |
Demand: Nested strict product demands (#18885)wip/T18885
Fixing #18903 gives us enough expressiveness to tackle #18885, where we
have
```hs
f :: Int -> Int
f y =
let x
| expensive y == 1 = (expensive (y+1), expensive (y+2))
| otherwise = (expensive (y+3), expensive (y+4))
in case () of
_ | expensive (y+5) == 42 -> fst x
_ | expensive (y+6) == 41 -> fst x + snd x
_ | otherwise -> 0
```
Here, we used to give `x` demand `1P(1P(U),1P(U))`. The outer `1`
is because `x` is used lazily and the inner `1`s are redundant with
that fact. That leaves some expressiveness on the table. After this
change, we infer `1P(SP(U),1P(U))`, meaning that *whenever we evaluate
`x`*, we evaluate its first component strictly, effectively making
strictness product demands apply *relatively*. Usage product demands
still apply absolutely, though.
More details on how we could exploit the new language in
`Note [Absent sub-demands]`.
Fixes #18885.
There's a single remaining regression in `T9630`, which increases +16%
in residency but decreases slightly in total allocations. I checked
the heap profile, which doesn't suggest any obvious regressions.
Ticky doesn't point to the reason either, because total allocations
actually improved. I think it's OK to just accept it.
Metric Increase:
T9630
Diffstat (limited to 'docs/users_guide/using-optimisation.rst')
-rw-r--r-- | docs/users_guide/using-optimisation.rst | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/docs/users_guide/using-optimisation.rst b/docs/users_guide/using-optimisation.rst index 8fec4f1a7b..8bb5870adc 100644 --- a/docs/users_guide/using-optimisation.rst +++ b/docs/users_guide/using-optimisation.rst @@ -1268,11 +1268,13 @@ by saying ``-fno-wombat``. maybe n _ Nothing = n maybe _ s (Just a) = s a - We give it demand signature ``<U><1C1(U)><SU>``. The ``C1(U)`` is a *call - sub-demand* that says "Called at most once, where the result is used - according to ``U``". The expression ``f `seq` f 1 2`` puts ``f`` under - demand ``MCS(U)`` and serves as an example where the upper bound on - evaluation cardinality doesn't conincide with that of the call cardinality. + We give it demand signature ``<U><1CS(U)><SU>``. The ``CS(U)`` is a + *call sub-demand* that applies when the surrounding demand is evaluated + at all. It says "If evaluated, the thing is called exactly once, where + the result is used according to ``U``". The expression ``f `seq` f 1 2`` + puts ``f`` under demand ``MCS(U)`` and serves as an example where the + upper bound on evaluation cardinality doesn't conincide with that of + the call cardinality. Cardinality is always relative to the enclosing call cardinality, so ``g 1 2 + g 3 4`` puts ``g`` under demand ``MCM(CS(U))``, which says |