@@ -583,18 +583,16 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter, result::Me
583
583
nargs:: Int = method. nargs
584
584
method. isva && (nargs -= 1 )
585
585
length (arginfo. argtypes) < nargs && return nothing
586
- if ! ( const_prop_argument_heuristic (interp, arginfo) || const_prop_rettype_heuristic (interp, result . rt) )
586
+ if ! const_prop_argument_heuristic (interp, arginfo, sv )
587
587
add_remark! (interp, sv, " [constprop] Disabled by argument and rettype heuristics" )
588
588
return nothing
589
589
end
590
- allconst = is_allconst (arginfo)
591
- if ! force
592
- if ! const_prop_function_heuristic (interp, f, arginfo, nargs, allconst)
593
- add_remark! (interp, sv, " [constprop] Disabled by function heuristic" )
594
- return nothing
595
- end
590
+ all_overridden = is_all_overridden (arginfo)
591
+ if ! force && ! const_prop_function_heuristic (interp, f, arginfo, nargs, all_overridden, sv)
592
+ add_remark! (interp, sv, " [constprop] Disabled by function heuristic" )
593
+ return nothing
596
594
end
597
- force |= allconst
595
+ force |= all_overridden
598
596
mi = specialize_method (match; preexisting= ! force)
599
597
if mi === nothing
600
598
add_remark! (interp, sv, " [constprop] Failed to specialize" )
@@ -618,11 +616,15 @@ function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodC
618
616
return false
619
617
end
620
618
621
- # see if propagating constants may be worthwhile
622
- function const_prop_argument_heuristic (interp:: AbstractInterpreter , (; fargs, argtypes):: ArgInfo )
623
- for a in argtypes
619
+ # determines heuristically whether if constant propagation can be worthwhile
620
+ # by checking if any of given `argtypes` is "interesting" enough to be propagated
621
+ function const_prop_argument_heuristic (_:: AbstractInterpreter , (; fargs, argtypes):: ArgInfo , _:: InferenceState )
622
+ for i in 1 : length (argtypes)
623
+ a = argtypes[i]
624
624
if isa (a, Conditional) && fargs != = nothing
625
- return is_const_prop_profitable_conditional (a, fargs)
625
+ if is_const_prop_profitable_conditional (a, fargs)
626
+ return true
627
+ end
626
628
end
627
629
a = widenconditional (a)
628
630
if has_nontrivial_const_info (a) && is_const_prop_profitable_arg (a)
@@ -662,22 +664,15 @@ function find_constrained_arg(cnd::Conditional, fargs::Vector{Any})
662
664
end
663
665
end
664
666
665
- function const_prop_rettype_heuristic (interp:: AbstractInterpreter , @nospecialize (rettype))
666
- return improvable_via_constant_propagation (rettype)
667
- end
668
-
669
- function is_allconst ((; fargs, argtypes):: ArgInfo )
667
+ # checks if all argtypes has additional information other than what `Type` can provide
668
+ function is_all_overridden ((; fargs, argtypes):: ArgInfo )
670
669
for a in argtypes
671
670
if isa (a, Conditional) && fargs != = nothing
672
671
if is_const_prop_profitable_conditional (a, fargs)
673
672
continue
674
673
end
675
674
end
676
- a = widenconditional (a)
677
- # TODO unify these condition with `has_nontrivial_const_info`
678
- if ! isa (a, Const) && ! isconstType (a) && ! isa (a, PartialStruct) && ! isa (a, PartialOpaque)
679
- return false
680
- end
675
+ is_forwardable_argtype (widenconditional (a)) || return false
681
676
end
682
677
return true
683
678
end
691
686
692
687
function const_prop_function_heuristic (
693
688
interp:: AbstractInterpreter , @nospecialize (f), (; argtypes):: ArgInfo ,
694
- nargs:: Int , allconst :: Bool )
689
+ nargs:: Int , all_overridden :: Bool , _ :: InferenceState )
695
690
if nargs > 1
696
691
if istopfunction (f, :getindex ) || istopfunction (f, :setindex! )
697
692
arrty = argtypes[2 ]
@@ -708,7 +703,7 @@ function const_prop_function_heuristic(
708
703
end
709
704
end
710
705
end
711
- if ! allconst && (istopfunction (f, :+ ) || istopfunction (f, :- ) || istopfunction (f, :* ) ||
706
+ if ! all_overridden && (istopfunction (f, :+ ) || istopfunction (f, :- ) || istopfunction (f, :* ) ||
712
707
istopfunction (f, :(== )) || istopfunction (f, :!= ) ||
713
708
istopfunction (f, :<= ) || istopfunction (f, :>= ) || istopfunction (f, :< ) || istopfunction (f, :> ) ||
714
709
istopfunction (f, :<< ) || istopfunction (f, :>> ))
@@ -1250,7 +1245,7 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
1250
1245
fargs′ = fargs[4 : end ]
1251
1246
pushfirst! (fargs′, fargs[1 ])
1252
1247
arginfo = ArgInfo (fargs′, argtypes′)
1253
- const_prop_argument_heuristic (interp, arginfo) || const_prop_rettype_heuristic (interp, rt ) || return CallMeta (rt, InvokeCallInfo (match, nothing ))
1248
+ const_prop_argument_heuristic (interp, arginfo, sv ) || return CallMeta (rt, InvokeCallInfo (match, nothing ))
1254
1249
# # typeintersect might have narrowed signature, but the accuracy gain doesn't seem worth the cost involved with the lattice comparisons
1255
1250
# for i in 1:length(argtypes′)
1256
1251
# t, a = ti.parameters[i], argtypes′[i]
0 commit comments