Skip to content

Commit aa85568

Browse files
committed
compiler: setup CallInfo interface type
This commit defines new `CallInfo` abstract type that is supposed to be interfaced by all callinfos like `MethodMatchInfo`. Actual interface features will be added in follow commits.
1 parent 75e96c5 commit aa85568

File tree

14 files changed

+99
-94
lines changed

14 files changed

+99
-94
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
7272
# which is all that's required for :consistent-cy. Of course, we don't
7373
# know anything else about this statement.
7474
effects = Effects(; consistent=ALWAYS_TRUE, nonoverlayed)
75-
return CallMeta(Any, effects, false)
75+
return CallMeta(Any, effects, NoCallInfo())
7676
end
7777

7878
argtypes = arginfo.argtypes
7979
matches = find_matching_methods(argtypes, atype, method_table(interp),
8080
InferenceParams(interp).MAX_UNION_SPLITTING, max_methods)
8181
if isa(matches, FailedMethodMatch)
8282
add_remark!(interp, sv, matches.reason)
83-
return CallMeta(Any, Effects(), false)
83+
return CallMeta(Any, Effects(), NoCallInfo())
8484
end
8585

8686
(; valid_worlds, applicable, info) = matches
@@ -219,7 +219,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
219219
method = match.method
220220
sig = match.spec_types
221221
mi = specialize_method(match; preexisting=true)
222-
if mi !== nothing && !const_prop_methodinstance_heuristic(interp, match, mi::MethodInstance, arginfo, sv)
222+
if mi !== nothing && !const_prop_methodinstance_heuristic(interp, match, mi, arginfo, sv)
223223
csig = get_compileable_sig(method, sig, match.sparams)
224224
if csig !== nothing && csig !== sig
225225
# The result of this inference is not directly used, so temporarily empty
@@ -1387,15 +1387,15 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Vector{Any}, sv::
13871387
max_methods::Int = get_max_methods(sv.mod, interp))
13881388
itft = argtype_by_index(argtypes, 2)
13891389
aft = argtype_by_index(argtypes, 3)
1390-
(itft === Bottom || aft === Bottom) && return CallMeta(Bottom, EFFECTS_THROWS, false)
1390+
(itft === Bottom || aft === Bottom) && return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
13911391
aargtypes = argtype_tail(argtypes, 4)
13921392
aftw = widenconst(aft)
13931393
if !isa(aft, Const) && !isa(aft, PartialOpaque) && (!isType(aftw) || has_free_typevars(aftw))
13941394
if !isconcretetype(aftw) || (aftw <: Builtin)
13951395
add_remark!(interp, sv, "Core._apply_iterate called on a function of a non-concrete type")
13961396
# bail now, since it seems unlikely that abstract_call will be able to do any better after splitting
13971397
# this also ensures we don't call abstract_call_gf_by_type below on an IntrinsicFunction or Builtin
1398-
return CallMeta(Any, Effects(), false)
1398+
return CallMeta(Any, Effects(), NoCallInfo())
13991399
end
14001400
end
14011401
res = Union{}
@@ -1470,7 +1470,7 @@ function abstract_apply(interp::AbstractInterpreter, argtypes::Vector{Any}, sv::
14701470
if bail_out_apply(interp, res, sv)
14711471
if i != length(ctypes)
14721472
# No point carrying forward the info, we're not gonna inline it anyway
1473-
retinfo = false
1473+
retinfo = NoCallInfo()
14741474
end
14751475
break
14761476
end
@@ -1670,21 +1670,21 @@ end
16701670
function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, sv::InferenceState)
16711671
ft′ = argtype_by_index(argtypes, 2)
16721672
ft = widenconst(ft′)
1673-
ft === Bottom && return CallMeta(Bottom, EFFECTS_THROWS, false)
1673+
ft === Bottom && return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
16741674
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3))
1675-
types === Bottom && return CallMeta(Bottom, EFFECTS_THROWS, false)
1676-
isexact || return CallMeta(Any, Effects(), false)
1675+
types === Bottom && return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1676+
isexact || return CallMeta(Any, Effects(), NoCallInfo())
16771677
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
16781678
nargtype = typeintersect(types, argtype)
1679-
nargtype === Bottom && return CallMeta(Bottom, EFFECTS_THROWS, false)
1680-
nargtype isa DataType || return CallMeta(Any, Effects(), false) # other cases are not implemented below
1681-
isdispatchelem(ft) || return CallMeta(Any, Effects(), false) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
1679+
nargtype === Bottom && return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
1680+
nargtype isa DataType || return CallMeta(Any, Effects(), NoCallInfo()) # other cases are not implemented below
1681+
isdispatchelem(ft) || return CallMeta(Any, Effects(), NoCallInfo()) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
16821682
ft = ft::DataType
16831683
lookupsig = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
16841684
nargtype = Tuple{ft, nargtype.parameters...}
16851685
argtype = Tuple{ft, argtype.parameters...}
16861686
match, valid_worlds, overlayed = findsup(lookupsig, method_table(interp))
1687-
match === nothing && return CallMeta(Any, Effects(), false)
1687+
match === nothing && return CallMeta(Any, Effects(), NoCallInfo())
16881688
update_valid_age!(sv, valid_worlds)
16891689
method = match.method
16901690
tienv = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
@@ -1730,7 +1730,7 @@ function abstract_finalizer(interp::AbstractInterpreter, argtypes::Vector{Any},
17301730
call = abstract_call(interp, ArgInfo(nothing, finalizer_argvec), sv, 1)
17311731
return CallMeta(Nothing, Effects(), FinalizerInfo(call.info, call.effects))
17321732
end
1733-
return CallMeta(Nothing, Effects(), false)
1733+
return CallMeta(Nothing, Effects(), NoCallInfo())
17341734
end
17351735

17361736
# call where the function is known exactly
@@ -1752,10 +1752,10 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
17521752
end
17531753
rt = abstract_call_builtin(interp, f, arginfo, sv, max_methods)
17541754
effects = builtin_effects(typeinf_lattice(interp), f, argtypes[2:end], rt)
1755-
return CallMeta(rt, effects, false)
1755+
return CallMeta(rt, effects, NoCallInfo())
17561756
elseif isa(f, Core.OpaqueClosure)
17571757
# calling an OpaqueClosure about which we have no information returns no information
1758-
return CallMeta(Any, Effects(), false)
1758+
return CallMeta(Any, Effects(), NoCallInfo())
17591759
elseif f === Core.kwfunc
17601760
if la == 2
17611761
aty = argtypes[2]
@@ -1766,11 +1766,11 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
17661766
end
17671767
end
17681768
end
1769-
return CallMeta(Any, EFFECTS_UNKNOWN, false)
1769+
return CallMeta(Any, EFFECTS_UNKNOWN, NoCallInfo())
17701770
elseif f === TypeVar
17711771
# Manually look through the definition of TypeVar to
17721772
# make sure to be able to get `PartialTypeVar`s out.
1773-
(la < 2 || la > 4) && return CallMeta(Union{}, EFFECTS_UNKNOWN, false)
1773+
(la < 2 || la > 4) && return CallMeta(Union{}, EFFECTS_UNKNOWN, NoCallInfo())
17741774
n = argtypes[2]
17751775
ub_var = Const(Any)
17761776
lb_var = Const(Union{})
@@ -1780,14 +1780,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
17801780
elseif la == 3
17811781
ub_var = argtypes[3]
17821782
end
1783-
return CallMeta(typevar_tfunc(n, lb_var, ub_var), EFFECTS_UNKNOWN, false)
1783+
return CallMeta(typevar_tfunc(n, lb_var, ub_var), EFFECTS_UNKNOWN, NoCallInfo())
17841784
elseif f === UnionAll
1785-
return CallMeta(abstract_call_unionall(argtypes), EFFECTS_UNKNOWN, false)
1785+
return CallMeta(abstract_call_unionall(argtypes), EFFECTS_UNKNOWN, NoCallInfo())
17861786
elseif f === Tuple && la == 2
17871787
aty = argtypes[2]
17881788
ty = isvarargtype(aty) ? unwrapva(aty) : widenconst(aty)
17891789
if !isconcretetype(ty)
1790-
return CallMeta(Tuple, EFFECTS_UNKNOWN, false)
1790+
return CallMeta(Tuple, EFFECTS_UNKNOWN, NoCallInfo())
17911791
end
17921792
elseif is_return_type(f)
17931793
return return_type_tfunc(interp, argtypes, sv)
@@ -1802,11 +1802,11 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
18021802
# mark !== as exactly a negated call to ===
18031803
rty = abstract_call_known(interp, (===), arginfo, sv, max_methods).rt
18041804
if isa(rty, Conditional)
1805-
return CallMeta(Conditional(rty.slot, rty.elsetype, rty.thentype), EFFECTS_TOTAL, false) # swap if-else
1805+
return CallMeta(Conditional(rty.slot, rty.elsetype, rty.thentype), EFFECTS_TOTAL, NoCallInfo()) # swap if-else
18061806
elseif isa(rty, Const)
18071807
return CallMeta(Const(rty.val === false), EFFECTS_TOTAL, MethodResultPure())
18081808
end
1809-
return CallMeta(rty, EFFECTS_TOTAL, false)
1809+
return CallMeta(rty, EFFECTS_TOTAL, NoCallInfo())
18101810
elseif la == 3 && istopfunction(f, :(>:))
18111811
# mark issupertype as a exact alias for issubtype
18121812
# swap T1 and T2 arguments and call <:
@@ -1816,7 +1816,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
18161816
fargs = nothing
18171817
end
18181818
argtypes = Any[typeof(<:), argtypes[3], argtypes[2]]
1819-
return CallMeta(abstract_call_known(interp, <:, ArgInfo(fargs, argtypes), sv, max_methods).rt, EFFECTS_TOTAL, false)
1819+
return CallMeta(abstract_call_known(interp, <:, ArgInfo(fargs, argtypes), sv, max_methods).rt, EFFECTS_TOTAL, NoCallInfo())
18201820
elseif la == 2 &&
18211821
(a2 = argtypes[2]; isa(a2, Const)) && (svecval = a2.val; isa(svecval, SimpleVector)) &&
18221822
istopfunction(f, :length)
@@ -1898,13 +1898,13 @@ function abstract_call(interp::AbstractInterpreter, arginfo::ArgInfo,
18981898
return abstract_call_opaque_closure(interp,
18991899
ft, ArgInfo(arginfo.fargs, newargtypes), sv, #=check=#true)
19001900
elseif (uft = unwrap_unionall(widenconst(ft)); isa(uft, DataType) && uft.name === typename(Core.OpaqueClosure))
1901-
return CallMeta(rewrap_unionall((uft::DataType).parameters[2], widenconst(ft)), Effects(), false)
1901+
return CallMeta(rewrap_unionall((uft::DataType).parameters[2], widenconst(ft)), Effects(), NoCallInfo())
19021902
elseif f === nothing
19031903
# non-constant function, but the number of arguments is known
19041904
# and the ft is not a Builtin or IntrinsicFunction
19051905
if hasintersect(widenconst(ft), Union{Builtin, Core.OpaqueClosure})
19061906
add_remark!(interp, sv, "Could not identify method table for call")
1907-
return CallMeta(Any, Effects(), false)
1907+
return CallMeta(Any, Effects(), NoCallInfo())
19081908
end
19091909
max_methods = max_methods === nothing ? get_max_methods(sv.mod, interp) : max_methods
19101910
return abstract_call_gf_by_type(interp, nothing, arginfo, argtypes_to_type(argtypes), sv, max_methods)

base/compiler/inferencestate.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ mutable struct InferenceState
106106
bb_vartables::Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet
107107
ssavaluetypes::Vector{Any}
108108
stmt_edges::Vector{Union{Nothing,Vector{Any}}}
109-
stmt_info::Vector{Any}
109+
stmt_info::Vector{CallInfo}
110110

111111
#= intermediate states for interprocedural abstract interpretation =#
112112
pclimitations::IdSet{InferenceState} # causes of precision restrictions (LimitedAccuracy) on currpc ssavalue
@@ -152,7 +152,7 @@ mutable struct InferenceState
152152
ssavalue_uses = find_ssavalue_uses(code, nssavalues)
153153
nstmts = length(code)
154154
stmt_edges = Union{Nothing, Vector{Any}}[ nothing for i = 1:nstmts ]
155-
stmt_info = Any[ nothing for i = 1:nstmts ]
155+
stmt_info = CallInfo[ NoCallInfo() for i = 1:nstmts ]
156156

157157
nslots = length(src.slotflags)
158158
slottypes = Vector{Any}(undef, nslots)

base/compiler/optimize.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ mutable struct OptimizationState
113113
linfo::MethodInstance
114114
src::CodeInfo
115115
ir::Union{Nothing, IRCode}
116-
stmt_info::Vector{Any}
116+
stmt_info::Vector{CallInfo}
117117
mod::Module
118118
sptypes::Vector{Any} # static parameters
119119
slottypes::Vector{Any}
@@ -146,7 +146,7 @@ mutable struct OptimizationState
146146
if slottypes === nothing
147147
slottypes = Any[ Any for i = 1:nslots ]
148148
end
149-
stmt_info = Any[nothing for i = 1:nssavalues]
149+
stmt_info = CallInfo[ NoCallInfo() for i = 1:nssavalues ]
150150
# cache some useful state computations
151151
def = linfo.def
152152
mod = isa(def, Method) ? def.module : def
@@ -598,7 +598,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
598598
insert!(code, idx, Expr(:code_coverage_effect))
599599
insert!(codelocs, idx, codeloc)
600600
insert!(ssavaluetypes, idx, Nothing)
601-
insert!(stmtinfo, idx, nothing)
601+
insert!(stmtinfo, idx, NoCallInfo())
602602
insert!(ssaflags, idx, IR_FLAG_NULL)
603603
if ssachangemap === nothing
604604
ssachangemap = fill(0, nstmts)
@@ -619,7 +619,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
619619
insert!(code, idx + 1, ReturnNode())
620620
insert!(codelocs, idx + 1, codelocs[idx])
621621
insert!(ssavaluetypes, idx + 1, Union{})
622-
insert!(stmtinfo, idx + 1, nothing)
622+
insert!(stmtinfo, idx + 1, NoCallInfo())
623623
insert!(ssaflags, idx + 1, ssaflags[idx])
624624
if ssachangemap === nothing
625625
ssachangemap = fill(0, nstmts)

base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ function escape_call!(astate::AnalysisState, pc::Int, args::Vector{Any}, callinf
12901290
# now cascade to the builtin handling
12911291
escape_call!(astate, pc, args)
12921292
return
1293-
elseif isa(info, CallInfo)
1293+
elseif isa(info, EACallInfo)
12941294
for linfo in info.linfos
12951295
escape_invoke!(astate, pc, args, linfo, 1)
12961296
end

base/compiler/ssair/EscapeAnalysis/interprocedural.jl

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
# TODO this file contains many duplications with the inlining analysis code, factor them out
22

33
import Core.Compiler:
4-
MethodInstance, InferenceResult, Signature, ConstPropResult, ConcreteResult, SemiConcreteResult,
5-
MethodResultPure, MethodMatchInfo, UnionSplitInfo, ConstCallInfo, InvokeCallInfo,
6-
call_sig, argtypes_to_type, is_builtin, is_return_type, istopfunction, validate_sparams,
7-
specialize_method, invoke_rewrite
4+
MethodInstance, InferenceResult, Signature, ConstPropResult, ConcreteResult,
5+
SemiConcreteResult, CallInfo, NoCallInfo, MethodResultPure, MethodMatchInfo,
6+
UnionSplitInfo, ConstCallInfo, InvokeCallInfo,
7+
call_sig, argtypes_to_type, is_builtin, is_return_type, istopfunction,
8+
validate_sparams, specialize_method, invoke_rewrite
89

910
const Linfo = Union{MethodInstance,InferenceResult}
10-
struct CallInfo
11+
struct EACallInfo
1112
linfos::Vector{Linfo}
1213
nothrow::Bool
1314
end
1415

15-
function resolve_call(ir::IRCode, stmt::Expr, @nospecialize(info))
16+
function resolve_call(ir::IRCode, stmt::Expr, @nospecialize(info::CallInfo))
1617
sig = call_sig(ir, stmt)
1718
if sig === nothing
1819
return missing
@@ -36,7 +37,7 @@ function resolve_call(ir::IRCode, stmt::Expr, @nospecialize(info))
3637
end
3738
if info isa MethodResultPure
3839
return true
39-
elseif info === false
40+
elseif info === NoCallInfo
4041
return missing
4142
end
4243
# TODO handle OpaqueClosureCallInfo
@@ -63,16 +64,16 @@ function analyze_invoke_call(sig::Signature, info::InvokeCallInfo)
6364
end
6465
result = info.result
6566
if isa(result, ConstPropResult)
66-
return CallInfo(Linfo[result.result], true)
67+
return EACallInfo(Linfo[result.result], true)
6768
elseif isa(result, ConcreteResult)
68-
return CallInfo(Linfo[result.mi], true)
69+
return EACallInfo(Linfo[result.mi], true)
6970
elseif isa(result, SemiConcreteResult)
70-
return CallInfo(Linfo[result.mi], true)
71+
return EACallInfo(Linfo[result.mi], true)
7172
else
7273
argtypes = invoke_rewrite(sig.argtypes)
7374
mi = analyze_match(match, length(argtypes))
7475
mi === nothing && return missing
75-
return CallInfo(Linfo[mi], true)
76+
return EACallInfo(Linfo[mi], true)
7677
end
7778
end
7879

@@ -110,7 +111,7 @@ function analyze_const_call(sig::Signature, cinfo::ConstCallInfo)
110111
nothrow &= match.fully_covers
111112
end
112113
end
113-
return CallInfo(linfos, nothrow)
114+
return EACallInfo(linfos, nothrow)
114115
end
115116

116117
function analyze_call(sig::Signature, infos::Vector{MethodMatchInfo})
@@ -133,7 +134,7 @@ function analyze_call(sig::Signature, infos::Vector{MethodMatchInfo})
133134
nothrow &= match.fully_covers
134135
end
135136
end
136-
return CallInfo(linfos, nothrow)
137+
return EACallInfo(linfos, nothrow)
137138
end
138139

139140
function analyze_match(match::MethodMatch, npassedargs::Int)

base/compiler/ssair/inlining.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,14 +1091,14 @@ function inline_apply!(
10911091
if isa(info, UnionSplitApplyCallInfo)
10921092
if length(info.infos) != 1
10931093
# TODO: Handle union split applies?
1094-
new_info = info = false
1094+
new_info = info = NoCallInfo()
10951095
else
10961096
info = info.infos[1]
10971097
new_info = info.call
10981098
end
10991099
else
1100-
@assert info === nothing || info === false
1101-
new_info = info = false
1100+
@assert info === NoCallInfo()
1101+
new_info = info = NoCallInfo()
11021102
end
11031103
arg_start = 3
11041104
argtypes = sig.argtypes
@@ -1618,7 +1618,7 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
16181618
inline_const_if_inlineable!(ir[SSAValue(idx)]) && continue
16191619
info = info.info
16201620
end
1621-
if info === false
1621+
if info === NoCallInfo()
16221622
# Inference determined this couldn't be analyzed. Don't question it.
16231623
continue
16241624
end

base/compiler/ssair/ir.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,15 @@ const AnySSAValue = Union{SSAValue, OldSSAValue, NewSSAValue}
188188
struct InstructionStream
189189
inst::Vector{Any}
190190
type::Vector{Any}
191-
info::Vector{Any}
191+
info::Vector{CallInfo}
192192
line::Vector{Int32}
193193
flag::Vector{UInt8}
194194
end
195195
function InstructionStream(len::Int)
196-
insts = Array{Any}(undef, len)
197-
types = Array{Any}(undef, len)
198-
info = Array{Any}(undef, len)
199-
fill!(info, nothing)
196+
insts = Vector{Any}(undef, len)
197+
types = Vector{Any}(undef, len)
198+
info = Vector{CallInfo}(undef, len)
199+
fill!(info, NoCallInfo())
200200
lines = fill(Int32(0), len)
201201
flags = fill(IR_FLAG_NULL, len)
202202
return InstructionStream(insts, types, info, lines, flags)
@@ -227,7 +227,7 @@ function resize!(stmts::InstructionStream, len)
227227
for i in (old_length + 1):len
228228
stmts.line[i] = 0
229229
stmts.flag[i] = IR_FLAG_NULL
230-
stmts.info[i] = nothing
230+
stmts.info[i] = NoCallInfo()
231231
end
232232
return stmts
233233
end

base/compiler/ssair/irinterp.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ end
1414
function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
1515
arginfo::ArgInfo, @nospecialize(atype),
1616
sv::IRCode, max_methods::Int)
17-
return CallMeta(Any, Effects(), false)
17+
return CallMeta(Any, Effects(), NoCallInfo())
1818
end
1919

2020
function collect_limitations!(@nospecialize(typ), ::IRCode)

base/compiler/ssair/legacy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function inflate_ir!(ci::CodeInfo, sptypes::Vector{Any}, argtypes::Vector{Any})
3939
if !isa(ssavaluetypes, Vector{Any})
4040
ssavaluetypes = Any[ Any for i = 1:ssavaluetypes::Int ]
4141
end
42-
info = Any[nothing for i = 1:nstmts]
42+
info = CallInfo[NoCallInfo() for i = 1:nstmts]
4343
stmts = InstructionStream(code, ssavaluetypes, info, ci.codelocs, ci.ssaflags)
4444
linetable = ci.linetable
4545
if !isa(linetable, Vector{LineInfoNode})

0 commit comments

Comments
 (0)