@@ -1255,8 +1255,29 @@ function typeinf_type(interp::AbstractInterpreter, mi::MethodInstance)
12551255 return ci. rettype
12561256end
12571257
1258+ # Resolve a call, as described by `argtype` to a single matching
1259+ # Method and return a compilable MethodInstance for the call, if
1260+ # it will be runtime-dispatched to exactly that MethodInstance
1261+ function compileable_specialization_for_call (interp:: AbstractInterpreter , @nospecialize (argtype))
1262+ matches = findall (argtype, method_table (interp); limit = 1 )
1263+ matches === nothing && return nothing
1264+ length (matches. matches) == 0 && return nothing
1265+ match = only (matches. matches)
1266+
1267+ compileable_atype = get_compileable_sig (match. method, match. spec_types, match. sparams)
1268+ compileable_atype === nothing && return nothing
1269+ if match. spec_types != = compileable_atype
1270+ sp_ = ccall (:jl_type_intersection_with_env , Any, (Any, Any), compileable_atype, method. sig):: SimpleVector
1271+ sparams = sp_[2 ]:: SimpleVector
1272+ mi = specialize_method (match. method, compileable_atype, sparams)
1273+ else
1274+ mi = specialize_method (match. method, compileable_atype, match. sparams)
1275+ end
1276+ return mi
1277+ end
1278+
12581279# collect a list of all code that is needed along with CodeInstance to codegen it fully
1259- function collectinvokes! (wq:: Vector{CodeInstance} , ci:: CodeInfo )
1280+ function collectinvokes! (wq:: Vector{CodeInstance} , ci:: CodeInfo , sptypes :: Vector{VarState} )
12601281 src = ci. code
12611282 for i = 1 : length (src)
12621283 stmt = src[i]
@@ -1265,6 +1286,31 @@ function collectinvokes!(wq::Vector{CodeInstance}, ci::CodeInfo)
12651286 edge = stmt. args[1 ]
12661287 edge isa CodeInstance && isdefined (edge, :inferred ) && push! (wq, edge)
12671288 end
1289+
1290+ if isexpr (stmt, :call )
1291+ farg = stmt. args[1 ]
1292+ ! applicable (argextype, farg, ci, sptypes) && continue # TODO : Why is this failing during bootstrap
1293+ ftyp = widenconst (argextype (farg, ci, sptypes))
1294+ if ftyp <: Builtin
1295+ # TODO : Make interp elsewhere
1296+ interp = NativeInterpreter (Base. get_world_counter ())
1297+ if Core. finalizer isa ftyp && length (stmt. args) == 3
1298+ finalizer = argextype (stmt. args[2 ], ci, sptypes)
1299+ obj = argextype (stmt. args[3 ], ci, sptypes)
1300+ atype = argtypes_to_type (Any[finalizer, obj])
1301+
1302+ mi = compileable_specialization_for_call (interp, atype)
1303+ mi === nothing && continue
1304+
1305+ if mi. def. primary_world <= Base. get_world_counter () <= mi. def. deleted_world
1306+ ci = typeinf_ext (interp, mi, SOURCE_MODE_GET_SOURCE)
1307+ # TODO : separate workqueue for NativeInterpreter
1308+ ci isa CodeInstance && push! (wq, ci)
1309+ end
1310+ # push!(wq, mi)
1311+ end
1312+ end
1313+ end
12681314 # TODO : handle other StmtInfo like @cfunction and OpaqueClosure?
12691315 end
12701316end
@@ -1301,8 +1347,9 @@ function add_codeinsts_to_jit!(interp::AbstractInterpreter, ci, source_mode::UIn
13011347 end
13021348 end
13031349 push! (inspected, callee)
1304- collectinvokes! (tocompile, src)
13051350 mi = get_ci_mi (callee)
1351+ sptypes = sptypes_from_meth_instance (mi)
1352+ collectinvokes! (tocompile, src, sptypes)
13061353 if iszero (ccall (:jl_mi_cache_has_ci , Cint, (Any, Any), mi, callee))
13071354 cached = ccall (:jl_get_ci_equiv , Any, (Any, UInt), callee, get_inference_world (interp)):: CodeInstance
13081355 if cached === callee
@@ -1400,7 +1447,8 @@ function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim_m
14001447 end
14011448 push! (inspected, callee)
14021449 if src isa CodeInfo
1403- collectinvokes! (tocompile, src)
1450+ sptypes = sptypes_from_meth_instance (mi)
1451+ collectinvokes! (tocompile, src, sptypes)
14041452 # try to reuse an existing CodeInstance from before to avoid making duplicates in the cache
14051453 if iszero (ccall (:jl_mi_cache_has_ci , Cint, (Any, Any), mi, callee))
14061454 cached = ccall (:jl_get_ci_equiv , Any, (Any, UInt), callee, this_world):: CodeInstance
0 commit comments