[Git][ghc/ghc][wip/refactor-demand] 2 commits: Demand: Interleave usage and strictness demands (#18903)

Sebastian Graf gitlab at gitlab.haskell.org
Wed Nov 18 19:37:45 UTC 2020



Sebastian Graf pushed to branch wip/refactor-demand at Glasgow Haskell Compiler / GHC


Commits:
b8e7e479 by Sebastian Graf at 2020-11-18T20:28:24+01:00
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

- - - - -
e506b8c3 by Sebastian Graf at 2020-11-18T20:28:43+01:00
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.

- - - - -


30 changed files:

- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Core/Opt/CprAnal.hs
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/SetLevels.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Opt/SpecConstr.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Stg/Lift/Analysis.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Id.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Utils/Outputable.hs
- docs/users_guide/9.2.1-notes.rst
- docs/users_guide/debugging.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/using-optimisation.rst
- testsuite/tests/arityanal/should_compile/Arity01.stderr
- testsuite/tests/arityanal/should_compile/Arity02.stderr
- testsuite/tests/arityanal/should_compile/Arity03.stderr
- testsuite/tests/arityanal/should_compile/Arity04.stderr
- testsuite/tests/arityanal/should_compile/Arity05.stderr
- testsuite/tests/arityanal/should_compile/Arity09.stderr
- testsuite/tests/arityanal/should_compile/Arity11.stderr
- testsuite/tests/arityanal/should_compile/Arity14.stderr


The diff was not included because it is too large.


View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff04b6e387cde4f6f6bfc2959443d4e9f3f96990...e506b8c37f0ebcabc2d6e30f2d073b15b37a65b1

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ff04b6e387cde4f6f6bfc2959443d4e9f3f96990...e506b8c37f0ebcabc2d6e30f2d073b15b37a65b1
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20201118/73ecaac6/attachment.html>


More information about the ghc-commits mailing list