@@ -1243,8 +1243,29 @@ function typeinf_type(interp::AbstractInterpreter, mi::MethodInstance)
1243
1243
return ci. rettype
1244
1244
end
1245
1245
1246
+ # Resolve a call, as described by `argtype` to a single matching
1247
+ # Method and return a compilable MethodInstance for the call, if
1248
+ # it will be runtime-dispatched to exactly that MethodInstance
1249
+ function compileable_specialization_for_call (interp:: AbstractInterpreter , @nospecialize (argtype))
1250
+ matches = findall (argtype, method_table (interp); limit = 1 )
1251
+ matches === nothing && return nothing
1252
+ length (matches. matches) == 0 && return nothing
1253
+ match = only (matches. matches)
1254
+
1255
+ compileable_atype = get_compileable_sig (match. method, match. spec_types, match. sparams)
1256
+ compileable_atype === nothing && return nothing
1257
+ if match. spec_types != = compileable_atype
1258
+ sp_ = ccall (:jl_type_intersection_with_env , Any, (Any, Any), compileable_atype, method. sig):: SimpleVector
1259
+ sparams = sp_[2 ]:: SimpleVector
1260
+ mi = specialize_method (match. method, compileable_atype, sparams)
1261
+ else
1262
+ mi = specialize_method (match. method, compileable_atype, match. sparams)
1263
+ end
1264
+ return mi
1265
+ end
1266
+
1246
1267
# collect a list of all code that is needed along with CodeInstance to codegen it fully
1247
- function collectinvokes! (wq:: Vector{CodeInstance} , ci:: CodeInfo )
1268
+ function collectinvokes! (wq:: Vector{CodeInstance} , ci:: CodeInfo , sptypes :: Vector{VarState} , seen :: Union{Nothing,IdSet{MethodInstance}} )
1248
1269
src = ci. code
1249
1270
for i = 1 : length (src)
1250
1271
stmt = src[i]
@@ -1253,6 +1274,34 @@ function collectinvokes!(wq::Vector{CodeInstance}, ci::CodeInfo)
1253
1274
edge = stmt. args[1 ]
1254
1275
edge isa CodeInstance && isdefined (edge, :inferred ) && push! (wq, edge)
1255
1276
end
1277
+
1278
+ if isexpr (stmt, :call ) && seen != = nothing
1279
+ farg = stmt. args[1 ]
1280
+ ! applicable (argextype, farg, ci, sptypes) && continue # TODO : Why is this failing during bootstrap
1281
+ ftyp = widenconst (argextype (farg, ci, sptypes))
1282
+ if ftyp <: Builtin
1283
+ # TODO : Make interp elsewhere
1284
+ interp = NativeInterpreter (Base. get_world_counter ())
1285
+ if Core. finalizer isa ftyp && length (stmt. args) == 3
1286
+ finalizer = argextype (stmt. args[2 ], ci, sptypes)
1287
+ obj = argextype (stmt. args[3 ], ci, sptypes)
1288
+ atype = argtypes_to_type (Any[finalizer, obj])
1289
+
1290
+ mi = compileable_specialization_for_call (interp, atype)
1291
+ mi === nothing && continue
1292
+
1293
+ mi in seen && continue
1294
+ push! (seen, mi)
1295
+
1296
+ if mi. def. primary_world <= Base. get_world_counter () <= mi. def. deleted_world
1297
+ ci = typeinf_ext (interp, mi, SOURCE_MODE_NOT_REQUIRED)
1298
+ # TODO : separate workqueue for NativeInterpreter
1299
+ ci isa CodeInstance && push! (wq, ci)
1300
+ end
1301
+ # push!(wq, mi)
1302
+ end
1303
+ end
1304
+ end
1256
1305
# TODO : handle other StmtInfo like @cfunction and OpaqueClosure?
1257
1306
end
1258
1307
end
@@ -1289,7 +1338,10 @@ function add_codeinsts_to_jit!(interp::AbstractInterpreter, ci, source_mode::UIn
1289
1338
end
1290
1339
end
1291
1340
push! (inspected, callee)
1292
- collectinvokes! (tocompile, src)
1341
+ mi = get_ci_mi (callee)
1342
+ sptypes = sptypes_from_meth_instance (mi)
1343
+ collectinvokes! (tocompile, src, sptypes, nothing )
1344
+ # collectinvokes!(tocompile, src)
1293
1345
mi = get_ci_mi (callee)
1294
1346
if iszero (ccall (:jl_mi_cache_has_ci , Cint, (Any, Any), mi, callee))
1295
1347
cached = ccall (:jl_get_ci_equiv , Any, (Any, UInt), callee, get_inference_world (interp)):: CodeInstance
@@ -1328,6 +1380,7 @@ const TRIM_UNSAFE_WARN = 3
1328
1380
function typeinf_ext_toplevel (methods:: Vector{Any} , worlds:: Vector{UInt} , trim_mode:: Int )
1329
1381
inspected = IdSet {CodeInstance} ()
1330
1382
tocompile = Vector {CodeInstance} ()
1383
+ inspected_mis = IdSet {MethodInstance} ()
1331
1384
codeinfos = []
1332
1385
# first compute the ABIs of everything
1333
1386
latest = true # whether this_world == world_counter()
@@ -1389,7 +1442,8 @@ function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim_m
1389
1442
end
1390
1443
push! (inspected, callee)
1391
1444
if src isa CodeInfo
1392
- collectinvokes! (tocompile, src)
1445
+ sptypes = sptypes_from_meth_instance (mi)
1446
+ collectinvokes! (tocompile, src, sptypes, inspected_mis)
1393
1447
# try to reuse an existing CodeInstance from before to avoid making duplicates in the cache
1394
1448
if iszero (ccall (:jl_mi_cache_has_ci , Cint, (Any, Any), mi, callee))
1395
1449
cached = ccall (:jl_get_ci_equiv , Any, (Any, UInt), callee, this_world):: CodeInstance
0 commit comments