[GHC] #10918: Float once-used let binding into a recursive function

GHC ghc-devs at haskell.org
Tue Sep 29 20:53:13 UTC 2015


#10918: Float once-used let binding into a recursive function
-------------------------------------+-------------------------------------
        Reporter:  nomeata           |                Owner:
            Type:  task              |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  7.10.2
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
-------------------------------------+-------------------------------------

Comment (by nomeata):

 Thanks for the input!

 Next thing to consider problem: Can we float it past the case analysis (or
 past multiple recursive bindings):

 In
 {{{
   let x = f x0
   in let go 30 = x
          go 20 = x
          go 10 = something else
          go i = go (i+1)
      in go y
 }}}
 we know that `x` is evaluated at most once, so we want to float it in.
 Also, `x` might actually not be needed, so we would gain something by not
 allocating it before hand. But we also definitely not want it to float
 past the let and the lambda, just to get
 {{{
   let go i =
     let x = f x0
     in case i of
          30 -> x
          20 -> x
          10 -> something else
          i  -> go (i+1)
   in go y
 }}}
 as now we would allocate it on _every_ call.

 So either, floats that are allowed to go into a recursive group _must_
 also go past a case, possibly duplicating it:

 {{{
   let go 30 = let x = f x0 in x
       go 20 = let x = f x0 in x
       go 10 = something else
       go i  = go (i+1)
   in go y
 }}}

 But this would blow up the code size... .

 A more cautious route would be to only float something inside a recursive
 group if it is used at most once _and_ there is only one syntactical call
 to it, because then we can be reasonably sure that it will also float into
 the branches.

 Is there an easy way to detect that something has only one syntactic
 occurence?

 Is it not possible to tell the inliner to do this work and decision
 making?

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


More information about the ghc-tickets mailing list