[GHC] #15606: Don't float out lets in between lambdsa

GHC ghc-devs at haskell.org
Wed Sep 5 15:15:00 UTC 2018


#15606: Don't float out lets in between lambdsa
-------------------------------------+-------------------------------------
           Reporter:  simonpj        |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:  8.6.1
          Component:  Compiler       |           Version:  8.4.3
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Consider
 {{{
 f = \x. let y = <blah>
         in \z. let v = h x y in <stuff>
 }}}
 The full laziness pass will float out that v-binding thus
 {{{
 f = \x. let y = <blah>
             v = h x y
         in \z. <stuff>
 }}}
 And now (if `h` is, say, imported) it'll stay like that.

 But suppose `<blah>` simlifies to `Just x`.  Then we allow ourselves to
 eta-expand thus
 {{{
 f = \x z. let y = <blah>
               v = h x y
           in <stuff>
 }}}
 Now (an early design choice in the let-floater) we never float the
 v-binding in between the `\x` and `\z`.

 This is very non-confluent: a smal change in exactly how rapidly `<blah>`
 simplifies can
 have a big, irreversible effect on the code for `f`.

 IDEA: extend the let-floater's design choice to not float out between two
 lambdas, even if
 they are separated by lets/cases etc.   One way to say this is to ask when
 a lambda gets
 a new level number compared to its immediately enclosing lambda.

 Examples where `y` gets the same level number as `x`
 * `\x.\y. blah`
 * `\x. let binds in \y`
 * `\x. case scrut of pi -> \y.blah`

 Examples where `y` gets the a level number one bigger than `x`
 * `\x. let v = \y.rhs in blah`
 * `\x. f (\y.rhs)`

 This probably won't make a lot of difference, but it'd be worth trying

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


More information about the ghc-tickets mailing list