SpecConstr generates functions that do not use their arguments
See also
Consider this function:
f :: Int -> (Bool,Bool) -> Bool -> Bool
f 0 x y = y
f n (p,q) y = f (n-1) (p,q) q
SpecConstr
does a reasonable job, but ends up with a function like this:
T4908a.f_$s$wf =
\ (sc_sp4 :: GHC.Prim.Int#)
(sc1_sp5 :: GHC.Types.Bool)
(sc2_sp6 :: GHC.Types.Bool)
(sc3_sp7 :: GHC.Types.Bool) ->
case sc_sp4 of ds_Xom {
__DEFAULT ->
T4908a.f_$s$wf (GHC.Prim.-# ds_Xom 1) sc1_sp5 sc2_sp6 sc2_sp6;
0 -> sc3_sp7
}
Note that sc1_sp5
is passed around the loop but never used.
I had a quick go at trying to make SpecConstr
cleverer, but absence info requires a fixpoint analysis, which the existing ArgOcc
stuff doesn't do. Nor can we rely on absence analysis from earlier in the compiler, because CSE invalidates it.
A possibility would be to run strictness/absence analysis again after SpecConstr
, which would pick this up. I'm not sure what other consequences this would have.
So there's an opportunity here, but I'm not sure how much it matters in practice.
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.1 |
Type | Task |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |