@@ -97,10 +97,9 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
97
97
napplicable = length (applicable)
98
98
rettype = Bottom
99
99
edgecycle = false
100
- edges = Any []
100
+ edges = MethodInstance []
101
101
nonbot = 0 # the index of the only non-Bottom inference result if > 0
102
102
seen = 0 # number of signatures actually inferred
103
- istoplevel = sv. linfo. def isa Module
104
103
multiple_matches = napplicable > 1
105
104
106
105
if f != = nothing && napplicable == 1 && is_method_pure (applicable[1 ]:: MethodMatch )
@@ -115,7 +114,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
115
114
match = applicable[i]:: MethodMatch
116
115
method = match. method
117
116
sig = match. spec_types
118
- if istoplevel && ! isdispatchtuple ( sig)
117
+ if bail_out_toplevel_call (interp, sig, sv )
119
118
# only infer concrete call sites in top-level expressions
120
119
add_remark! (interp, sv, " Refusing to infer non-concrete call site in top-level expression" )
121
120
rettype = Any
@@ -135,7 +134,9 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
135
134
end
136
135
edgecycle |= edgecycle1:: Bool
137
136
this_rt = tmerge (this_rt, rt)
138
- this_rt === Any && break
137
+ if bail_out_call (interp, this_rt, sv)
138
+ break
139
+ end
139
140
end
140
141
else
141
142
this_rt, edgecycle1, edge = abstract_call_method (interp, method, sig, match. sparams, multiple_matches, sv)
@@ -153,7 +154,9 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
153
154
end
154
155
seen += 1
155
156
rettype = tmerge (rettype, this_rt)
156
- rettype === Any && break
157
+ if bail_out_call (interp, rettype, sv)
158
+ break
159
+ end
157
160
end
158
161
# try constant propagation if only 1 method is inferred to non-Bottom
159
162
# this is in preparation for inlining, or improving the return result
@@ -179,18 +182,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
179
182
# and avoid keeping track of a more complex result type.
180
183
rettype = Any
181
184
end
182
- if ! (rettype === Any) # adding a new method couldn't refine (widen) this type
183
- for edge in edges
184
- add_backedge! (edge:: MethodInstance , sv)
185
- end
186
- for (thisfullmatch, mt) in zip (fullmatch, mts)
187
- if ! thisfullmatch
188
- # also need an edge to the method table in case something gets
189
- # added that did not intersect with any existing method
190
- add_mt_backedge! (mt, atype, sv)
191
- end
192
- end
193
- end
185
+ add_call_backedges! (interp, rettype, edges, fullmatch, mts, atype, sv)
194
186
# print("=> ", rettype, "\n")
195
187
if rettype isa LimitedAccuracy
196
188
union! (sv. pclimitations, rettype. causes)
@@ -205,6 +197,27 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
205
197
return CallMeta (rettype, info)
206
198
end
207
199
200
+ function add_call_backedges! (interp:: AbstractInterpreter ,
201
+ @nospecialize (rettype),
202
+ edges:: Vector{MethodInstance} ,
203
+ fullmatch:: Vector{Bool} , mts:: Vector{Core.MethodTable} , @nospecialize (atype),
204
+ sv:: InferenceState )
205
+ if rettype === Any
206
+ # for `NativeInterpreter`, we don't add backedges when a new method couldn't refine
207
+ # (widen) this type
208
+ return
209
+ end
210
+ for edge in edges
211
+ add_backedge! (edge, sv)
212
+ end
213
+ for (thisfullmatch, mt) in zip (fullmatch, mts)
214
+ if ! thisfullmatch
215
+ # also need an edge to the method table in case something gets
216
+ # added that did not intersect with any existing method
217
+ add_mt_backedge! (mt, atype, sv)
218
+ end
219
+ end
220
+ end
208
221
209
222
function const_prop_profitable (@nospecialize (arg))
210
223
# have new information from argtypes that wasn't available from the signature
@@ -746,7 +759,7 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
746
759
call = abstract_call (interp, nothing , ct, sv, max_methods)
747
760
push! (retinfos, ApplyCallInfo (call. info, arginfo))
748
761
res = tmerge (res, call. rt)
749
- if res === Any
762
+ if bail_out_apply (interp, res, sv)
750
763
# No point carrying forward the info, we're not gonna inline it anyway
751
764
retinfo = nothing
752
765
break
@@ -1171,7 +1184,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
1171
1184
argtypes = Vector {Any} (undef, n)
1172
1185
@inbounds for i = 1 : n
1173
1186
ai = abstract_eval_value (interp, ea[i], vtypes, sv)
1174
- if ai === Bottom
1187
+ if bail_out_statement (interp, ai, sv)
1175
1188
return Bottom
1176
1189
end
1177
1190
argtypes[i] = ai
@@ -1349,6 +1362,8 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
1349
1362
condt = abstract_eval_value (interp, stmt. cond, s[pc], frame)
1350
1363
if condt === Bottom
1351
1364
empty! (frame. pclimitations)
1365
+ end
1366
+ if bail_out_local (interp, condt, frame)
1352
1367
break
1353
1368
end
1354
1369
condval = maybe_extract_const_bool (condt)
@@ -1440,7 +1455,9 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
1440
1455
else
1441
1456
if hd === :(= )
1442
1457
t = abstract_eval_statement (interp, stmt. args[2 ], changes, frame)
1443
- t === Bottom && break
1458
+ if bail_out_local (interp, t, frame)
1459
+ break
1460
+ end
1444
1461
frame. src. ssavaluetypes[pc] = t
1445
1462
lhs = stmt. args[1 ]
1446
1463
if isa (lhs, Slot)
@@ -1455,7 +1472,9 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
1455
1472
# these do not generate code
1456
1473
else
1457
1474
t = abstract_eval_statement (interp, stmt, changes, frame)
1458
- t === Bottom && break
1475
+ if bail_out_local (interp, t, frame)
1476
+ break
1477
+ end
1459
1478
if ! isempty (frame. ssavalue_uses[pc])
1460
1479
record_ssa_assign (pc, t, frame)
1461
1480
else
0 commit comments