Skip to content

Commit fd6eee7

Browse files
authored
Refactor abstract_eval to separate out statements and values (#36350)
In preparation for adding the ability for statements to return additional info, while values will only ever have a type.
1 parent be72a57 commit fd6eee7

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

base/compiler/abstractinterpretation.jl

+43-24
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ function sp_type_rewrap(@nospecialize(T), linfo::MethodInstance, isreturn::Bool)
970970
end
971971

972972
function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, vtypes::VarTable, sv::InferenceState)
973-
f = abstract_eval(interp, e.args[2], vtypes, sv)
973+
f = abstract_eval_value(interp, e.args[2], vtypes, sv)
974974
# rt = sp_type_rewrap(e.args[3], sv.linfo, true)
975975
at = Any[ sp_type_rewrap(argt, sv.linfo, false) for argt in e.args[4]::SimpleVector ]
976976
pushfirst!(at, f)
@@ -981,7 +981,21 @@ function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, vtypes::V
981981
nothing
982982
end
983983

984-
function abstract_eval(interp::AbstractInterpreter, @nospecialize(e), vtypes::VarTable, sv::InferenceState)
984+
function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::VarTable, sv::InferenceState)
985+
if e.head === :static_parameter
986+
n = e.args[1]
987+
t = Any
988+
if 1 <= n <= length(sv.sptypes)
989+
t = sv.sptypes[n]
990+
end
991+
elseif e.head === :boundscheck
992+
return Bool
993+
else
994+
return Any
995+
end
996+
end
997+
998+
function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::VarTable, sv::InferenceState)
985999
if isa(e, QuoteNode)
9861000
return AbstractEvalConstant((e::QuoteNode).value)
9871001
elseif isa(e, SSAValue)
@@ -992,31 +1006,44 @@ function abstract_eval(interp::AbstractInterpreter, @nospecialize(e), vtypes::Va
9921006
return abstract_eval_global(e.mod, e.name)
9931007
end
9941008

1009+
return AbstractEvalConstant(e)
1010+
end
1011+
1012+
function abstract_eval_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::VarTable, sv::InferenceState)
1013+
if isa(e, Expr)
1014+
return abstract_eval_value_expr(interp, e, vtypes, sv)
1015+
else
1016+
return abstract_eval_special_value(interp, e, vtypes, sv)
1017+
end
1018+
end
1019+
1020+
function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), vtypes::VarTable, sv::InferenceState)
9951021
if !isa(e, Expr)
996-
return AbstractEvalConstant(e)
1022+
return abstract_eval_special_value(interp, e, vtypes, sv)
9971023
end
1024+
9981025
e = e::Expr
9991026
if e.head === :call
10001027
ea = e.args
10011028
n = length(ea)
10021029
argtypes = Vector{Any}(undef, n)
10031030
@inbounds for i = 1:n
1004-
ai = abstract_eval(interp, ea[i], vtypes, sv)
1031+
ai = abstract_eval_value(interp, ea[i], vtypes, sv)
10051032
if ai === Bottom
10061033
return Bottom
10071034
end
10081035
argtypes[i] = ai
10091036
end
10101037
t = abstract_call(interp, ea, argtypes, vtypes, sv)
10111038
elseif e.head === :new
1012-
t = instanceof_tfunc(abstract_eval(interp, e.args[1], vtypes, sv))[1]
1039+
t = instanceof_tfunc(abstract_eval_value(interp, e.args[1], vtypes, sv))[1]
10131040
if isconcretetype(t) && !t.mutable
10141041
args = Vector{Any}(undef, length(e.args)-1)
10151042
ats = Vector{Any}(undef, length(e.args)-1)
10161043
anyconst = false
10171044
allconst = true
10181045
for i = 2:length(e.args)
1019-
at = abstract_eval(interp, e.args[i], vtypes, sv)
1046+
at = abstract_eval_value(interp, e.args[i], vtypes, sv)
10201047
if !anyconst
10211048
anyconst = has_nontrivial_const_info(at)
10221049
end
@@ -1046,9 +1073,9 @@ function abstract_eval(interp::AbstractInterpreter, @nospecialize(e), vtypes::Va
10461073
end
10471074
end
10481075
elseif e.head === :splatnew
1049-
t = instanceof_tfunc(abstract_eval(interp, e.args[1], vtypes, sv))[1]
1076+
t = instanceof_tfunc(abstract_eval_value(interp, e.args[1], vtypes, sv))[1]
10501077
if length(e.args) == 2 && isconcretetype(t) && !t.mutable
1051-
at = abstract_eval(interp, e.args[2], vtypes, sv)
1078+
at = abstract_eval_value(interp, e.args[2], vtypes, sv)
10521079
n = fieldcount(t)
10531080
if isa(at, Const) && isa(at.val, Tuple) && n == length(at.val) &&
10541081
_all(i->at.val[i] isa fieldtype(t, i), 1:n)
@@ -1059,35 +1086,27 @@ function abstract_eval(interp::AbstractInterpreter, @nospecialize(e), vtypes::Va
10591086
end
10601087
end
10611088
elseif e.head === :foreigncall
1062-
abstract_eval(interp, e.args[1], vtypes, sv)
1089+
abstract_eval_value(interp, e.args[1], vtypes, sv)
10631090
t = sp_type_rewrap(e.args[2], sv.linfo, true)
10641091
for i = 3:length(e.args)
1065-
if abstract_eval(interp, e.args[i], vtypes, sv) === Bottom
1092+
if abstract_eval_value(interp, e.args[i], vtypes, sv) === Bottom
10661093
t = Bottom
10671094
end
10681095
end
10691096
elseif e.head === :cfunction
10701097
t = e.args[1]
10711098
isa(t, Type) || (t = Any)
10721099
abstract_eval_cfunction(interp, e, vtypes, sv)
1073-
elseif e.head === :static_parameter
1074-
n = e.args[1]
1075-
t = Any
1076-
if 1 <= n <= length(sv.sptypes)
1077-
t = sv.sptypes[n]
1078-
end
10791100
elseif e.head === :method
10801101
t = (length(e.args) == 1) ? Any : Nothing
10811102
elseif e.head === :copyast
1082-
t = abstract_eval(interp, e.args[1], vtypes, sv)
1103+
t = abstract_eval_value(interp, e.args[1], vtypes, sv)
10831104
if t isa Const && t.val isa Expr
10841105
# `copyast` makes copies of Exprs
10851106
t = Expr
10861107
end
10871108
elseif e.head === :invoke
10881109
error("type inference data-flow error: tried to double infer a function")
1089-
elseif e.head === :boundscheck
1090-
return Bool
10911110
elseif e.head === :isdefined
10921111
sym = e.args[1]
10931112
t = Bool
@@ -1116,7 +1135,7 @@ function abstract_eval(interp::AbstractInterpreter, @nospecialize(e), vtypes::Va
11161135
end
11171136
end
11181137
else
1119-
t = Any
1138+
return abstract_eval_value_expr(interp, e, vtypes, sv)
11201139
end
11211140
@assert !isa(t, TypeVar)
11221141
if isa(t, DataType) && isdefined(t, :instance)
@@ -1175,7 +1194,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
11751194
elseif isa(stmt, GotoNode)
11761195
pc´ = (stmt::GotoNode).label
11771196
elseif isa(stmt, GotoIfNot)
1178-
condt = abstract_eval(interp, stmt.cond, s[pc], frame)
1197+
condt = abstract_eval_value(interp, stmt.cond, s[pc], frame)
11791198
if condt === Bottom
11801199
break
11811200
end
@@ -1209,7 +1228,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
12091228
end
12101229
elseif isa(stmt, ReturnNode)
12111230
pc´ = n + 1
1212-
rt = widenconditional(abstract_eval(interp, stmt.val, s[pc], frame))
1231+
rt = widenconditional(abstract_eval_value(interp, stmt.val, s[pc], frame))
12131232
if !isa(rt, Const) && !isa(rt, Type) && !isa(rt, PartialStruct)
12141233
# only propagate information we know we can store
12151234
# and is valid inter-procedurally
@@ -1254,7 +1273,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
12541273
end
12551274
else
12561275
if hd === :(=)
1257-
t = abstract_eval(interp, stmt.args[2], changes, frame)
1276+
t = abstract_eval_statement(interp, stmt.args[2], changes, frame)
12581277
t === Bottom && break
12591278
frame.src.ssavaluetypes[pc] = t
12601279
lhs = stmt.args[1]
@@ -1269,7 +1288,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
12691288
elseif hd === :inbounds || hd === :meta || hd === :loopinfo || hd == :code_coverage_effect
12701289
# these do not generate code
12711290
else
1272-
t = abstract_eval(interp, stmt, changes, frame)
1291+
t = abstract_eval_statement(interp, stmt, changes, frame)
12731292
t === Bottom && break
12741293
if !isempty(frame.ssavalue_uses[pc])
12751294
record_ssa_assign(pc, t, frame)

0 commit comments

Comments
 (0)