@@ -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_backedge! (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,26 @@ 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_backedge! (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`, adding a new method couldn't refine (widen) this type
207
+ return
208
+ end
209
+ for edge in edges
210
+ add_backedge! (edge, sv)
211
+ end
212
+ for (thisfullmatch, mt) in zip (fullmatch, mts)
213
+ if ! thisfullmatch
214
+ # also need an edge to the method table in case something gets
215
+ # added that did not intersect with any existing method
216
+ add_mt_backedge! (mt, atype, sv)
217
+ end
218
+ end
219
+ end
208
220
209
221
function const_prop_profitable (@nospecialize (arg))
210
222
# have new information from argtypes that wasn't available from the signature
@@ -733,7 +745,7 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
733
745
call = abstract_call (interp, nothing , ct, sv, max_methods)
734
746
push! (retinfos, ApplyCallInfo (call. info, arginfo))
735
747
res = tmerge (res, call. rt)
736
- if res === Any
748
+ if bail_out_apply (interp, res, sv)
737
749
# No point carrying forward the info, we're not gonna inline it anyway
738
750
retinfo = nothing
739
751
break
@@ -1158,7 +1170,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
1158
1170
argtypes = Vector {Any} (undef, n)
1159
1171
@inbounds for i = 1 : n
1160
1172
ai = abstract_eval_value (interp, ea[i], vtypes, sv)
1161
- if ai === Bottom
1173
+ if bail_out_statement (interp, ai, sv)
1162
1174
return Bottom
1163
1175
end
1164
1176
argtypes[i] = ai
@@ -1334,7 +1346,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
1334
1346
pc´ = (stmt:: GotoNode ). label
1335
1347
elseif isa (stmt, GotoIfNot)
1336
1348
condt = abstract_eval_value (interp, stmt. cond, s[pc], frame)
1337
- if condt === Bottom
1349
+ if bail_out_local (interp, condt, frame)
1338
1350
empty! (frame. pclimitations)
1339
1351
break
1340
1352
end
@@ -1427,7 +1439,9 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
1427
1439
else
1428
1440
if hd === :(= )
1429
1441
t = abstract_eval_statement (interp, stmt. args[2 ], changes, frame)
1430
- t === Bottom && break
1442
+ if bail_out_local (interp, t, frame)
1443
+ break
1444
+ end
1431
1445
frame. src. ssavaluetypes[pc] = t
1432
1446
lhs = stmt. args[1 ]
1433
1447
if isa (lhs, Slot)
@@ -1442,7 +1456,9 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
1442
1456
# these do not generate code
1443
1457
else
1444
1458
t = abstract_eval_statement (interp, stmt, changes, frame)
1445
- t === Bottom && break
1459
+ if bail_out_local (interp, t, frame)
1460
+ break
1461
+ end
1446
1462
if ! isempty (frame. ssavalue_uses[pc])
1447
1463
record_ssa_assign (pc, t, frame)
1448
1464
else
0 commit comments