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 20, 2022
1 parent e723d37 commit 1ad9f95
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
const_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_rt = const_result.rt
if const_rt rt
rt = const_rt
end
(; effects, const_result) = const_result
end
tristate_merge!(sv, effects)
push!(const_results, const_result)
Expand Down Expand Up @@ -136,7 +140,12 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
const_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
this_const_rt = const_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
end
(; effects, const_result) = const_result
end
tristate_merge!(sv, effects)
Expand Down Expand Up @@ -1485,7 +1494,11 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
# 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_rt = const_result.rt
if const_rt rt
rt = const_rt
end
const_result = const_result.const_result
end
return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result))
end
Expand Down Expand Up @@ -1633,7 +1646,11 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part
const_result = abstract_call_method_with_const_args(interp, result, nothing,
arginfo, match, sv)
if const_result !== nothing
(;rt, const_result) = const_result
const_rt = const_result.rt
if const_rt rt
rt = const_rt
end
const_result = const_result.const_result
end
end
info = OpaqueClosureCallInfo(match, const_result)
Expand Down

0 comments on commit 1ad9f95

Please sign in to comment.