[GHC] #14137: Do more inlining into non-recursive join points

GHC ghc-devs at haskell.org
Sat Aug 19 10:55:23 UTC 2017


#14137: Do more inlining into non-recursive join points
-------------------------------------+-------------------------------------
        Reporter:  simonpj           |                Owner:  nomeata
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:  JoinPoints
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by nomeata):

 >  Maybe it didn't start that way?

 Quite possible (didn’t check). The problem of things floating out of
 recursive lets and never back in has beein bothering me for a while,
 especially in the context of
 https://ghc.haskell.org/trac/ghc/ticket/10918#comment:5.

 Maybe the following thought deserves a ticket of its own:

 Currently, we cannot inline `x` in
 {{{
   let x = f x0
   in let go 10 y = exit1 x y
          go 20 y = exit2 (y*y)
          go 30 y = exit3 0
          go i = go (i+1) (y*2)
      in go y
 }}}
 because it goes into a recursive function and under lambdas, and that is,
 in general, dangerous. But in this case, it would be ok because the
 occurence of `x` is not actually on a recursive path. But that is hard to
 spot in this form!

 It would be easy to spot if we take all codepaths of `go` that do not
 mention `go` and float them out of the recursive let ''as non-recursive
 jointpoints'':

 {{{
   let x = f x0
   in join j1 y = exit1 x y
      join j2 y = exit2 (y*y)
      join j3 = exit3 0
      let go 10 y = call j1 y
          go 20 y = call j2 y
          go 30 y = call j3
          go i = go (i+1) (y*2)
      in go y
 }}}

 and now the existing machinery will happily inline `x` into `j1` or `j2`.

 In the example of this ticket, we’d move all occurrences of `ds5` out of
 `save` this way, and the inliner could do its work unhindered by the
 recursion.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14137#comment:10>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list