Don't float unlifted join points to top level
authorSimon Peyton Jones <simonpj@microsoft.com>
Tue, 30 Jul 2019 14:56:08 +0000 (15:56 +0100)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Sun, 4 Aug 2019 22:18:08 +0000 (18:18 -0400)
commit7d8d0012acd8701c0bb562376fd8321009342dcd
tree71095e7098bc6a935112c8794a2bfa7ad88bc841
parent8a061d18c759cd396bb71d82688ffb28f5d27c94
Don't float unlifted join points to top level

Ticket #16978 showed that we were floating a recursive,
unlifted join point to top level.  It's very much a corner
case:

    joinrec j :: Int#
            j = jump j
    in ...

But somehow it showed up in a real program.

For non-recursive bindings in SetLevels.lvlBind we were already
(correctly) checking for unlifted bindings, but when I wrote
that code I didn't think that a /recursive/ binding could be
unlifted but /join-points/ can be!

Actually I don't think that SetLevels should be floating
join points at all.  SetLevels really floats things to move
stuff out of loops and save allocation; but none of that applies
to join points.  The only reason to float join points is in
cases like
   join j1 x = join j2 y = ...
               in ...
which we might want to swizzle to
   join j2 x y = ... in
   join j1 x = ...
   in ...
because now j1 looks small and might be inlined away altogether.
But this is a very local float perhaps better done in the simplifier.

Still: this patch fixes the crash, and does so in a way that is
harmless if/when we change our strategy for floating join points.
compiler/simplCore/SetLevels.hs