FloatOut discards strict evalution context
Consider
module Lib (h) where
g :: Int -> (Int,Int)
g n = (n, n+1)
{-# NOINLINE g #-}
h :: Int -> Int
h _ = snd (g 2)
we get the simplified Core
$wg_sHs
= \ w_sHo ->
(# w_sHo, case w_sHo of { I# x_aGX -> I# (+# x_aGX 1#) } #)
lvl_sHJ = I# 2#
lvl_sH8
= case $wg_sHs lvl_sHJ of { (# ww_sHt, ww_sHu #) ->
(ww_sHt, ww_sHu)
}
h = \ _ -> case lvl_sH8 of { (ds1_aGM, y_aGN) -> y_aGN }
Note how g 2
was floated out and thus separated from its strict snd
evaluation context in h
.
In this case that inhibits us from seeing (with #18894 (closed)) that every call to g
also evaluates the second component of the returned pair (and never looks into the first).
I'd much rather see the whole expression snd (g 2)
floated out, so including the surrounding case
:
$wg_sHs
= \ w_sHo ->
(# w_sHo, case w_sHo of { I# x_aGX -> I# (+# x_aGX 1#) } #)
lvl_sHJ = I# 2#
lvl_sH8
= case $wg_sHs lvl_sHJ of { (# ww_sHt, ww_sHu #) ->
ww_sHu
}
h = \ _ -> lvl_sH8
This is partly caused by Note [Case MFEs]
in SetLevels. See also #14564 (comment 145965)