@@ -382,7 +382,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t
382382 jl_method_instance_t *mi = codeinst->def ;
383383 size_t nrealargs = jl_nparams (mi->specTypes ); // number of actual arguments being passed
384384 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);
386386 jl_gc_unsafe_leave (ct->ptls , gc_state);
387387 preal_decl = " " ; // no need to fixup the name
388388 }
@@ -713,7 +713,7 @@ static void jl_emit_codeinst_to_jit(
713713 int waiting = jl_analyze_workqueue (codeinst, params);
714714 if (waiting) {
715715 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);
717717 }
718718 else {
719719 finish_params (result_m.getModuleUnlocked (), params);
@@ -760,7 +760,7 @@ static void _jl_compile_codeinst(
760760}
761761
762762
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);
764764
765765// compile a C-callable alias
766766extern " C" JL_DLLEXPORT_CODEGEN
@@ -774,45 +774,68 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
774774 uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed (&jl_measure_compile_time_enabled);
775775 if (measure_compile_time_enabled)
776776 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 ();
777780 orc::ThreadSafeContext ctx;
778781 auto into = unwrap (llvmmod);
779- jl_codegen_params_t *pparams = (jl_codegen_params_t *)p;
780782 orc::ThreadSafeModule backing;
783+ bool success = true ;
784+ const char *name = " " ;
785+ SmallVector<jl_code_instance_t *,0 > dependencies;
781786 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);
786789 into = &backing;
787790 }
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);
794793 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 );
796797 pparams = ¶ms;
797798 }
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 ) ;
804805 }
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 );
811818 }
819+ jl_analyze_workqueue (nullptr , params, true );
820+ assert (params.workqueue .empty ());
821+ finish_params (&M, params);
812822 }
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);
816839 }
817840 }
818841 }
0 commit comments