SpecConstr: Better tune which patterns/arguments to specialize for.
The motivation is !8148 (comment 438129) where we regress (quite badly) because as far as I can tell SpecConstr is a bit too eager to specialize certain arguments.
The basic idea is we have a pattern like this:
$j_s4qg (x_X1P [Dmd=SL, OS=OneShot] :: GHC.Prim.Int#)
(wild_X1Q [Dmd=SL, OS=OneShot] :: Int)
= case wild_X1Q of wild_X1R { GHC.Types.I# ipv_s4qk -> ... rhs -- with *boxed* uses of wild_X1Q
If we specialize for wild_X1Q
being I# <something>
we end up reboxing in the RHS which can be quite bad. In the linked comment i saw exact-reals regress by 25%!
It's a bit of a fluke. Things overall still get better in !8148 (closed) despite this one regression. But we should still try to fix this.
I think one approach would be to try and do better in distinguishing properly interesting occurances of variables from "boring" ones. For example consider these functions:
f maybe_x = case maybe_x of
Just x -> e1
Nothing -> e2
g maybe_x ww_unknown_function = case maybe_x of maybe_x' -> ... ww_unknown_function maybe_x' ...
h maybe_x = case maybe_x of maybe_x' -> ... f maybe_x' ...
f
is obviously good to specialize. h
can be interesting if it allows us to use a specialized f
in it's rhs. But there is no point in specializing the argument for g
in general.
The only benefit is that it would allow us to drop the seq. But tag inference can often already make the seq a no-op at runtime if we turn the argument into a cbv argument (which is quite likely). So I think we should try to avoid specializing for the case where the only use is a "boring" seq.