<!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/c642a43abf2bbf766cc97ebd090e022e811eeabe">c642a43a</a></strong>
<div>
<span>by Sebastian Graf</span>
<i>at 2020-11-11T16:14:02+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.
</pre>
</li>
<li>
<strong><a href="https://gitlab.haskell.org/ghc/ghc/-/commit/3d2d37c6d70a93854090a91467e5987102e4d4d7">3d2d37c6</a></strong>
<div>
<span>by Sebastian Graf</span>
<i>at 2020-11-11T16:14:02+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: #777;">

<br>
<a href="https://gitlab.haskell.org/ghc/ghc/-/compare/390a17c5723c37c8f259d3fe60824933449a8a1b...3d2d37c6d70a93854090a91467e5987102e4d4d7">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>