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

Try harder to avoid making a variable with RULES into a loop-breaker

See Note [Recursive rules] in OccurAnal
parent 41cd72b3
......@@ -300,16 +300,18 @@ reOrderCycle bndrs (bind : binds)
-- where df is the exported dictionary. Then df makes a really
-- bad choice for loop breaker
| is_con_app rhs = 3 -- Data types help with cases
| idHasRules bndr = 3
-- Avoid things with specialisations; we'd like
-- to take advantage of them in the subsequent bindings
-- Also vital to avoid risk of divergence:
-- Note [Recursive rules]
| is_con_app rhs = 2 -- Data types help with cases
-- This used to have a lower score than inlineCandidate, but
-- it's *really* helpful if dictionaries get inlined fast,
-- so I'm experimenting with giving higher priority to data-typed things
| inlineCandidate bndr rhs = 2 -- Likely to be inlined
| idHasRules bndr = 1
-- Avoid things with specialisations; we'd like
-- to take advantage of them in the subsequent bindings
| inlineCandidate bndr rhs = 1 -- Likely to be inlined
| otherwise = 0
......@@ -352,6 +354,25 @@ makeLoopBreaker bndrs rhs_usg bndr
rules_only = bndrs `intersectsUFM` rhs_usg
\end{code}
Note [Recursive rules]
~~~~~~~~~~~~~~~~~~~~~~
Consider this group, which is typical of what SpecConstr builds:
fs a = ....f (C a)....
f x = ....f (C a)....
{-# RULE f (C a) = fs a #-}
So 'f' and 'fs' are mutually recursive. If we choose 'fs' as the loop breaker,
all is well; the RULE is applied, and 'fs' becomes self-recursive.
But if we choose 'f' as the loop breaker, we may get an infinite loop:
- the RULE is applied in f's RHS (see Note [Self-recursive rules] in Simplify
- fs is inlined (say it's small)
- now there's another opportunity to apply the RULE
So it's very important to choose the RULE-variable as the loop breaker.
This showed up when compiling Control.Concurrent.Chan.getChanContents.
Note [Closure conversion]
~~~~~~~~~~~~~~~~~~~~~~~~~
We treat (\x. C p q) as a high-score candidate in the letrec scoring algorithm.
......
......@@ -952,6 +952,8 @@ completeCall env var cont
-- the wrapper didn't occur for things that have specialisations till a
-- later phase, so but now we just try RULES first
--
-- Note [Self-recursive rules]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- You might think that we shouldn't apply rules for a loop breaker:
-- doing so might give rise to an infinite loop, because a RULE is
-- rather like an extra equation for the function:
......
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