Skip to content

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?

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information