@@ -44,7 +44,8 @@ struct MethodMatchInfo <: CallInfo
44
44
return new (results, mt, atype, fullmatch, edges)
45
45
end
46
46
end
47
- function add_edges_impl (edges:: Vector{Any} , info:: MethodMatchInfo )
47
+ add_edges_impl (edges:: Vector{Any} , info:: MethodMatchInfo ) = _add_edges_impl (edges, info)
48
+ function _add_edges_impl (edges:: Vector{Any} , info:: MethodMatchInfo , mi_edge:: Bool = false )
48
49
if ! fully_covering (info)
49
50
# add legacy-style missing backedge info also
50
51
exists = false
@@ -66,7 +67,7 @@ function add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo)
66
67
edge = info. edges[1 ]
67
68
m = info. results[1 ]
68
69
if edge === nothing
69
- mi = specialize_method (m)
70
+ mi = specialize_method (m) # don't allow `Method`-edge for this optimized format
70
71
edge = mi
71
72
else
72
73
mi = edge. def
@@ -88,13 +89,11 @@ function add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo)
88
89
edge = info. edges[i]
89
90
m = info. results[i]
90
91
if edge === nothing
91
- # push!(edges, m.method)
92
- mi = specialize_method (m)
93
- push! (edges, mi)
92
+ edge = mi_edge ? specialize_method (m) : m. method
94
93
else
95
94
@assert edge. def. def === m. method
96
- push! (edges, edge)
97
95
end
96
+ push! (edges, edge)
98
97
end
99
98
nothing
100
99
end
@@ -112,11 +111,11 @@ function add_one_edge!(edges::Vector{Any}, edge::MethodInstance)
112
111
end
113
112
function add_one_edge! (edges:: Vector{Any} , edge:: CodeInstance )
114
113
for i in 1 : length (edges)
115
- edgeᵢ = edges[i]
114
+ edgeᵢ_orig = edgeᵢ = edges[i]
116
115
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ. def)
117
116
edgeᵢ isa MethodInstance || continue
118
117
if edgeᵢ === edge. def && ! (i > 1 && edges[i- 1 ] isa Type)
119
- if edges[i] isa MethodInstance
118
+ if edgeᵢ_orig isa MethodInstance
120
119
# found edge we can upgrade
121
120
edges[i] = edge
122
121
return
@@ -149,7 +148,9 @@ struct UnionSplitInfo <: CallInfo
149
148
split:: Vector{MethodMatchInfo}
150
149
end
151
150
add_edges_impl (edges:: Vector{Any} , info:: UnionSplitInfo ) =
152
- for split in info. split; add_edges! (edges, split); end
151
+ _add_edges_impl (edges, info)
152
+ _add_edges_impl (edges:: Vector{Any} , info:: UnionSplitInfo , mi_edge:: Bool = false ) =
153
+ for split in info. split; _add_edges_impl (edges, split, mi_edge); end
153
154
nsplit_impl (info:: UnionSplitInfo ) = length (info. split)
154
155
getsplit_impl (info:: UnionSplitInfo , idx:: Int ) = getsplit (info. split[idx], 1 )
155
156
getresult_impl (:: UnionSplitInfo , :: Int ) = nothing
@@ -294,21 +295,21 @@ struct InvokeCallInfo <: CallInfo
294
295
result:: Union{Nothing,ConstResult}
295
296
atype # ::Type
296
297
end
297
- function add_edges_impl (edges:: Vector{Any} , info:: InvokeCallInfo )
298
+ add_edges_impl (edges:: Vector{Any} , info:: InvokeCallInfo ) =
299
+ _add_edges_impl (edges, info)
300
+ function _add_edges_impl (edges:: Vector{Any} , info:: InvokeCallInfo , mi_edge:: Bool = false )
298
301
edge = info. edge
299
302
if edge === nothing
300
- mi = specialize_method (info. match)
301
- add_invoke_edge! (edges, info. atype, mi)
302
- else
303
- add_invoke_edge! (edges, info. atype, edge)
303
+ edge = mi_edge ? specialize_method (info. match) : info. match. method
304
304
end
305
+ add_invoke_edge! (edges, info. atype, edge)
305
306
nothing
306
307
end
307
- function add_invoke_edge! (edges:: Vector{Any} , @nospecialize (atype), edge:: MethodInstance )
308
+ function add_invoke_edge! (edges:: Vector{Any} , @nospecialize (atype), edge:: Union{ MethodInstance,Method} )
308
309
for i in 2 : length (edges)
309
310
edgeᵢ = edges[i]
310
311
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ. def)
311
- edgeᵢ isa MethodInstance || continue
312
+ edgeᵢ isa MethodInstance || edgeᵢ isa Method || continue
312
313
if edgeᵢ === edge
313
314
edge_minus_1 = edges[i- 1 ]
314
315
if edge_minus_1 isa Type && edge_minus_1 == atype
@@ -321,13 +322,13 @@ function add_invoke_edge!(edges::Vector{Any}, @nospecialize(atype), edge::Method
321
322
end
322
323
function add_invoke_edge! (edges:: Vector{Any} , @nospecialize (atype), edge:: CodeInstance )
323
324
for i in 2 : length (edges)
324
- edgeᵢ = edges[i]
325
+ edgeᵢ_orig = edgeᵢ = edges[i]
325
326
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ. def)
326
- edgeᵢ isa MethodInstance || continue
327
- if edgeᵢ === edge. def
327
+ if (( edgeᵢ isa MethodInstance && edgeᵢ === edge . def) ||
328
+ ( edgeᵢ isa Method && edgeᵢ === edge. def. def))
328
329
edge_minus_1 = edges[i- 1 ]
329
330
if edge_minus_1 isa Type && edge_minus_1 == atype
330
- if edges[i] isa MethodInstance
331
+ if edgeᵢ_orig isa MethodInstance || edgeᵢ_orig isa Method
331
332
# found edge we can upgrade
332
333
edges[i] = edge
333
334
return
426
427
add_edges_impl (edges:: Vector{Any} , info:: ModifyOpInfo ) = add_edges! (edges, info. info)
427
428
428
429
struct VirtualMethodMatchInfo <: CallInfo
429
- info:: CallInfo
430
+ info:: Union{MethodMatchInfo,UnionSplitInfo,InvokeCallInfo}
430
431
end
431
- add_edges_impl (edges:: Vector{Any} , info:: VirtualMethodMatchInfo ) = add_edges! (edges, info. info)
432
+ add_edges_impl (edges:: Vector{Any} , info:: VirtualMethodMatchInfo ) =
433
+ _add_edges_impl (edges, info. info, #= mi_edge=# true )
432
434
433
435
@specialize
0 commit comments