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

GHC ghc-devs at haskell.org
Tue Oct 6 21:16:29 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):

 Hey, where is my comment I reported something here a few days ago :-( Darn
 it. Maybe I should open a ticket asking for the removal of the “Preview”
 button (after all, there is a live preview these days).

 Anyways, I made `CallArity` consider all variables interesting, so that we
 actually collect cardinality information on things that cannot be eta-
 expanded, made it store the once-used-information:
 {{{#!hs
     v'' | called_once = v' `setIdDemandInfo` oneifyDmd (idDemandInfo v')
         | otherwise   = v'
 }}}
 and then made `preInlineUnconditionally` use this information:
 {{{#!hs
      try_once in_lam int_cxt     -- There's one textual occurrence
          | not in_lam = isNotTopLevel top_lvl || early_phase
 -        | otherwise  = int_cxt && canInlineInLam rhs
 +        | otherwise  = (int_cxt && canInlineInLam rhs) || isSingleUsed
 (idDemandInfo bndr)
 }}}

 This had the desired effect of changing

 {{{#!hs
   let x = f x0
   in let go 20 = x
          go 10 = something else
          go i = go (i+1)
      in go y
 }}}
 to
 {{{#!hs
      let go 20 = f x0
          go 10 = something else
          go i = go (i+1)
      in go y
 }}}
 in the simplifier phase following Call Arity, as expected. But the later
 FloatOut pass would simply float `f x0` out again to where it was before.

 I’m not sure how to prevent that. In general, floating something out of a
 recursive group is good, and the information that was used to effect the
 inlining (namely the once-used of `x`) is lost, as no `x` remains.

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


More information about the ghc-tickets mailing list