Commit d56631cb authored by simonpj@microsoft.com's avatar simonpj@microsoft.com

Comments only in OccurAnal

parent 7aae56e3
......@@ -171,8 +171,8 @@ However things are made quite a bit more complicated by RULES. Remember
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We avoid infinite inlinings by choosing loop breakers, and
ensuring that a loop breaker cuts each loop. But what is a
"loop"? In particular, a RULES is like an equation for 'f' that
is *always* inlined if it are applicable. We do *not* disable
"loop"? In particular, a RULE is like an equation for 'f' that
is *always* inlined if it is applicable. We do *not* disable
rules for loop-breakers. It's up to whoever makes the rules to
make sure that the rules themselves alwasys terminate. See Note
[Rules for recursive functions] in Simplify.lhs
......@@ -237,8 +237,9 @@ However things are made quite a bit more complicated by RULES. Remember
* Note [Rule dependency info]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The VarSet in a SpecInfo is used for dependency analysis in the
occurrence analyser. We must track free vars in *both* lhs and rhs. Why both?
Consider
occurrence analyser. We must track free vars in *both* lhs and rhs.
Hence use of idRuleVars, rather than idRuleRhsVars in addRuleUsage.
Why both? Consider
x = y
RULE f x = 4
Then if we substitute y for x, we'd better do so in the
......@@ -509,7 +510,7 @@ reOrderCycle (bind : binds)
-- bad choice for loop breaker
| is_con_app rhs = 3 -- Data types help with cases
-- Note [conapp]
-- Note [Constructor applictions]
-- If an Id is marked "never inline" then it makes a great loop breaker
-- The only reason for not checking that here is that it is rare
......@@ -560,22 +561,24 @@ reOrderCycle (bind : binds)
is_con_app _ = False
makeLoopBreaker :: Bool -> Id -> Id
-- Set the loop-breaker flag
-- See Note [Weak loop breakers]
-- Set the loop-breaker flag: see Note [Weak loop breakers]
makeLoopBreaker weak bndr = setIdOccInfo bndr (IAmALoopBreaker weak)
\end{code}
Note [Worker inline loop]
~~~~~~~~~~~~~~~~~~~~~~~~
Never choose a wrapper as the loop breaker! Because
wrappers get auto-generated inlinings when importing, and
that can lead to an infinite inlining loop. For example:
Note [INLINE pragmas]
~~~~~~~~~~~~~~~~~~~~~
Never choose a function with an INLINE pramga as the loop breaker!
If such a function is mutually-recursive with a non-INLINE thing,
then the latter should be the loop-breaker.
A particular case is wrappers generated by the demand analyser.
If you make then into a loop breaker you may get an infinite
inlining loop. For example:
rec {
$wfoo x = ....foo x....
{-loop brk-} foo x = ...$wfoo x...
}
The interface file sees the unfolding for $wfoo, and sees that foo is
strict (and hence it gets an auto-generated wrapper). Result: an
infinite inlining in the importing scope. So be a bit careful if you
......@@ -584,6 +587,22 @@ nofib/spectral/minimax. If the repTree wrapper is chosen as the loop
breaker then compiling Game.hs goes into an infinite loop (this
happened when we gave is_con_app a lower score than inline candidates).
Note [Constructor applications]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It's really really important to inline dictionaries. Real
example (the Enum Ordering instance from GHC.Base):
rec f = \ x -> case d of (p,q,r) -> p x
g = \ x -> case d of (p,q,r) -> q x
d = (v, f, g)
Here, f and g occur just once; but we can't inline them into d.
On the other hand we *could* simplify those case expressions if
we didn't stupidly choose d as the loop breaker.
But we won't because constructor args are marked "Many".
Inlining dictionaries is really essential to unravelling
the loops in static numeric dictionaries, see GHC.Float.
Note [Closure conversion]
~~~~~~~~~~~~~~~~~~~~~~~~~
We treat (\x. C p q) as a high-score candidate in the letrec scoring algorithm.
......@@ -657,10 +676,14 @@ addRuleUsage :: UsageDetails -> Id -> UsageDetails
-- Add the usage from RULES in Id to the usage
addRuleUsage usage id
= foldVarSet add usage (idRuleVars id)
-- idRuleVars here: see Note [Rule dependency info]
where
add v u = addOneOcc u v NoOccInfo -- Give a non-committal binder info
-- (i.e manyOcc) because many copies
-- of the specialised thing can appear
add v u = addOneOcc u v NoOccInfo
-- Give a non-committal binder info (i.e manyOcc) because
-- a) Many copies of the specialised thing can appear
-- b) We don't want to substitute a BIG expression inside a RULE
-- even if that's the only occurrence of the thing
-- (Same goes for INLINE.)
\end{code}
Expressions
......
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