Skip to content

Commit 0c2d99c

Browse files
committed
simplify the fields of UnionSplitInfo
xref: <#54972 (comment)>
1 parent 550f321 commit 0c2d99c

File tree

3 files changed

+60
-63
lines changed

3 files changed

+60
-63
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -280,17 +280,41 @@ any_ambig(info::MethodMatchInfo) = any_ambig(info.results)
280280
any_ambig(m::MethodMatches) = any_ambig(m.info)
281281
fully_covering(info::MethodMatchInfo) = info.fullmatch
282282
fully_covering(m::MethodMatches) = fully_covering(m.info)
283+
function add_uncovered_edges!(sv::AbsIntState, info::MethodMatchInfo, @nospecialize(atype))
284+
fully_covering(info) || add_mt_backedge!(sv, info.mt, atype)
285+
nothing
286+
end
287+
add_uncovered_edges!(sv::AbsIntState, matches::MethodMatches, @nospecialize(atype)) =
288+
add_uncovered_edges!(sv, matches.info, atype)
283289

284290
struct UnionSplitMethodMatches
285291
applicable::Vector{Any}
286292
applicable_argtypes::Vector{Vector{Any}}
287293
info::UnionSplitInfo
288294
valid_worlds::WorldRange
289295
end
290-
any_ambig(info::UnionSplitInfo) = any(any_ambig, info.matches)
296+
any_ambig(info::UnionSplitInfo) = any(any_ambig, info.split)
291297
any_ambig(m::UnionSplitMethodMatches) = any_ambig(m.info)
292-
fully_covering(info::UnionSplitInfo) = all(info.fullmatches)
298+
fully_covering(info::UnionSplitInfo) = all(fully_covering, info.split)
293299
fully_covering(m::UnionSplitMethodMatches) = fully_covering(m.info)
300+
function add_uncovered_edges!(sv::AbsIntState, info::UnionSplitInfo, @nospecialize(atype))
301+
all(fully_covering, info.split) && return nothing
302+
# add mt backedges with removing duplications
303+
for mt in uncovered_method_tables(info)
304+
add_mt_backedge!(sv, mt, atype)
305+
end
306+
end
307+
add_uncovered_edges!(sv::AbsIntState, matches::UnionSplitMethodMatches, @nospecialize(atype)) =
308+
add_uncovered_edges!(sv, matches.info, atype)
309+
function uncovered_method_tables(info::UnionSplitInfo)
310+
mts = MethodTable[]
311+
for mminfo in info.split
312+
fully_covering(mminfo) && continue
313+
any(mt′::MethodTable->mt′===mminfo.mt, mts) && continue
314+
push!(mts, mminfo.mt)
315+
end
316+
return mts
317+
end
294318

295319
function find_method_matches(interp::AbstractInterpreter, argtypes::Vector{Any}, @nospecialize(atype);
296320
max_union_splitting::Int = InferenceParams(interp).max_union_splitting,
@@ -308,43 +332,30 @@ is_union_split_eligible(𝕃::AbstractLattice, argtypes::Vector{Any}, max_union_
308332
function find_union_split_method_matches(interp::AbstractInterpreter, argtypes::Vector{Any},
309333
@nospecialize(atype), max_methods::Int)
310334
split_argtypes = switchtupleunion(typeinf_lattice(interp), argtypes)
311-
infos = MethodLookupResult[]
335+
infos = MethodMatchInfo[]
312336
applicable = Any[]
313337
applicable_argtypes = Vector{Any}[] # arrays like `argtypes`, including constants, for each match
314338
valid_worlds = WorldRange()
315-
mts = MethodTable[]
316-
fullmatches = Bool[]
317339
for i in 1:length(split_argtypes)
318340
arg_n = split_argtypes[i]::Vector{Any}
319341
sig_n = argtypes_to_type(arg_n)
320342
mt = ccall(:jl_method_table_for, Any, (Any,), sig_n)
321343
mt === nothing && return FailedMethodMatch("Could not identify method table for call")
322344
mt = mt::MethodTable
323-
matches = findall(sig_n, method_table(interp); limit = max_methods)
324-
if matches === nothing
345+
thismatches = findall(sig_n, method_table(interp); limit = max_methods)
346+
if thismatches === nothing
325347
return FailedMethodMatch("For one of the union split cases, too many methods matched")
326348
end
327-
push!(infos, matches)
328-
for m in matches
349+
for m in thismatches
329350
push!(applicable, m)
330351
push!(applicable_argtypes, arg_n)
331352
end
332-
valid_worlds = intersect(valid_worlds, matches.valid_worlds)
333-
thisfullmatch = any(match::MethodMatch->match.fully_covers, matches)
334-
mt_found = false
335-
for (i, mt′) in enumerate(mts)
336-
if mt′ === mt
337-
fullmatches[i] &= thisfullmatch
338-
mt_found = true
339-
break
340-
end
341-
end
342-
if !mt_found
343-
push!(mts, mt)
344-
push!(fullmatches, thisfullmatch)
345-
end
353+
valid_worlds = intersect(valid_worlds, thismatches.valid_worlds)
354+
thisfullmatch = any(match::MethodMatch->match.fully_covers, thismatches)
355+
thisinfo = MethodMatchInfo(thismatches, mt, thisfullmatch)
356+
push!(infos, thisinfo)
346357
end
347-
info = UnionSplitInfo(infos, mts, fullmatches)
358+
info = UnionSplitInfo(infos)
348359
return UnionSplitMethodMatches(
349360
applicable, applicable_argtypes, info, valid_worlds)
350361
end
@@ -583,14 +594,7 @@ function add_call_backedges!(interp::AbstractInterpreter, @nospecialize(rettype)
583594
end
584595
# also need an edge to the method table in case something gets
585596
# added that did not intersect with any existing method
586-
if isa(matches, MethodMatches)
587-
fully_covering(matches) || add_mt_backedge!(sv, matches.info.mt, atype)
588-
else
589-
matches::UnionSplitMethodMatches
590-
for (thisfullmatch, mt) in zip(matches.info.fullmatches, matches.info.mts)
591-
thisfullmatch || add_mt_backedge!(sv, mt, atype)
592-
end
593-
end
597+
add_uncovered_edges!(sv, matches, atype)
594598
return nothing
595599
end
596600

base/compiler/stmtinfo.jl

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ end
3939
nsplit_impl(info::MethodMatchInfo) = 1
4040
getsplit_impl(info::MethodMatchInfo, idx::Int) = (@assert idx == 1; info.results)
4141
getresult_impl(::MethodMatchInfo, ::Int) = nothing
42-
add_uncovered_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, @nospecialize(atype)) = (!info.fullmatch && push!(edges, info.mt, atype); )
42+
function add_uncovered_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, @nospecialize(atype))
43+
fully_covering(info) || push!(edges, info.mt, atype)
44+
nothing
45+
end
4346

4447
"""
4548
info::UnionSplitInfo <: CallInfo
@@ -51,25 +54,25 @@ each partition (`info.matches::Vector{MethodMatchInfo}`).
5154
This info is illegal on any statement that is not a call to a generic function.
5255
"""
5356
struct UnionSplitInfo <: CallInfo
54-
matches::Vector{MethodLookupResult}
55-
mts::Vector{MethodTable}
56-
fullmatches::Vector{Bool}
57+
split::Vector{MethodMatchInfo}
5758
end
5859

5960
nmatches(info::MethodMatchInfo) = length(info.results)
6061
function nmatches(info::UnionSplitInfo)
6162
n = 0
62-
for mminfo in info.matches
63-
n += length(mminfo)
63+
for mminfo in info.split
64+
n += nmatches(mminfo)
6465
end
6566
return n
6667
end
67-
nsplit_impl(info::UnionSplitInfo) = length(info.matches)
68-
getsplit_impl(info::UnionSplitInfo, idx::Int) = info.matches[idx]
68+
nsplit_impl(info::UnionSplitInfo) = length(info.split)
69+
getsplit_impl(info::UnionSplitInfo, idx::Int) = getsplit(info.split[idx], 1)
6970
getresult_impl(::UnionSplitInfo, ::Int) = nothing
7071
function add_uncovered_edges_impl(edges::Vector{Any}, info::UnionSplitInfo, @nospecialize(atype))
71-
for (mt, fullmatch) in zip(info.mts, info.fullmatches)
72-
!fullmatch && push!(edges, mt, atype)
72+
all(fully_covering, info.split) && return nothing
73+
# add mt backedges with removing duplications
74+
for mt in uncovered_method_tables(info)
75+
push!(edges, mt, atype)
7376
end
7477
end
7578

base/compiler/tfuncs.jl

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,33 +2979,23 @@ function abstract_applicable(interp::AbstractInterpreter, argtypes::Vector{Any},
29792979
else
29802980
(; valid_worlds, applicable) = matches
29812981
update_valid_age!(sv, valid_worlds)
2982-
2983-
# also need an edge to the method table in case something gets
2984-
# added that did not intersect with any existing method
2985-
if isa(matches, MethodMatches)
2986-
fully_covering(matches) || add_mt_backedge!(sv, matches.info.mt, atype)
2987-
else
2988-
for (thisfullmatch, mt) in zip(matches.info.fullmatches, matches.info.mts)
2989-
thisfullmatch || add_mt_backedge!(sv, mt, atype)
2990-
end
2991-
end
2992-
29932982
napplicable = length(applicable)
29942983
if napplicable == 0
29952984
rt = Const(false) # never any matches
2985+
elseif !fully_covering(matches) || any_ambig(matches)
2986+
# Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature.
2987+
rt = Bool
29962988
else
29972989
rt = Const(true) # has applicable matches
2998-
for i in 1:napplicable
2999-
match = applicable[i]::MethodMatch
3000-
edge = specialize_method(match)::MethodInstance
3001-
add_backedge!(sv, edge)
3002-
end
3003-
3004-
if !fully_covering(matches) || any_ambig(matches)
3005-
# Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature.
3006-
rt = Bool
3007-
end
30082990
end
2991+
for i in 1:napplicable
2992+
match = applicable[i]::MethodMatch
2993+
edge = specialize_method(match)::MethodInstance
2994+
add_backedge!(sv, edge)
2995+
end
2996+
# also need an edge to the method table in case something gets
2997+
# added that did not intersect with any existing method
2998+
add_uncovered_edges!(sv, matches, atype)
30092999
end
30103000
return CallMeta(rt, Union{}, EFFECTS_TOTAL, NoCallInfo())
30113001
end

0 commit comments

Comments
 (0)