Skip to content
  • Sebastian Graf's avatar
    Demand: Interleave usage and strictness demands (#18903) · 0aec78b6
    Sebastian Graf authored and Marge Bot's avatar Marge Bot committed
    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 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(P(1P(U),SP(U)))`. This would allow Nested CPR to unbox the
    division, for example.
    
    Fixes #18903.
    While fixing regressions, I also discovered and fixed #18957.
    
    Metric Decrease:
        T13253-spj
    0aec78b6