Loss of inlining after strictness analysis
While investigating something else I saw this in the final Tidy Core
after optimisation
join {
wild_X5jU [Dmd=<S,1*U>]
:: (# State# RealWorld, Array Int HValue #)
[LclId[JoinId(0)],
Unf=Unf{Src=InlineStable, TopLvl=False, Value=False,
ConLike=False, WorkFree=False,
Expandable=False,
Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=False)
Tmpl= jump $j1_s5RP w_s5Qs}]
wild_X5jU = jump $j1_s5RP ww_s5Qw } in
jump wild_X5jU;
That's ridiculous! Why wasn't it inlined at its (only!) use site?
It turns out that
-
The original
InlineStable
came from whenwild
was lambda-bound.See
Note [Case binders and join points]
inSimplify.hs
-
But then worker-wrapper let-binds that previously-lambda-boudn arg
in
WwLib.mkWWstr_one
. But it does not remove the unfolding.That's bad; in contrast, when we beta-reduce we are careful to
remove the unfolding; see
Note [Zap unfolding when beta-reducing]
in
Simplify.hs
. -
We don't
preInlineUnconditionally
things with stable unfoldings; seeNote [Stable unfoldings and preInlineUnconditionally]
inSimplUtils
Net result: it doesn't get inlined at all!
Easy fix: zap the unfolding in mkWWstr_one
as well.
I'm unhappy with the whole business of passing both boxed and
unboxed versions, described in Note [Case binders and join points]
.
It smells wrong, and this ticket is another canary.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |