Join point wrapper not inlined
Consider
loop :: Int -> Int -> (Int, ())
loop x y = go x
where
go x = if x > y then (x, ()) else go (x*2)
Compile that with -O2
and get
loop
= \ (x_aXE :: Int) (y_aXF :: Int) ->
join {
$wgo_s2sP [InlPrag=NOUSERINLINE[2], Dmd=<C(S),1*C1(U(U,U))>]
:: GHC.Prim.Int# -> (Int, ())
[LclId[JoinId(1)], Arity=1, Str=<L,U>m, Unf=OtherCon []]
$wgo_s2sP (ww_s2sN [OS=OneShot] :: GHC.Prim.Int#)
= case y_aXF of { GHC.Types.I# y1_a2rI ->
case GHC.Prim.># ww_s2sN y1_a2rI of {
__DEFAULT ->
joinrec {
$wgo1_X2t9 [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
:: GHC.Prim.Int# -> (Int, ())
[LclId[JoinId(1)], Arity=1, Str=<L,U>m, Unf=OtherCon []]
$wgo1_X2t9 (ww1_X2t8 :: GHC.Prim.Int#)
= case GHC.Prim.># ww1_X2t8 y1_a2rI of {
__DEFAULT -> jump $wgo1_X2t9 (GHC.Prim.*# ww1_X2t8 2#);
1# -> (GHC.Types.I# ww1_X2t8, GHC.Tuple.())
}; } in
jump $wgo1_X2t9 (GHC.Prim.*# ww_s2sN 2#);
1# -> (GHC.Types.I# ww_s2sN, GHC.Tuple.())
}
} } in
join {
go_s2se [InlPrag=NOUSERINLINE[2], Dmd=<C(S),1*C1(U(U,U))>]
:: Int -> (Int, ())
[LclId[JoinId(1)],
Arity=1,
Str=<S,1*U(U)>m,
Unf=Unf{Src=InlineStable, TopLvl=False, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
Tmpl= \ (w_s2sK [Occ=Once!] :: Int) ->
case w_s2sK of { GHC.Types.I# ww1_s2sN [Occ=Once] ->
jump $wgo_s2sP ww1_s2sN
}}]
go_s2se (w_s2sK [OS=OneShot] :: Int)
= case w_s2sK of { GHC.Types.I# ww1_s2sN ->
jump $wgo_s2sP ww1_s2sN
} } in
jump go_s2se x_aXE
I'd expected something like
loop
= \ (x_aXE :: Int) (y_aXF :: Int) ->
join {
$wgo_s2sP [InlPrag=NOUSERINLINE[2], Dmd=<C(S),1*C1(U(U,U))>]
:: GHC.Prim.Int# -> (Int, ())
[LclId[JoinId(1)], Arity=1, Str=<L,U>m, Unf=OtherCon []]
$wgo_s2sP (ww_s2sN [OS=OneShot] :: GHC.Prim.Int#)
= case y_aXF of { GHC.Types.I# y1_a2rI ->
case GHC.Prim.># ww_s2sN y1_a2rI of {
__DEFAULT ->
joinrec {
$wgo1_X2t9 [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
:: GHC.Prim.Int# -> (Int, ())
[LclId[JoinId(1)], Arity=1, Str=<L,U>m, Unf=OtherCon []]
$wgo1_X2t9 (ww1_X2t8 :: GHC.Prim.Int#)
= case GHC.Prim.># ww1_X2t8 y1_a2rI of {
__DEFAULT -> jump $wgo1_X2t9 (GHC.Prim.*# ww1_X2t8 2#);
1# -> (GHC.Types.I# ww1_X2t8, GHC.Tuple.())
}; } in
jump $wgo1_X2t9 (GHC.Prim.*# ww_s2sN 2#);
1# -> (GHC.Types.I# ww_s2sN, GHC.Tuple.())
}
} } in
case x_aXE of { GHC.Types.I# ww1_s2sN ->
jump $wgo_s2sP ww1_s2sN
}
that coincides with simply inlining the join point wrapper go
. I wonder why we don't inline it.