diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2018-04-06 09:46:29 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2018-04-06 09:46:53 +0100 |
commit | 891ffd58c323a44a10959ce5a78529a3db75c7ff (patch) | |
tree | f98796cf7d9684688ddc3cd4d5f8be79b7a0528d | |
parent | c2f90c84e6dcf4331e934a76de313b168c77b6dc (diff) | |
download | haskell-891ffd58c323a44a10959ce5a78529a3db75c7ff.tar.gz |
Comments only, about exitifcation
-rw-r--r-- | compiler/basicTypes/Id.hs | 2 | ||||
-rw-r--r-- | compiler/simplCore/Exitify.hs | 39 | ||||
-rw-r--r-- | compiler/simplCore/SimplUtils.hs | 2 | ||||
-rw-r--r-- | compiler/simplCore/Simplify.hs | 2 |
4 files changed, 29 insertions, 16 deletions
diff --git a/compiler/basicTypes/Id.hs b/compiler/basicTypes/Id.hs index fbece0e68d..709bea4c09 100644 --- a/compiler/basicTypes/Id.hs +++ b/compiler/basicTypes/Id.hs @@ -498,7 +498,7 @@ isJoinId_maybe id _ -> 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 id = isJoinId id && isOneOcc (idOccInfo id) && occ_in_lam (idOccInfo id) diff --git a/compiler/simplCore/Exitify.hs b/compiler/simplCore/Exitify.hs index 2d3b5aff55..cf6a930d3e 100644 --- a/compiler/simplCore/Exitify.hs +++ b/compiler/simplCore/Exitify.hs @@ -250,7 +250,6 @@ type ExitifyM = State [(JoinId, CoreExpr)] {- Note [Interesting expression] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - We do not want this to happen: joinrec go 0 x y = x @@ -291,7 +290,6 @@ non-imported variable. Note [Jumps can be interesting] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - A jump to a join point can be interesting, if its arguments contain free 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) -The join point itself can be interesting, even if none if -its arguments are (assume `g` to be an imported function that, on its own, does -not make this interesting): +The join point itself can be interesting, even if none if its +arguments have free variables free in the joinrec. For example + + 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 joinrec go 0 x y = jump j (map g x) go (n-1) x y = jump go (n-1) (x+y) 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]). But after exitification we have @@ -353,7 +369,6 @@ interesting expressions. Note [Calculating free variables] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - We have two options where to annotate the tree with free variables: A) The whole tree. @@ -369,7 +384,6 @@ it would have to ensure that the annotations are correct. Note [Do not inline exit join points] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - When we have let t = foo bar @@ -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`. -To prevent inlining, we check for that in `preInlineUnconditionally` directly. -For `postInlineUnconditionally` and unfolding-based inlining, the function -`simplLetUnfolding` simply gives exit join points no unfolding, which prevents -this kind of inlining. +To prevent inlining, we check for isExitJoinId +* In `preInlineUnconditionally` directly. +* In `simplLetUnfolding` we simply give exit join points no unfolding, which + prevents inlining in `postInlineUnconditionally` and call sites. Note [Placement of the exitification pass] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - I (Joachim) experimented with multiple positions for the Exitification pass in the Core2Core pipeline: diff --git a/compiler/simplCore/SimplUtils.hs b/compiler/simplCore/SimplUtils.hs index cc72f7aa2a..db26af426e 100644 --- a/compiler/simplCore/SimplUtils.hs +++ b/compiler/simplCore/SimplUtils.hs @@ -1113,7 +1113,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env | not active = Nothing | isTopLevel top_lvl && isBottomingId bndr = Nothing -- Note [Top-level bottoming Ids] | 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 (isStableUnfolding unf) = Just (extend_subst_with rhs) diff --git a/compiler/simplCore/Simplify.hs b/compiler/simplCore/Simplify.hs index a60df1c0ad..78b62d3a29 100644 --- a/compiler/simplCore/Simplify.hs +++ b/compiler/simplCore/Simplify.hs @@ -3271,7 +3271,7 @@ simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty unf | isStableUnfolding unf = simplStableUnfolding env top_lvl cont_mb id unf rhs_ty | 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 = mkLetUnfolding (seDynFlags env) top_lvl InlineRhs id new_rhs |