@@ -480,8 +480,32 @@ end # HAS_INTEGRATED_CACHE
480480# # codegen/inference integration
481481
482482function ci_cache_populate (interp, cache, mi, min_world, max_world)
483- if VERSION >= v " 1.12.0-DEV.15"
484- inferred_ci = CC. typeinf_ext_toplevel (interp, mi, CC. SOURCE_MODE_FORCE_SOURCE) # or SOURCE_MODE_FORCE_SOURCE_UNCACHED?
483+ codeinfos = Pair{CodeInstance, CodeInfo}[]
484+ @static if VERSION >= v " 1.12.0-DEV.1434"
485+ # see typeinfer.jl: typeinf_ext_toplevel
486+ ci = CC. typeinf_ext (interp, mi, CC. SOURCE_MODE_NOT_REQUIRED)
487+ inspected = IdSet {CodeInstance} ()
488+ tocompile = CodeInstance[ci]
489+ while ! isempty (tocompile)
490+ callee = pop! (tocompile)
491+ callee in inspected && continue
492+ push! (inspected, callee)
493+ # now make sure everything has source code, if desired
494+ mi = CC. get_ci_mi (callee)
495+ def = mi. def
496+ if CC. use_const_api (callee)
497+ src = CC. codeinfo_for_const (interp, mi, ci. rettype_const)
498+ else
499+ # TODO : typeinf_code could return something with different edges/ages/owner/abi (needing an update to callee), which we don't handle here
500+ src = CC. typeinf_code (interp, mi, true )
501+ end
502+ if src isa CodeInfo
503+ CC. collectinvokes! (tocompile, src)
504+ push! (codeinfos, callee => src)
505+ end
506+ end
507+ elseif VERSION >= v " 1.12.0-DEV.15"
508+ inferred_ci = CC. typeinf_ext_toplevel (interp, mi, CC. SOURCE_MODE_FORCE_SOURCE)
485509 @assert inferred_ci != = nothing " Inference of $mi failed"
486510
487511 # inference should have populated our cache
@@ -512,13 +536,13 @@ function ci_cache_populate(interp, cache, mi, min_world, max_world)
512536 end
513537 end
514538
515- return ci :: CodeInstance
539+ return codeinfos
516540end
517541
518542function ci_cache_lookup (cache, mi, min_world, max_world)
519543 wvc = WorldView (cache, min_world, max_world)
520544 ci = CC. get (wvc, mi, nothing )
521- if ci != = nothing && ci. inferred === nothing
545+ if VERSION < v " 1.12.0-DEV.1434 " && ci != = nothing && ci. inferred === nothing
522546 # if for some reason we did end up with a codeinfo without inferred source, e.g.,
523547 # because of calling `Base.return_types` which only sets rettyp, pretend we didn't
524548 # run inference so that we re-infer now and not during codegen (which is disallowed)
543567 CompilationPolicyExtern = 1
544568end
545569
546- # HACK: in older versions of Julia, `jl_create_native` doesn't take a world argument
547- # but instead always generates code for the current world. note that this doesn't
548- # actually change the world age, but just spoofs the counter `jl_create_native` reads.
549- # XXX : Base.get_world_counter is supposed to be monotonically increasing and is runtime global.
550- macro in_world (world, ex)
551- quote
552- actual_world = Base. get_world_counter ()
553- world_counter = cglobal (:jl_world_counter , Csize_t)
554- unsafe_store! (world_counter, $ (esc (world)))
555- try
556- $ (esc (ex))
557- finally
558- unsafe_store! (world_counter, actual_world)
559- end
560- end
561- end
562-
563570"""
564571 precompile(job::CompilerJob)
565572
@@ -574,10 +581,7 @@ function Base.precompile(@nospecialize(job::CompilerJob))
574581 # populate the cache
575582 interp = get_interpreter (job)
576583 cache = CC. code_cache (interp)
577- if ci_cache_lookup (cache, job. source, job. world, job. world) === nothing
578- ci_cache_populate (interp, cache, job. source, job. world, job. world)
579- return ci_cache_lookup (cache, job. source, job. world, job. world) != = nothing
580- end
584+ ci_cache_populate (interp, cache, job. source, job. world, job. world)
581585 return true
582586end
583587
@@ -589,10 +593,7 @@ function compile_method_instance(@nospecialize(job::CompilerJob))
589593 # populate the cache
590594 interp = get_interpreter (job)
591595 cache = CC. code_cache (interp)
592- if ci_cache_lookup (cache, job. source, job. world, job. world) === nothing
593- ci_cache_populate (interp, cache, job. source, job. world, job. world)
594- @assert ci_cache_lookup (cache, job. source, job. world, job. world) != = nothing
595- end
596+ populated = ci_cache_populate (interp, cache, job. source, job. world, job. world)
596597
597598 # create a callback to look-up function in our cache,
598599 # and keep track of the method instances we needed.
@@ -639,7 +640,16 @@ function compile_method_instance(@nospecialize(job::CompilerJob))
639640 Metadata (ConstantInt (DEBUG_METADATA_VERSION ()))
640641 end
641642
642- native_code = if VERSION >= v " 1.12.0-DEV.1667"
643+ native_code = if VERSION >= v " 1.12.0-DEV.1823"
644+ codeinfos = Any[]
645+ for (ci, src) in populated
646+ # each item in the list should be a CodeInstance followed by a CodeInfo
647+ # indicating something to compile
648+ push! (codeinfos, ci:: CodeInstance )
649+ push! (codeinfos, src:: CodeInfo )
650+ end
651+ @ccall jl_emit_native (codeinfos:: Vector{Any} , ts_mod:: LLVM.API.LLVMOrcThreadSafeModuleRef , Ref (params):: Ptr{Base.CodegenParams} , #= extern linkage=# false :: Cint ):: Ptr{Cvoid}
652+ elseif VERSION >= v " 1.12.0-DEV.1667"
643653 ccall (:jl_create_native , Ptr{Cvoid},
644654 (Vector{MethodInstance}, LLVM. API. LLVMOrcThreadSafeModuleRef, Ptr{Base. CodegenParams}, Cint, Cint, Cint, Csize_t, Ptr{Cvoid}),
645655 [job. source], ts_mod, Ref (params), CompilationPolicyExtern, #= imaging mode=# 0 , #= external linkage=# 0 , job. world, Base. unsafe_convert (Ptr{Nothing}, lookup_cb))
0 commit comments