Assume at least one evaluation for nested SubDemands (#21081)
See the new Note [SubDemand denotes at least one evaluation]
.
A demand n :* sd
on a let binder x=e
now means
"
x
was evaluatedn
times and in any program trace it is evaluated,e
is evaluated deeply in sub-demandsd
."
The "any time it is evaluated" premise is what this patch adds. As a result, we get better nested strictness. For example (T21081)
f :: (Bool, Bool) -> (Bool, Bool)
f pr = (case pr of (a,b) -> a /= b, True)
-- before: <MP(L,L)>
-- after: <MP(SL,SL)>
g :: Int -> (Bool, Bool)
g x = let y = let z = odd x in (z,z) in f y
The change in demand signature "before" to "after" allows us to case-bind z
here.
Similarly good things happen for the sd
in call sub-demands Cn(sd)
, which
allows for more eta-reduction (which is only sound with -fno-pedantic-bottoms
,
albeit).
We also fix #21085 (closed), a surprising inconsistency with Poly
to Call
sub-demand
expansion.
In an attempt to fix a regression caused by less inlining due to eta-reduction
in T15426, I eta-expanded the definition of elemIndex
and elemIndices
, thus
fixing #21345 (closed) on the go.
The main point of this patch is that it fixes #21081 (closed) and #21133 (closed).
Annoyingly, I discovered that more precise demand signatures for join points can
transform a program into a lazier program if that join point gets floated to the
top-level, see #21392. There is no simple fix at the moment, but !5349 might.
Thus, we accept a ~5% regression in MultiLayerModulesTH_OneShot
, where #21392
bites us in addListToUniqDSet
. T21392 reliably reproduces the issue.