Skip to content

Commit b13fbcc

Browse files
committed
transform InterConditional in abstract_call
1 parent 4e39251 commit b13fbcc

File tree

3 files changed

+31
-24
lines changed

3 files changed

+31
-24
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,35 @@ function abstract_call(interp::AbstractInterpreter, fargs::Union{Nothing,Vector{
10331033
add_remark!(interp, sv, "Could not identify method table for call")
10341034
return CallMeta(Any, false)
10351035
end
1036-
return abstract_call_gf_by_type(interp, nothing, argtypes, argtypes_to_type(argtypes), sv, max_methods)
1036+
callinfo = abstract_call_gf_by_type(interp, nothing, argtypes, argtypes_to_type(argtypes), sv, max_methods)
1037+
return callinfo_from_interprocedural(callinfo, fargs)
1038+
end
1039+
callinfo = abstract_call_known(interp, f, fargs, argtypes, sv, max_methods)
1040+
return callinfo_from_interprocedural(callinfo, fargs)
1041+
end
1042+
1043+
function callinfo_from_interprocedural(callinfo::CallMeta, ea::Union{Nothing,Vector{Any}})
1044+
if ea === nothing
1045+
return callinfo
1046+
end
1047+
1048+
rt = callinfo.rt
1049+
if isa(rt, InterConditional)
1050+
# try to convert interprocedural conditional constraint from callee into the constraint
1051+
# on slots of the current frame
1052+
i = rt.slot
1053+
if checkbounds(Bool, ea, i)
1054+
# `InterConditional` is supposed to be passed here only after "valid" `abstract_call`,
1055+
# and thus `i` should always be in bounds of `ea`, but just for safety
1056+
e = @inbounds ea[i]
1057+
if isa(e, Slot)
1058+
return CallMeta(Conditional(e, rt.vtype, rt.elsetype), callinfo.info)
1059+
end
1060+
end
1061+
return CallMeta(widenconditional(rt), callinfo.info)
1062+
else
1063+
return callinfo
10371064
end
1038-
return abstract_call_known(interp, f, fargs, argtypes, sv, max_methods)
10391065
end
10401066

10411067
function sp_type_rewrap(@nospecialize(T), linfo::MethodInstance, isreturn::Bool)
@@ -1144,10 +1170,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
11441170
end
11451171
callinfo = abstract_call(interp, ea, argtypes, sv)
11461172
sv.stmt_info[sv.currpc] = callinfo.info
1147-
rt = callinfo.rt
1148-
t = isa(rt, InterConditional) ?
1149-
transform_from_interconditional(rt, ea) :
1150-
rt
1173+
t = callinfo.rt
11511174
elseif e.head === :new
11521175
t = instanceof_tfunc(abstract_eval_value(interp, e.args[1], vtypes, sv))[1]
11531176
if isconcretetype(t) && !t.mutable
@@ -1258,19 +1281,6 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
12581281
return t
12591282
end
12601283

1261-
# try to convert interprocedural-conditional constraint from callee into constraints for
1262-
# the current frame
1263-
function transform_from_interconditional(rt::InterConditional, ea::Vector{Any})
1264-
i = rt.slot
1265-
if checkbounds(Bool, ea, i)
1266-
e = @inbounds ea[i]
1267-
if isa(e, Slot)
1268-
return Conditional(e, rt.vtype, rt.elsetype)
1269-
end
1270-
end
1271-
return widenconditional(rt)
1272-
end
1273-
12741284
function abstract_eval_global(M::Module, s::Symbol)
12751285
if isdefined(M,s) && isconst(M,s)
12761286
return Const(getfield(M,s))

base/compiler/tfuncs.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,10 +1648,7 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s
16481648
if contains_is(argtypes_vec, Union{})
16491649
return Const(Union{})
16501650
end
1651-
rt = abstract_call(interp, nothing, argtypes_vec, sv, -1).rt
1652-
if isa(rt, InterConditional)
1653-
rt = widenconditional(rt)
1654-
end
1651+
rt = widenconditional(abstract_call(interp, nothing, argtypes_vec, sv, -1).rt)
16551652
if isa(rt, Const)
16561653
# output was computed to be constant
16571654
return Const(typeof(rt.val))

base/compiler/typeinfer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ function finish(me::InferenceState, interp::AbstractInterpreter)
421421
nothing
422422
end
423423

424-
bestguess_to_interprocedural(@nospecialize(bestguess), _) = bestguess
424+
bestguess_to_interprocedural(@nospecialize(bestguess), _::Int) = bestguess
425425
function bestguess_to_interprocedural(bestguess::Conditional, nargs::Int)
426426
# keep `Conditional` return type only when it constrains any of call argument
427427
i = slot_id(bestguess.var)

0 commit comments

Comments
 (0)