Bottom extraction: float out bottoming expressions to top level
authorsimonpj@microsoft.com <unknown>
Fri, 11 Dec 2009 16:19:28 +0000 (16:19 +0000)
committersimonpj@microsoft.com <unknown>
Fri, 11 Dec 2009 16:19:28 +0000 (16:19 +0000)
commitb84ba676034763b3082bbd9405794a4fde499d14
tree6d6d15917e0c6946ec318640e4b0e5d5a00ac4fd
parent015d3d46b6de2f95386a515a7d166d996a0416db
Bottom extraction: float out bottoming expressions to top level

The idea is to float out bottoming expressions to top level,
abstracting them over any variables they mention, if necessary.  This
is good because it makes functions smaller (and more likely to
inline), by keeping error code out of line.

See Note [Bottoming floats] in SetLevels.

On the way, this fixes the HPC failures for cg059 and friends.

I've been meaning to do this for some time.  See Maessen's paper 1999
"Bottom extraction: factoring error handling out of functional
programs" (unpublished I think).

Here are the nofib results:

        Program           Size    Allocs   Runtime   Elapsed
--------------------------------------------------------------------------------
            Min          +0.1%     -7.8%    -14.4%    -32.5%
            Max          +0.5%     +0.2%     +1.6%    +13.8%
 Geometric Mean          +0.4%     -0.2%     -4.9%     -6.7%

Module sizes
        -1 s.d.                -----           -2.6%
        +1 s.d.                -----           +2.3%
        Average                -----           -0.2%

Compile times:
        -1 s.d.                -----          -11.4%
        +1 s.d.                -----           +4.3%
        Average                -----           -3.8%

I'm think program sizes have crept up because the base library
is bigger -- module sizes in nofib decrease very slightly.  In turn
I think that may be because the floating generates a call where
there was no call before.  Anyway I think it's acceptable.

The main changes are:

* SetLevels floats out things that exprBotStrictness_maybe
  identifies as bottom.  Make sure to pin on the right
  strictness info to the newly created Ids, so that the
  info ends up in interface files.

  Since FloatOut is run twice, we have to be careful that we
  don't treat the function created by the first float-out as
  a candidate for the second; this is what worthFloating does.

  See SetLevels Note [Bottoming floats]
                Note [Bottoming floats: eta expansion]

* Be careful not to inline top-level bottoming functions; this
  would just undo what the floating transformation achieves.
  See CoreUnfold Note [Do not inline top-level bottoming functions

  Ensuring this requires a bit of extra plumbing, but nothing drastic..

* Similarly pre/postInlineUnconditionally should be
  careful not to re-inline top-level bottoming things!
  See SimplUtils Note [Top-level botomming Ids]
                 Note [Top level and postInlineUnconditionally]
compiler/coreSyn/CoreUnfold.lhs
compiler/iface/MkIface.lhs
compiler/iface/TcIface.lhs
compiler/main/TidyPgm.lhs
compiler/simplCore/FloatOut.lhs
compiler/simplCore/SetLevels.lhs
compiler/simplCore/SimplUtils.lhs
compiler/simplCore/Simplify.lhs
compiler/specialise/Specialise.lhs