Opened 13 months ago

Last modified 8 months ago

#15606 new bug

Don't float out lets in between lambdsa

Reported by: simonpj Owned by:
Priority: normal Milestone: 8.6.1
Component: Compiler Version: 8.4.3
Keywords: FloatOut Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

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

Change History (1)

comment:1 Changed 8 months ago by simonpj

Keywords: FloatOut added
Note: See TracTickets for help on using tickets.