<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html lang="en">
<head>
<meta content="text/html; charset=US-ASCII" http-equiv="Content-Type">
<title>
GitLab
</title>
<style>img {
max-width: 100%; height: auto;
}
</style>
</head>
<body>
<div class="content">
<h3>
Sebastian Graf pushed to branch wip/refactor-demand
at <a href="https://gitlab.haskell.org/ghc/ghc">Glasgow Haskell Compiler / GHC</a>
</h3>
<h4>
Commits:
</h4>
<ul>
<li>
<strong><a href="https://gitlab.haskell.org/ghc/ghc/-/commit/b8e7e4794e542e882da5d6ef668bb160718bec46">b8e7e479</a></strong>
<div>
<span>by Sebastian Graf</span>
<i>at 2020-11-18T20:28:24+01:00</i>
</div>
<pre class="commit-message" style="white-space: pre-wrap; margin: 0;">Demand: Interleave usage and strictness demands (#18903)
As outlined in #18903, interleaving usage and strictness demands not
only means a more compact demand representation, but also allows us to
express demands that we weren't easily able to express before.
Call demands
============
Call demands are *relative* in the sense that a call demand `Cn(cd)`
on `g` says "`g` is called `n` times. *Whenever `g` is called*, the
result is used according to `cd`". Example from #18903:
```hs
h :: Int -> Int
h m =
let g :: Int -> (Int,Int)
g 1 = (m, 0)
g n = (2 * n, 2 `div` n)
{-# NOINLINE g #-}
in case m of
1 -> 0
2 -> snd (g m)
_ -> uncurry (+) (g m)
```
Without the interleaved representation, we would just get `L` for the
strictness demand on `g`. Now we are able to express that whenever
`g` is called, its second component is used strictly in denoting `g`
by `1C1((1(U),S(U)))`. This would allow Nested CPR to unbox the
division, for example.
Nested strict product demands
=============================
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 #18903 and fixes #18885.
While fixing regressions, I also discovered and fixed #18957.
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
Metric Decrease:
T13253-spj
</pre>
</li>
<li>
<strong><a href="https://gitlab.haskell.org/ghc/ghc/-/commit/e506b8c37f0ebcabc2d6e30f2d073b15b37a65b1">e506b8c3</a></strong>
<div>
<span>by Sebastian Graf</span>
<i>at 2020-11-18T20:28:43+01:00</i>
</div>
<pre class="commit-message" style="white-space: pre-wrap; margin: 0;">Update user's guide entry on demand analysis and worker/wrapper
The demand signature notation has been undocumented for a long time.
The only source to understand it, apart from reading the `Outputable`
instance, has been an outdated wiki page.
Since the previous commits have reworked the demand lattice, I took
it as an opportunity to also write some documentation about notation.
</pre>
</li>
</ul>
<h4>30 changed files:</h4>
<ul>
<li class="file-stats">
<a href="#451725cc4e5d443a3b7c2adcdf224840f953b7e2">
compiler/GHC/Builtin/primops.txt.pp
</a>
</li>
<li class="file-stats">
<a href="#c1bf6b849619bc8d7ef37a97d993dbfaa9966f7b">
compiler/GHC/Core/Opt/CprAnal.hs
</a>
</li>
<li class="file-stats">
<a href="#8104fa1b71db6cfc4eb90cd769463d9eb9004619">
compiler/GHC/Core/Opt/DmdAnal.hs
</a>
</li>
<li class="file-stats">
<a href="#bd153f89bc48f3fd5079b51fb799808aacbd750c">
compiler/GHC/Core/Opt/Pipeline.hs
</a>
</li>
<li class="file-stats">
<a href="#cc763cdd1967f5d921161a32f64136cfcf0332c5">
compiler/GHC/Core/Opt/SetLevels.hs
</a>
</li>
<li class="file-stats">
<a href="#f168a93cde5e2aec2441d6331dfe500172df4af3">
compiler/GHC/Core/Opt/Simplify.hs
</a>
</li>
<li class="file-stats">
<a href="#48fbb5cdea308650de5756521feb28ec68819b9b">
compiler/GHC/Core/Opt/Simplify/Utils.hs
</a>
</li>
<li class="file-stats">
<a href="#b6a5ba32bafb8fbda933538b3007e755fef6f101">
compiler/GHC/Core/Opt/SpecConstr.hs
</a>
</li>
<li class="file-stats">
<a href="#f4421b4e35592648510c877ecf55b1af2b96dcee">
compiler/GHC/Core/Opt/WorkWrap/Utils.hs
</a>
</li>
<li class="file-stats">
<a href="#d79a8a61508cb6c5f38a23ab2b691bb77306f672">
compiler/GHC/CoreToStg.hs
</a>
</li>
<li class="file-stats">
<a href="#a5d27de4e3111a69f69902c65ecf7b3379f7c49a">
compiler/GHC/CoreToStg/Prep.hs
</a>
</li>
<li class="file-stats">
<a href="#079d6b28856775716c78fdd4a4b35bb45a59002c">
compiler/GHC/Iface/Syntax.hs
</a>
</li>
<li class="file-stats">
<a href="#657eec52eed3c8be846a0b60eb6088d5f465de8a">
compiler/GHC/Stg/Lift/Analysis.hs
</a>
</li>
<li class="file-stats">
<a href="#d09e98aae6ad2eb59d08eac7894b68c0ab820cda">
compiler/GHC/Types/Demand.hs
</a>
</li>
<li class="file-stats">
<a href="#20aaf8344f379f354fe31dd0c1c4db4ddc5b17aa">
compiler/GHC/Types/Id.hs
</a>
</li>
<li class="file-stats">
<a href="#38110817cdbc9a34d2b80a14070cabc7515c808a">
compiler/GHC/Types/Id/Info.hs
</a>
</li>
<li class="file-stats">
<a href="#261c0c5029eb34eb7436b087d77314f377ff8223">
compiler/GHC/Types/Id/Make.hs
</a>
</li>
<li class="file-stats">
<a href="#d3cf57b6a5ebc234dc7689db38ef9b6cf2259c0f">
compiler/GHC/Utils/Outputable.hs
</a>
</li>
<li class="file-stats">
<a href="#d87dfc77856eeaef6134e28336290ddcbcf18d7d">
docs/users_guide/9.2.1-notes.rst
</a>
</li>
<li class="file-stats">
<a href="#36435f993774454b5956f3a38a9276ed176c61cc">
docs/users_guide/debugging.rst
</a>
</li>
<li class="file-stats">
<a href="#ed75822e0b6142f196a6abeb623c7669d31b4711">
docs/users_guide/exts/instances.rst
</a>
</li>
<li class="file-stats">
<a href="#2e45f2cd303dd998950a7c8042e796a5b2abd64f">
docs/users_guide/using-optimisation.rst
</a>
</li>
<li class="file-stats">
<a href="#46fdea7197af7a69a0a0d1b96b0a0dab860a614b">
testsuite/tests/arityanal/should_compile/Arity01.stderr
</a>
</li>
<li class="file-stats">
<a href="#d17dc73d83ae4f8e388a6375f61874dd8423a3d7">
testsuite/tests/arityanal/should_compile/Arity02.stderr
</a>
</li>
<li class="file-stats">
<a href="#10626459c163674d3f8465668ecf305d97f16d41">
testsuite/tests/arityanal/should_compile/Arity03.stderr
</a>
</li>
<li class="file-stats">
<a href="#6bde466587e782a5b7fd61f10ce3a979706ec4aa">
testsuite/tests/arityanal/should_compile/Arity04.stderr
</a>
</li>
<li class="file-stats">
<a href="#e2f6b12889757561d508a64f69d28577e96df813">
testsuite/tests/arityanal/should_compile/Arity05.stderr
</a>
</li>
<li class="file-stats">
<a href="#943adaed1cf65cfe70778088aad52155f98e4206">
testsuite/tests/arityanal/should_compile/Arity09.stderr
</a>
</li>
<li class="file-stats">
<a href="#2779dd39638d332b4347f082443df52a088814ec">
testsuite/tests/arityanal/should_compile/Arity11.stderr
</a>
</li>
<li class="file-stats">
<a href="#e866e357dffcf10a28dffedc3e9b7a5fc972bbef">
testsuite/tests/arityanal/should_compile/Arity14.stderr
</a>
</li>
</ul>
<h5>The diff was not included because it is too large.</h5>
</div>
<div class="footer" style="margin-top: 10px;">
<p style="font-size: small; color: #666;">
—
<br>
<a href="https://gitlab.haskell.org/ghc/ghc/-/compare/ff04b6e387cde4f6f6bfc2959443d4e9f3f96990...e506b8c37f0ebcabc2d6e30f2d073b15b37a65b1">View it on GitLab</a>.
<br>
You're receiving this email because of your account on gitlab.haskell.org.
If you'd like to receive fewer emails, you can
adjust your notification settings.
</p>
</div>
</body>
</html>