WorkWrap: Clarify how `-ffun-to-thunk` creates space leaks
Currently, the user's guide states:
Worker-wrapper removes unused arguments, but usually we do not remove them all, lest it turn a function closure into a thunk, thereby perhaps creating a space leak and/or disrupting inlining. This flag allows worker/wrapper to remove all value lambdas.
I don't really understand how turning a function into a thunk introduces space leaks. Operationally, the only difference is in memoisation. So my question is akin to asking:
How can memoising the result of a function f :: Void# -> r
introduce a space leak when simply retaining the closure of f
does not? Perhaps something to do with the closure of the returned r
object, a large list maybe. Can we give a succinct example that demonstrates an ever increasing residency with -ffun-to-thunk
vs without? Can we perhaps find a different work-around for the problem?
Besides, I tried the following program:
f :: Int -> Int
f x = sum (g x) + sum [0..x] + sum (g (x+2))
where
g _ = [0..x]
{-# NOINLINE g #-}
and even without -ffun-to-thunk
, we get
$wf
= \ ww_s1In ->
let { lvl_s1J6 = eftInt 0# ww_s1In } in
let { $wg_s1HW = \ @ p_s1HU (_ :: Void#) -> lvl_s1J6 } in
...
So even though we don't make $wg
into a thunk, we still float out a thunk out of $wg
's constant body. So it appears -ffun-to-thunk
doesn't have any effect after all?