@@ -382,7 +382,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t
382
382
jl_method_instance_t *mi = codeinst->def ;
383
383
size_t nrealargs = jl_nparams (mi->specTypes ); // number of actual arguments being passed
384
384
bool is_opaque_closure = jl_is_method (mi->def .value ) && mi->def .method ->is_for_opaque_closure ;
385
- emit_specsig_to_fptr1 (proto.decl , proto.cc , proto.return_roots , mi->specTypes , codeinst->rettype , is_opaque_closure, nrealargs, params, pinvoke, 0 , 0 );
385
+ emit_specsig_to_fptr1 (proto.decl , proto.cc , proto.return_roots , mi->specTypes , codeinst->rettype , is_opaque_closure, nrealargs, params, pinvoke);
386
386
jl_gc_unsafe_leave (ct->ptls , gc_state);
387
387
preal_decl = " " ; // no need to fixup the name
388
388
}
@@ -713,7 +713,7 @@ static void jl_emit_codeinst_to_jit(
713
713
int waiting = jl_analyze_workqueue (codeinst, params);
714
714
if (waiting) {
715
715
auto release = std::move (params.tsctx_lock ); // unlock again before moving from it
716
- incompletemodules.insert ( std::pair ( codeinst, std::make_tuple ( std:: move (params), waiting)) );
716
+ incompletemodules.try_emplace ( codeinst, std::move (params), waiting);
717
717
}
718
718
else {
719
719
finish_params (result_m.getModuleUnlocked (), params);
@@ -760,7 +760,7 @@ static void _jl_compile_codeinst(
760
760
}
761
761
762
762
763
- const char *jl_generate_ccallable (LLVMOrcThreadSafeModuleRef llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms);
763
+ const char *jl_generate_ccallable (Module * llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms);
764
764
765
765
// compile a C-callable alias
766
766
extern " C" JL_DLLEXPORT_CODEGEN
@@ -774,45 +774,68 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
774
774
uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed (&jl_measure_compile_time_enabled);
775
775
if (measure_compile_time_enabled)
776
776
compiler_start_time = jl_hrtime ();
777
+ jl_codegen_params_t *pparams = (jl_codegen_params_t *)p;
778
+ DataLayout DL = pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout ();
779
+ Triple TargetTriple = pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple ();
777
780
orc::ThreadSafeContext ctx;
778
781
auto into = unwrap (llvmmod);
779
- jl_codegen_params_t *pparams = (jl_codegen_params_t *)p;
780
782
orc::ThreadSafeModule backing;
783
+ bool success = true ;
784
+ const char *name = " " ;
785
+ SmallVector<jl_code_instance_t *,0 > dependencies;
781
786
if (into == NULL ) {
782
- if (!pparams) {
783
- ctx = jl_ExecutionEngine->makeContext ();
784
- }
785
- backing = jl_create_ts_module (" cextern" , pparams ? pparams->tsctx : ctx, pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout (), pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple ());
787
+ ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext ();
788
+ backing = jl_create_ts_module (" cextern" , ctx, DL, TargetTriple);
786
789
into = &backing;
787
790
}
788
- bool success = true ;
789
- {
790
- auto Lock = into->getContext ().getLock ();
791
- Module *M = into->getModuleUnlocked ();
792
- jl_codegen_params_t params (into->getContext (), M->getDataLayout (), Triple (M->getTargetTriple ()));
793
- params.imaging_mode = imaging_default ();
791
+ { // params scope
792
+ jl_codegen_params_t params (into->getContext (), DL, TargetTriple);
794
793
if (pparams == NULL ) {
795
- M->getContext ().setDiscardValueNames (true );
794
+ params.cache = p == NULL ;
795
+ params.imaging_mode = imaging_default ();
796
+ params.tsctx .getContext ()->setDiscardValueNames (true );
796
797
pparams = ¶ms;
797
798
}
798
- assert (pparams-> tsctx . getContext () == into->getContext (). getContext () );
799
- const char *name = jl_generate_ccallable ( wrap (into), sysimg, declrt, sigt, *pparams );
800
- if (! sysimg) {
801
- jl_unique_gcsafe_lock lock (extern_c_lock);
802
- if (jl_ExecutionEngine-> getGlobalValueAddress (name)) {
803
- success = false ;
799
+ Module &M = * into->getModuleUnlocked ( );
800
+ assert (pparams-> tsctx . getContext () == &M. getContext () );
801
+ name = jl_generate_ccallable (&M, sysimg, declrt, sigt, *pparams);
802
+ if (!sysimg && !p) {
803
+ { // drop lock to keep analyzer happy (since it doesn't know we have the only reference to it)
804
+ auto release = std::move (params. tsctx_lock ) ;
804
805
}
805
- if (success && p == NULL ) {
806
- jl_jit_globals (params.global_targets );
807
- assert (params.workqueue .empty ());
808
- if (params._shared_module ) {
809
- jl_ExecutionEngine->optimizeDLSyms (*params._shared_module ); // safepoint
810
- jl_ExecutionEngine->addModule (orc::ThreadSafeModule (std::move (params._shared_module ), params.tsctx ));
806
+ { // lock scope
807
+ jl_unique_gcsafe_lock lock (extern_c_lock);
808
+ if (jl_ExecutionEngine->getGlobalValueAddress (name))
809
+ success = false ;
810
+ }
811
+ params.tsctx_lock = params.tsctx .getLock (); // re-acquire lock
812
+ if (success && params.cache ) {
813
+ for (auto &it : params.workqueue ) {
814
+ jl_code_instance_t *codeinst = it.first ;
815
+ JL_GC_PROMISE_ROOTED (codeinst);
816
+ dependencies.push_back (codeinst);
817
+ recursive_compile_graph (codeinst, nullptr );
811
818
}
819
+ jl_analyze_workqueue (nullptr , params, true );
820
+ assert (params.workqueue .empty ());
821
+ finish_params (&M, params);
812
822
}
813
- if (success && llvmmod == NULL ) {
814
- jl_ExecutionEngine->optimizeDLSyms (*M); // safepoint
815
- jl_ExecutionEngine->addModule (std::move (*into));
823
+ }
824
+ pparams = nullptr ;
825
+ }
826
+ if (!sysimg && success && llvmmod == NULL ) {
827
+ { // lock scope
828
+ jl_unique_gcsafe_lock lock (extern_c_lock);
829
+ if (!jl_ExecutionEngine->getGlobalValueAddress (name)) {
830
+ for (auto dep : dependencies)
831
+ jl_compile_codeinst_now (dep);
832
+ {
833
+ auto Lock = backing.getContext ().getLock ();
834
+ jl_ExecutionEngine->optimizeDLSyms (*backing.getModuleUnlocked ()); // safepoint
835
+ }
836
+ jl_ExecutionEngine->addModule (std::move (backing));
837
+ success = jl_ExecutionEngine->getGlobalValueAddress (name);
838
+ assert (success);
816
839
}
817
840
}
818
841
}
0 commit comments