Skip to content

DmdAnal: Annotate some top-level bindings with demands (#18894)

Sebastian Graf requested to merge wip/T18894 into master

It's useful to annotate a non-exported top-level function like g in

module Lib (h) where

g :: Int -> Int -> (Int,Int)
g m 1 = (m, 0)
g m n = (2 * m, 2 `div` n)
{-# NOINLINE g #-}

h :: Int -> Int
h 1 = 0
h m
  | odd m     = snd (g m 2)
  | otherwise = uncurry (+) (g 2 m)

with its demand UCU(CS(P(1P(U),SP(U)), which tells us that whenever g was called, the second component of the returned pair was evaluated strictly.

Since #18903 (closed) we do so for local functions, where we can see all calls. For top-level functions, we can assume that all exported functions are demanded according to topDmd and thus get sound demands for non-exported top-level functions.

The demand on g is crucial information for Nested CPR, which may the go on and unbox g for the second pair component. That is true even if that pair component may diverge, as is the case for the call site g 13 0, which throws a div-by-zero exception.

We only track bindings of function type in order not to risk huge compile-time regressions, see isInterestingTopLevelFn.

Fixes #18894 (closed).

Edited by Sebastian Graf

Merge request reports