@@ -1616,7 +1616,6 @@ class jl_codectx_t {
1616
1616
std::vector<std::tuple<jl_cgval_t , BasicBlock *, AllocaInst *, PHINode *, jl_value_t *>> PhiNodes;
1617
1617
std::vector<bool > ssavalue_assigned;
1618
1618
std::vector<int > ssavalue_usecount;
1619
- std::vector<orc::ThreadSafeModule> oc_modules;
1620
1619
jl_module_t *module = NULL ;
1621
1620
jl_typecache_t type_cache;
1622
1621
jl_tbaacache_t tbaa_cache;
@@ -4460,7 +4459,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const
4460
4459
// Check if we already queued this up
4461
4460
auto it = ctx.call_targets .find (codeinst);
4462
4461
if (need_to_emit && it != ctx.call_targets .end ()) {
4463
- protoname = std::get< 2 >( it->second ) ->getName ();
4462
+ protoname = it->second . decl ->getName ();
4464
4463
need_to_emit = cache_valid = false ;
4465
4464
}
4466
4465
@@ -4504,7 +4503,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const
4504
4503
handled = true ;
4505
4504
if (need_to_emit) {
4506
4505
Function *trampoline_decl = cast<Function>(jl_Module->getNamedValue (protoname));
4507
- ctx.call_targets [codeinst] = std::make_tuple ( cc, return_roots, trampoline_decl, specsig) ;
4506
+ ctx.call_targets [codeinst] = { cc, return_roots, trampoline_decl, specsig} ;
4508
4507
}
4509
4508
}
4510
4509
}
@@ -5369,8 +5368,7 @@ static std::pair<Function*, Function*> get_oc_function(jl_codectx_t &ctx, jl_met
5369
5368
{
5370
5369
jl_svec_t *sig_args = NULL ;
5371
5370
jl_value_t *sigtype = NULL ;
5372
- jl_code_info_t *ir = NULL ;
5373
- JL_GC_PUSH3 (&sig_args, &sigtype, &ir);
5371
+ JL_GC_PUSH2 (&sig_args, &sigtype);
5374
5372
5375
5373
size_t nsig = 1 + jl_svec_len (argt_typ->parameters );
5376
5374
sig_args = jl_alloc_svec_uninit (nsig);
@@ -5392,16 +5390,25 @@ static std::pair<Function*, Function*> get_oc_function(jl_codectx_t &ctx, jl_met
5392
5390
JL_GC_POP ();
5393
5391
return std::make_pair ((Function*)NULL , (Function*)NULL );
5394
5392
}
5395
- ++EmittedOpaqueClosureFunctions;
5396
5393
5397
- ir = jl_uncompress_ir (closure_method, ci, ( jl_value_t *)inferred );
5394
+ auto it = ctx. emission_context . compiled_functions . find (ci );
5398
5395
5399
- // TODO: Emit this inline and outline it late using LLVM's coroutine support.
5400
- orc::ThreadSafeModule closure_m = jl_create_ts_module (
5401
- name_from_method_instance (mi), ctx.emission_context .tsctx ,
5402
- ctx.emission_context .imaging ,
5403
- jl_Module->getDataLayout (), Triple (jl_Module->getTargetTriple ()));
5404
- jl_llvm_functions_t closure_decls = emit_function (closure_m, mi, ir, rettype, ctx.emission_context );
5396
+ if (it == ctx.emission_context .compiled_functions .end ()) {
5397
+ ++EmittedOpaqueClosureFunctions;
5398
+ jl_code_info_t *ir = jl_uncompress_ir (closure_method, ci, (jl_value_t *)inferred);
5399
+ JL_GC_PUSH1 (&ir);
5400
+ // TODO: Emit this inline and outline it late using LLVM's coroutine support.
5401
+ orc::ThreadSafeModule closure_m = jl_create_ts_module (
5402
+ name_from_method_instance (mi), ctx.emission_context .tsctx ,
5403
+ ctx.emission_context .imaging ,
5404
+ jl_Module->getDataLayout (), Triple (jl_Module->getTargetTriple ()));
5405
+ jl_llvm_functions_t closure_decls = emit_function (closure_m, mi, ir, rettype, ctx.emission_context );
5406
+ JL_GC_POP ();
5407
+ it = ctx.emission_context .compiled_functions .insert (std::make_pair (ci, std::make_pair (std::move (closure_m), std::move (closure_decls)))).first ;
5408
+ }
5409
+
5410
+ auto &closure_m = it->second .first ;
5411
+ auto &closure_decls = it->second .second ;
5405
5412
5406
5413
assert (closure_decls.functionObject != " jl_fptr_sparam" );
5407
5414
bool isspecsig = closure_decls.functionObject != " jl_fptr_args" ;
@@ -5432,7 +5439,6 @@ static std::pair<Function*, Function*> get_oc_function(jl_codectx_t &ctx, jl_met
5432
5439
specF = cast<Function>(returninfo.decl .getCallee ());
5433
5440
}
5434
5441
}
5435
- ctx.oc_modules .push_back (std::move (closure_m));
5436
5442
JL_GC_POP ();
5437
5443
return std::make_pair (F, specF);
5438
5444
}
@@ -5715,7 +5721,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
5715
5721
if (jl_is_concrete_type (env_t )) {
5716
5722
jl_tupletype_t *argt_typ = (jl_tupletype_t *)argt.constant ;
5717
5723
Function *F, *specF;
5718
- std::tie (F, specF) = get_oc_function (ctx, (jl_method_t *)source.constant , (jl_datatype_t *)env_t , argt_typ, ub.constant );
5724
+ std::tie (F, specF) = get_oc_function (ctx, (jl_method_t *)source.constant , (jl_tupletype_t *)env_t , argt_typ, ub.constant );
5719
5725
if (F) {
5720
5726
jl_cgval_t jlcall_ptr = mark_julia_type (ctx, F, false , jl_voidpointer_type);
5721
5727
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA (ctx, ctx.tbaa ().tbaa_gcframe );
@@ -5725,7 +5731,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_
5725
5731
if (specF)
5726
5732
fptr = mark_julia_type (ctx, specF, false , jl_voidpointer_type);
5727
5733
else
5728
- fptr = mark_julia_type (ctx, (llvm::Value*) Constant::getNullValue (ctx.types ().T_size ), false , jl_voidpointer_type);
5734
+ fptr = mark_julia_type (ctx, Constant::getNullValue (ctx.types ().T_size ), false , jl_voidpointer_type);
5729
5735
5730
5736
// TODO: Inline the env at the end of the opaque closure and generate a descriptor for GC
5731
5737
jl_cgval_t env = emit_new_struct (ctx, env_t , nargs-4 , &argv.data ()[4 ]);
@@ -8757,19 +8763,6 @@ static jl_llvm_functions_t
8757
8763
jl_Module->getFunction (FN)->setLinkage (GlobalVariable::InternalLinkage);
8758
8764
}
8759
8765
8760
- // link in opaque closure modules
8761
- for (auto &TSMod : ctx.oc_modules ) {
8762
- SmallVector<std::string, 1 > Exports;
8763
- TSMod.withModuleDo ([&](Module &Mod) {
8764
- for (const auto &F: Mod.functions ())
8765
- if (!F.isDeclaration ())
8766
- Exports.push_back (F.getName ().str ());
8767
- });
8768
- jl_merge_module (TSM, std::move (TSMod));
8769
- for (auto FN: Exports)
8770
- jl_Module->getFunction (FN)->setLinkage (GlobalVariable::InternalLinkage);
8771
- }
8772
-
8773
8766
JL_GC_POP ();
8774
8767
return declarations;
8775
8768
}
@@ -8931,22 +8924,18 @@ jl_llvm_functions_t jl_emit_codeinst(
8931
8924
8932
8925
8933
8926
void jl_compile_workqueue (
8934
- jl_workqueue_t &emitted ,
8927
+ jl_codegen_params_t ¶ms ,
8935
8928
Module &original,
8936
- jl_codegen_params_t ¶ms, CompilationPolicy policy)
8929
+ CompilationPolicy policy)
8937
8930
{
8938
8931
JL_TIMING (CODEGEN, CODEGEN_Workqueue);
8939
8932
jl_code_info_t *src = NULL ;
8940
8933
JL_GC_PUSH1 (&src);
8941
8934
while (!params.workqueue .empty ()) {
8942
8935
jl_code_instance_t *codeinst;
8943
- Function *protodecl;
8944
- jl_returninfo_t ::CallingConv proto_cc;
8945
- bool proto_specsig;
8946
- unsigned proto_return_roots;
8947
8936
auto it = params.workqueue .back ();
8948
8937
codeinst = it.first ;
8949
- std::tie (proto_cc, proto_return_roots, protodecl, proto_specsig) = it.second ;
8938
+ auto proto = it.second ;
8950
8939
params.workqueue .pop_back ();
8951
8940
// try to emit code for this item from the workqueue
8952
8941
assert (codeinst->min_world <= params.world && codeinst->max_world >= params.world &&
@@ -8974,12 +8963,8 @@ void jl_compile_workqueue(
8974
8963
}
8975
8964
}
8976
8965
else {
8977
- auto &result = emitted[codeinst];
8978
- jl_llvm_functions_t *decls = NULL ;
8979
- if (std::get<0 >(result)) {
8980
- decls = &std::get<1 >(result);
8981
- }
8982
- else {
8966
+ auto it = params.compiled_functions .find (codeinst);
8967
+ if (it == params.compiled_functions .end ()) {
8983
8968
// Reinfer the function. The JIT came along and removed the inferred
8984
8969
// method body. See #34993
8985
8970
if (policy != CompilationPolicy::Default &&
@@ -8990,47 +8975,46 @@ void jl_compile_workqueue(
8990
8975
jl_create_ts_module (name_from_method_instance (codeinst->def ),
8991
8976
params.tsctx , params.imaging ,
8992
8977
original.getDataLayout (), Triple (original.getTargetTriple ()));
8993
- result.second = jl_emit_code (result_m, codeinst->def , src, src->rettype , params);
8994
- result.first = std::move (result_m);
8978
+ auto decls = jl_emit_code (result_m, codeinst->def , src, src->rettype , params);
8979
+ if (result_m)
8980
+ it = params.compiled_functions .insert (std::make_pair (codeinst, std::make_pair (std::move (result_m), std::move (decls)))).first ;
8995
8981
}
8996
8982
}
8997
8983
else {
8998
8984
orc::ThreadSafeModule result_m =
8999
8985
jl_create_ts_module (name_from_method_instance (codeinst->def ),
9000
8986
params.tsctx , params.imaging ,
9001
8987
original.getDataLayout (), Triple (original.getTargetTriple ()));
9002
- result.second = jl_emit_codeinst (result_m, codeinst, NULL , params);
9003
- result.first = std::move (result_m);
8988
+ auto decls = jl_emit_codeinst (result_m, codeinst, NULL , params);
8989
+ if (result_m)
8990
+ it = params.compiled_functions .insert (std::make_pair (codeinst, std::make_pair (std::move (result_m), std::move (decls)))).first ;
9004
8991
}
9005
- if (std::get<0 >(result))
9006
- decls = &std::get<1 >(result);
9007
- else
9008
- emitted.erase (codeinst); // undo the insert above
9009
8992
}
9010
- if (decls) {
9011
- if (decls->functionObject == " jl_fptr_args" ) {
9012
- preal_decl = decls->specFunctionObject ;
8993
+ if (it != params.compiled_functions .end ()) {
8994
+ auto &decls = it->second .second ;
8995
+ if (decls.functionObject == " jl_fptr_args" ) {
8996
+ preal_decl = decls.specFunctionObject ;
9013
8997
}
9014
- else if (decls-> functionObject != " jl_fptr_sparam" ) {
9015
- preal_decl = decls-> specFunctionObject ;
8998
+ else if (decls. functionObject != " jl_fptr_sparam" ) {
8999
+ preal_decl = decls. specFunctionObject ;
9016
9000
preal_specsig = true ;
9017
9001
}
9018
9002
}
9019
9003
}
9020
9004
// patch up the prototype we emitted earlier
9021
- Module *mod = protodecl ->getParent ();
9022
- assert (protodecl ->isDeclaration ());
9023
- if (proto_specsig ) {
9005
+ Module *mod = proto. decl ->getParent ();
9006
+ assert (proto. decl ->isDeclaration ());
9007
+ if (proto. specsig ) {
9024
9008
// expected specsig
9025
9009
if (!preal_specsig) {
9026
9010
// emit specsig-to-(jl)invoke conversion
9027
9011
Function *preal = emit_tojlinvoke (codeinst, mod, params);
9028
- protodecl ->setLinkage (GlobalVariable::InternalLinkage);
9012
+ proto. decl ->setLinkage (GlobalVariable::InternalLinkage);
9029
9013
// protodecl->setAlwaysInline();
9030
- jl_init_function (protodecl , params.TargetTriple );
9014
+ jl_init_function (proto. decl , params.TargetTriple );
9031
9015
size_t nrealargs = jl_nparams (codeinst->def ->specTypes ); // number of actual arguments being passed
9032
9016
// TODO: maybe this can be cached in codeinst->specfptr?
9033
- emit_cfunc_invalidate (protodecl, proto_cc, proto_return_roots , codeinst->def ->specTypes , codeinst->rettype , false , nrealargs, params, preal);
9017
+ emit_cfunc_invalidate (proto. decl , proto. cc , proto. return_roots , codeinst->def ->specTypes , codeinst->rettype , false , nrealargs, params, preal);
9034
9018
preal_decl = " " ; // no need to fixup the name
9035
9019
}
9036
9020
else {
@@ -9047,11 +9031,11 @@ void jl_compile_workqueue(
9047
9031
if (!preal_decl.empty ()) {
9048
9032
// merge and/or rename this prototype to the real function
9049
9033
if (Value *specfun = mod->getNamedValue (preal_decl)) {
9050
- if (protodecl != specfun)
9051
- protodecl ->replaceAllUsesWith (specfun);
9034
+ if (proto. decl != specfun)
9035
+ proto. decl ->replaceAllUsesWith (specfun);
9052
9036
}
9053
9037
else {
9054
- protodecl ->setName (preal_decl);
9038
+ proto. decl ->setName (preal_decl);
9055
9039
}
9056
9040
}
9057
9041
}
0 commit comments