Lambda lifting
Dan Rosen asks whether GHC has a lambda lifter. Yes, it does: GHC's full-laziness pass also doubles as a lambda lifter
- It's controlled by the
floatOutLambdasfield ofCoreMonad.FloatOutSwitches - This in turn is set from the
floatLamArgsfield ofDynFlagsinSimplCore - The
DynFlagsare set in moduleDynFlags(see-ffloat-all-lams,-ffloat-lam-args)
However on trying a small experiment on
f x = map (\y -> (x,y))
I see a bug and an infelicity.
- Bug: the comment with the
floatOutLambdasfield definition claims thatNothingmeans float all lambdas to the top. But the code inSetLevels.destLeveltreats(Just 0)andNothingidentically, which contradicts the comment. Workaround: use(Just 100) - Infelicity: with
-ffloat-lam-args=100we get
lvl_sdQ =
\ (@ t_acm) (@ t_acn) (x_a9H :: t_acm) (y_a9I :: t_acn) ->
(x_a9H, y_a9I)
Foo.f =
\ (@ t_acm)
(@ t_acn)
(x_a9H [Dmd=Just L] :: t_acm)
(eta_B1 :: [t_acn]) ->
GHC.Base.map
@ t_acn @ (t_acm, t_acn) (lvl_sdQ @ t_acm @ t_acn x_a9H) eta_B1
which is good, but then the next simplifier run inlines it straight back in again, via SimplUtils.preInlineUnconditionally.
I think preInlineUnconditionally should be a bit less gung-ho, perhaps, but I don't want to change it until I've see if there are any performance regressions.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.4.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |