Commit 891ffd58 authored by Simon Peyton Jones's avatar Simon Peyton Jones

Comments only, about exitifcation

parent c2f90c84
...@@ -498,7 +498,7 @@ isJoinId_maybe id ...@@ -498,7 +498,7 @@ isJoinId_maybe id
_ -> Nothing _ -> Nothing
| otherwise = Nothing | otherwise = Nothing
-- see Note [Exitification] and see Note [Do not inline exit join points] -- See Note [Exitification] and Note [Do not inline exit join points] in Exitify.hs
isExitJoinId :: Var -> Bool isExitJoinId :: Var -> Bool
isExitJoinId id = isJoinId id && isOneOcc (idOccInfo id) && occ_in_lam (idOccInfo id) isExitJoinId id = isJoinId id && isOneOcc (idOccInfo id) && occ_in_lam (idOccInfo id)
......
...@@ -250,7 +250,6 @@ type ExitifyM = State [(JoinId, CoreExpr)] ...@@ -250,7 +250,6 @@ type ExitifyM = State [(JoinId, CoreExpr)]
{- {-
Note [Interesting expression] Note [Interesting expression]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We do not want this to happen: We do not want this to happen:
joinrec go 0 x y = x joinrec go 0 x y = x
...@@ -291,7 +290,6 @@ non-imported variable. ...@@ -291,7 +290,6 @@ non-imported variable.
Note [Jumps can be interesting] Note [Jumps can be interesting]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A jump to a join point can be interesting, if its arguments contain free A jump to a join point can be interesting, if its arguments contain free
non-exported variables (z in the following example): non-exported variables (z in the following example):
...@@ -304,16 +302,34 @@ non-exported variables (z in the following example): ...@@ -304,16 +302,34 @@ non-exported variables (z in the following example):
go (n-1) x y = jump go (n-1) (x+y) go (n-1) x y = jump go (n-1) (x+y)
The join point itself can be interesting, even if none if The join point itself can be interesting, even if none if its
its arguments are (assume `g` to be an imported function that, on its own, does arguments have free variables free in the joinrec. For example
not make this interesting):
join j p = case p of (x,y) -> x+y
joinrec go 0 x y = jump j (x,y)
go (n-1) x y = jump go (n-1) (x+y) y
in …
Here, `j` would not be inlined because we do not inline something that looks
like an exit join point (see Note [Do not inline exit join points]). But
if we exitify the 'jump j (x,y)' we get
join j p = case p of (x,y) -> x+y
join exit x y = jump j (x,y)
joinrec go 0 x y = jump exit x y
go (n-1) x y = jump go (n-1) (x+y) y
in …
and now 'j' can inline, and we get rid of the pair. Here's another
example (assume `g` to be an imported function that, on its own,
does not make this interesting):
join j y = map f y join j y = map f y
joinrec go 0 x y = jump j (map g x) joinrec go 0 x y = jump j (map g x)
go (n-1) x y = jump go (n-1) (x+y) go (n-1) x y = jump go (n-1) (x+y)
in … in …
Here, `j` would not be inlined because we do not inline something that looks Again, `j` would not be inlined because we do not inline something that looks
like an exit join point (see Note [Do not inline exit join points]). like an exit join point (see Note [Do not inline exit join points]).
But after exitification we have But after exitification we have
...@@ -353,7 +369,6 @@ interesting expressions. ...@@ -353,7 +369,6 @@ interesting expressions.
Note [Calculating free variables] Note [Calculating free variables]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We have two options where to annotate the tree with free variables: We have two options where to annotate the tree with free variables:
A) The whole tree. A) The whole tree.
...@@ -369,7 +384,6 @@ it would have to ensure that the annotations are correct. ...@@ -369,7 +384,6 @@ it would have to ensure that the annotations are correct.
Note [Do not inline exit join points] Note [Do not inline exit join points]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When we have When we have
let t = foo bar let t = foo bar
...@@ -396,14 +410,13 @@ occ_in_lam, because `j2` is called only once. ...@@ -396,14 +410,13 @@ occ_in_lam, because `j2` is called only once.
We create exit join point ids with such an `OccInfo`, see `exit_occ_info`. We create exit join point ids with such an `OccInfo`, see `exit_occ_info`.
To prevent inlining, we check for that in `preInlineUnconditionally` directly. To prevent inlining, we check for isExitJoinId
For `postInlineUnconditionally` and unfolding-based inlining, the function * In `preInlineUnconditionally` directly.
`simplLetUnfolding` simply gives exit join points no unfolding, which prevents * In `simplLetUnfolding` we simply give exit join points no unfolding, which
this kind of inlining. prevents inlining in `postInlineUnconditionally` and call sites.
Note [Placement of the exitification pass] Note [Placement of the exitification pass]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I (Joachim) experimented with multiple positions for the Exitification pass in I (Joachim) experimented with multiple positions for the Exitification pass in
the Core2Core pipeline: the Core2Core pipeline:
......
...@@ -1113,7 +1113,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env ...@@ -1113,7 +1113,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env
| not active = Nothing | not active = Nothing
| isTopLevel top_lvl && isBottomingId bndr = Nothing -- Note [Top-level bottoming Ids] | isTopLevel top_lvl && isBottomingId bndr = Nothing -- Note [Top-level bottoming Ids]
| isCoVar bndr = Nothing -- Note [Do not inline CoVars unconditionally] | isCoVar bndr = Nothing -- Note [Do not inline CoVars unconditionally]
| isExitJoinId bndr = Nothing | isExitJoinId bndr = Nothing -- Note [Do not inline exit join points] in Exitify
| not (one_occ (idOccInfo bndr)) = Nothing | not (one_occ (idOccInfo bndr)) = Nothing
| not (isStableUnfolding unf) = Just (extend_subst_with rhs) | not (isStableUnfolding unf) = Just (extend_subst_with rhs)
......
...@@ -3271,7 +3271,7 @@ simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty unf ...@@ -3271,7 +3271,7 @@ simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty unf
| isStableUnfolding unf | isStableUnfolding unf
= simplStableUnfolding env top_lvl cont_mb id unf rhs_ty = simplStableUnfolding env top_lvl cont_mb id unf rhs_ty
| isExitJoinId id | isExitJoinId id
= return noUnfolding -- see Note [Do not inline exit join points] = return noUnfolding -- see Note [Do not inline exit join points] in Exitify
| otherwise | otherwise
= mkLetUnfolding (seDynFlags env) top_lvl InlineRhs id new_rhs = mkLetUnfolding (seDynFlags env) top_lvl InlineRhs id new_rhs
......
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