inference×effects: improve the const-prop' heuristics
This commit improves the heuristics to judge const-prop' profitability
with new effect property `:const_prop_profitable_args`. This is supposed
to supplement our primary const-prop' heuristic based on inlining cost
and is supposed to be a general fix for type stabilities issues discussed
at e.g. #45952 and #46430 (and eliminating the need for manual
`@constprop :aggressive` clutters in such situations).
The new effect property `:const_prop_profitable_args` tracks call
arguments that can be considered to shape up generated code if
their constant information is available. Currently this commit
exploits the following const-prop' profitabilities:
- `Val(x)`-profitability: as `Val` generally encodes constant information
into the type domain, it is generally profitable to constant prop' `x`
if the constructed `Val(x)` is used later (e.g. for dispatch).
This basically tries to exploit const-prop' profitability in the
following kind of case:
```julia
kernel(::Val{1}, args...) = ...
kernel(::Val{2}, args...) = ...
function profitable1(x::Int, args...)
kernel(Val(x), args...)
end
```
This allows the compiler to perform const-prop' for case like #45952
even if the primary heuristics based on inlining cost gets confused.
- branching-profitability: constant branch condition is generally very
profitable as it can shape up generated code as well as narrow down
the return type inference by cutting off the dead branch.
```julia
function profitable2(raise::Bool, args...)
v = op(args...)
if v === nothing && raise
return nothing
end
return v
end
```
Currently this commit passes all the test cases and also actually
improves target type stabilities, but doesn't work very ideally as it
seems to be a bit too aggressive (this commit right now strictly
increases the chances of const-propagation). I'd like to further tweak
this heuristic to keep the latency in general cases.