Commit da107045 authored by simonpj@microsoft.com's avatar simonpj@microsoft.com
Browse files

Be more conservative about duplicating continuations

Roman found that GHC was duplicating continuations that arose (essentially)
from uses of 'seq', or strict constructors.  This fixes the problem;
see the comments mkDupableCont (the Select case with a single alternative).

I'm a little concerned that this may also miss useful case-of-case
tranformations, so I'd like to know if anyone finds that this patch
makes performance worse.

To make it a bit more gung-ho, one could check for all the binders
being dead, before choosing this new, conservative alternative.
parent 098d99aa
...@@ -1826,6 +1826,43 @@ mkDupableCont env (ApplyTo _ arg mb_se cont) ...@@ -1826,6 +1826,43 @@ mkDupableCont env (ApplyTo _ arg mb_se cont)
; (floats2, arg2) <- mkDupableArg env arg1 ; (floats2, arg2) <- mkDupableArg env arg1
; return (floats2, (ApplyTo OkToDup arg2 Nothing dup_cont, nondup_cont)) }} ; return (floats2, (ApplyTo OkToDup arg2 Nothing dup_cont, nondup_cont)) }}
mkDupableCont env cont@(Select _ case_bndr [_] _ _)
= returnSmpl (emptyFloats env, (mkBoringStop scrut_ty, cont))
where
scrut_ty = substTy env (idType case_bndr)
-- This case is just like the previous one. Here's an example:
-- data T a = MkT !a
-- ...(MkT (abs x))...
-- Then we get
-- case (case x of I# x' ->
-- case x' <# 0# of
-- True -> I# (negate# x')
-- False -> I# x') of y {
-- DEFAULT -> MkT y
-- Because the (case x) has only one alternative, we'll transform to
-- case x of I# x' ->
-- case (case x' <# 0# of
-- True -> I# (negate# x')
-- False -> I# x') of y {
-- DEFAULT -> MkT y
-- But now we do *NOT* want to make a join point etc, giving
-- case x of I# x' ->
-- let $j = \y -> MkT y
-- in case x' <# 0# of
-- True -> $j (I# (negate# x'))
-- False -> $j (I# x')
-- In this case the $j will inline again, but suppose there was a big
-- strict computation enclosing the orginal call to MkT. Then, it won't
-- "see" the MkT any more, because it's big and won't get duplicated.
-- And, what is worse, nothing was gained by the case-of-case transform.
--
-- NB: Originally I matched [(DEFAULT,_,_)], but in the common
-- case of Int, the alternative-filling-in code turned the outer case into
-- case (...) of y { I# _ -> MkT y }
-- and that doesn't match the DEFAULT!
-- Now I match on any single-alternative case.
-- I hope that is the right thing to do!
mkDupableCont env (Select _ case_bndr alts se cont) mkDupableCont env (Select _ case_bndr alts se cont)
= -- e.g. (case [...hole...] of { pi -> ei }) = -- e.g. (case [...hole...] of { pi -> ei })
-- ===> -- ===>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment