What's the benefit of taking "do" blocks apart? Is there a way to turn that off?

Joachim Breitner mail at joachim-breitner.de
Wed Dec 29 19:39:02 UTC 2021

Hi Gergo,

Am Dienstag, dem 28.12.2021 um 15:57 +0000 schrieb Erdi, Gergo via ghc-


> I’m seeing ‘do’ blocks getting taking apart into top-level
> definitions, so e.g.
> main = do
>   some complicated expression 1
>   some complicated expression 2
> is compiled into
> sat_sKv = some complicated expression 1
> sat_sKw = \_ -> some complicated expression 2
> main = bindIO sat_sKv sat_sKw
> This seems to happen regardless of any common subexpressions, i.e. it
> is not the case that sat_sKv or sat_sKw are used anywhere else.
> What is the intended benefit of this floating-out? Is there a
> particular Core-to-Core pass that causes this? Is it possible to turn
> it off?

didn’t investigate deeper (maybe if you provide a small example I
would), but just from looking at this:

 * It is generally preferable to turn local lambda expressions
   into top-level functions. This way, instead of dynamically
   allocating a FUN heap object, it’s just a static function.

 * sat_sKv is an IO expression? Then it is actually a function in a way
   (taking the “State token” as an argument). So the above applies.

 * I think this is the FloatOut pass. You can turn it out using
   -fno-full-laziness. Not sure if some others passes might 
   do similar things, though.


Joachim Breitner
  mail at joachim-breitner.de

More information about the ghc-devs mailing list