[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