GHC does not inline `timesDouble` into lambda.
This happens in 8.6.4 as well as GHC-HEAD.
In nofib/imaginary/integrate
we have this function:
zark u v = integrate2D 0.0 u 0.0 v (\x->(\y->x*y))
Which really is zark u v = integrate2D 0.0 u 0.0 v (\x->(\y->x ´timesDouble´ y))
Where we should inline timesDouble into the lambda. Instead we get a closure that calls timesDouble.
I can see why we can't get rid of the closure, but the overhead of a call here seems not worth it.
Relevant core:
Main.main_go2
= \ (ds_a3Zb :: [Double]) (ds1_a3Zc :: [Double]) ->
case ds_a3Zb of {
[] -> GHC.Types.[] @ Double;
: ipv_a3Zg ipv1_a3Zh ->
case ds1_a3Zc of {
[] -> GHC.Types.[] @ Double;
: ipv2_a3Zm ipv3_a3Zn ->
GHC.Types.:
@ Double
(case ipv2_a3Zm of { GHC.Types.D# ww1_s5S2 ->
case $wintegrate1D_r5YG
0.0##
ww1_s5S2
(\ (y_a1wV :: Double) ->
case ipv_a3Zg of { GHC.Types.D# ww3_X5T5 ->
case $wintegrate1D_r5YG
0.0##
ww3_X5T5
(\ (x_a1wW :: Double) -> GHC.Float.timesDouble x_a1wW y_a1wV)
of ww4_s5S6
{ __DEFAULT ->
GHC.Types.D# ww4_s5S6
}
})
of ww2_s5S6
{ __DEFAULT ->
GHC.Types.D# ww2_s5S6
}
})
(Main.main_go2 ipv1_a3Zh ipv3_a3Zn)
}
}
end Rec }
Relevant STG code.
let {
sat_s5ZW [Occ=Once] :: GHC.Types.Double -> GHC.Types.Double
[LclId] =
\r [y_s5ZQ]
case ipv_s5ZJ of {
GHC.Types.D# ww3_s5ZS [Occ=Once] ->
let {
sat_s5ZU [Occ=Once]
:: GHC.Types.Double -> GHC.Types.Double
[LclId] =
\r [x_s5ZT]
GHC.Float.timesDouble x_s5ZT y_s5ZQ;
} in
case
$wintegrate1D_r5YG 0.0## ww3_s5ZS sat_s5ZU
of
ww4_s5ZV [Occ=Once]
{ __DEFAULT -> GHC.Types.D# [ww4_s5ZV];
};
};
} in ...