Repository : ssh://darcs.haskell.org//srv/darcs/ghc On branch : new-demand
http://hackage.haskell.org/trac/ghc/changeset/eac90c6371bf78af8a6b6778de1f8c8171d73cbc >--------------------------------------------------------------- commit eac90c6371bf78af8a6b6778de1f8c8171d73cbc Author: Ilya Sergey <[email protected]> Date: Mon Aug 13 16:00:13 2012 +0100 missing commentary on WW split added >--------------------------------------------------------------- compiler/stranal/NewWorkWrap.lhs | 52 +++++++++++++++++++++++++++++++++++++- 1 files changed, 51 insertions(+), 1 deletions(-) diff --git a/compiler/stranal/NewWorkWrap.lhs b/compiler/stranal/NewWorkWrap.lhs index 6c3dbd8..a8261e4 100644 --- a/compiler/stranal/NewWorkWrap.lhs +++ b/compiler/stranal/NewWorkWrap.lhs @@ -461,9 +461,10 @@ worthSplittingFun ds res = any worth_it ds || returnsCPR res -- worthSplitting returns False for an empty list of demands, -- and hence do_strict_ww is False if arity is zero and there is no CPR - -- See Note [Worker-wrapper for bottoming functions] where + -- See Note [Worker-wrapper for bottoming functions] worth_it (JD {strd=HyperStr, absd=a}) = isUsed a -- A Hyper-strict argument, safe to do W/W + -- See not [Worthy functions for Worker-Wrapper split] worth_it (JD {strd=SProd _, absd=a}) = isUsed a -- Product arg to evaluate worth_it (JD {strd=Str, absd=UProd _}) = True -- Strictly used product arg worth_it (JD {absd=Abs}) = True -- Absent arg @@ -481,6 +482,55 @@ worthSplittingThunk dmd res worth_it _ = False \end{code} +Note [Worthy functions for Worker-Wrapper split] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For non-bottoming functions a worker-wrapper transformation takes into +account several possibilities to decide if the function is worthy for +splitting: + +1. The result is of product type and the function is strict in some +(or even all) of its arguments. The check that the argument is used is +more of sanity nature, since strictness implies usage. Example: + +f :: (Int, Int) -> Int +f p = (case p of (a,b) -> a) + 1 + +should be splitted to + +f :: (Int, Int) -> Int +f p = case p of (a,b) -> $wf a + +$wf :: Int -> Int +$wf a = a + 1 + +2. Sometimes it also makes sense to perform a WW split if the +strictness analysis cannot say for sure if the function is strict in +components of its argument. Then we reason according to the inferred +usage information: if the function uses its product argument's +components, the WW split can be beneficial. Example: + +g :: Bool -> (Int, Int) -> Int +g c p = case p of (a,b) -> + if c then a else b + +The function g is strict in is argument p and lazy in its +components. However, both components are used in the RHS. The idea is +since some of the components (both in this case) are used in the +right-hand side, the product must presumable be taken apart. + +Therefore, the WW transform splits the function g to + +g :: Bool -> (Int, Int) -> Int +g c p = case p of (a,b) -> $wg c a b + +$wg :: Bool -> Int -> Int -> Int +$wg c a b = if c then a else b + +3. If an argument is absent, it would be silly to pass it to a +function, hence the worker with reduced arity is generated. + + Note [Worker-wrapper for bottoming functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used not to split if the result is bottom. _______________________________________________ Cvs-ghc mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-ghc
