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
floatOutLambdas
field ofCoreMonad.FloatOutSwitches
- This in turn is set from the
floatLamArgs
field ofDynFlags
inSimplCore
- The
DynFlags
are 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
floatOutLambdas
field definition claims thatNothing
means float all lambdas to the top. But the code inSetLevels.destLevel
treats(Just 0)
andNothing
identically, which contradicts the comment. Workaround: use(Just 100)
- Infelicity: with
-ffloat-lam-args=100
we 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 |