Avoid excessive specialisation in SpecConstr
This ticket captures an email thread so it doesn't get lost.
Consider this (from haddock/src/Haddock/Backends/Hoogle.hs
):
dropComment (' ':'-':'-':' ':_) = []
dropComment (x:xs) = x : dropComment xs
dropComment [] = []
This desugars thus:
dropComment xs
= case xs of
(C# x1 : xs1) ->
case x1 of
' '# ->
case xs1 of
(C# x2:xs2) ->
case x2 of
'-' -> ....
DEFAULT -> dropComment (C# x2 : xs2)
DEFAULT -> ...
[] -> ...
I have elided the branches that are less interesting, and I have done a bit of multi-level pattern matching to save space.
The thing to notice is this: at the recursive call, we know that the argument is a cons, with C# at the front. So SpecConstr
dutifully creates a specialized version. And similarly for each subsequent character! Indeed, if the match fails after matching (' ': '-' : )
prefix, the recursive call even knows that the first char is '-'
!
Hence we get as many specializations as we have characters in the input match.
So SpecConstr
is behaving as expected. Can anyone think of a heuristic to squash this behavior? At the moment we take the first N specializations and then stop. One heuristic might be "if there are lots of recursive calls, don't specialize". But that is very close to "if there are lots of specializations, drop some". Mind you, perhaps we should be more vigorous still: "if there are more than N, don't do any" on the grounds that randomly choosing the first few is unlikely to be useful.
Any thoughts?
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.3 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Unknown |
Architecture | Unknown |