Skip to content

Commit

Permalink
inference: override return type inference by const-prop more carefully
Browse files Browse the repository at this point in the history
A return type derived by const-prop' inference can be wider than that of
non const-prop' inference in rare cases e.g. when there are cycles but
cached result is still accurate. This commit checks if the const-prop'ed
result is really more accurate than non-const result.

fix Ferrite-FEM/Tensors.jl#178
  • Loading branch information
aviatesk committed Feb 21, 2022
1 parent f879d20 commit 920480e
Showing 1 changed file with 27 additions and 13 deletions.
40 changes: 27 additions & 13 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,13 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
end
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
this_arginfo = ArgInfo(fargs, this_argtypes)
const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv)
const_call_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv)
effects = result.edge_effects
if const_result !== nothing
(; rt, effects, const_result) = const_result
const_result = nothing
if const_call_result !== nothing
if const_call_result.rt rt
(; rt, effects, const_result) = const_call_result
end
end
tristate_merge!(sv, effects)
push!(const_results, const_result)
Expand Down Expand Up @@ -133,11 +136,17 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
# this is in preparation for inlining, or improving the return result
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
this_arginfo = ArgInfo(fargs, this_argtypes)
const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv)
const_call_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv)
effects = result.edge_effects
if const_result !== nothing
this_rt = const_result.rt
(; effects, const_result) = const_result
const_result = nothing
if const_call_result !== nothing
this_const_rt = const_call_result.rt
# return type of const-prop' inference can be wider than that of non const-prop' inference
# e.g. in cases when there are cycles but cached result is still accurate
if this_const_rt this_rt
this_rt = this_const_rt
(; effects, const_result) = const_call_result
end
end
tristate_merge!(sv, effects)
push!(const_results, const_result)
Expand Down Expand Up @@ -1483,9 +1492,12 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
# t, a = ti.parameters[i], argtypes′[i]
# argtypes′[i] = t ⊑ a ? t : a
# end
const_result = abstract_call_method_with_const_args(interp, result, singleton_type(ft′), arginfo, match, sv)
if const_result !== nothing
(;rt, const_result) = const_result
const_call_result = abstract_call_method_with_const_args(interp, result, singleton_type(ft′), arginfo, match, sv)
const_result = nothing
if const_call_result !== nothing
if const_call_result.rt rt
(; rt, const_result) = const_call_result
end
end
return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result))
end
Expand Down Expand Up @@ -1630,10 +1642,12 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part
match = MethodMatch(sig, Core.svec(), closure.source, sig <: rewrap_unionall(sigT, tt))
const_result = nothing
if !result.edgecycle
const_result = abstract_call_method_with_const_args(interp, result, nothing,
const_call_result = abstract_call_method_with_const_args(interp, result, nothing,
arginfo, match, sv)
if const_result !== nothing
(;rt, const_result) = const_result
if const_call_result !== nothing
if const_call_result.rt rt
(; rt, const_result) = const_call_result
end
end
end
info = OpaqueClosureCallInfo(match, const_result)
Expand Down

0 comments on commit 920480e

Please sign in to comment.