Skip to content

Commit 4422a1d

Browse files
Migrate codegen to operate on orc::ThreadSafeModule (#44440)
* Move to TSModule, round 2 * Pass in modules to codegen * Rename jl_create_datalayout * Get unlocked modules once * Pass along module data layout and target more frequently * Remove jl_get_ee_context * Add note about context locks
1 parent 48ae154 commit 4422a1d

File tree

12 files changed

+325
-273
lines changed

12 files changed

+325
-273
lines changed

doc/src/devdocs/locks.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ The following is a level 4 lock, which can only recurse to acquire level 1, 2, o
4747
4848
No Julia code may be called while holding a lock above this point.
4949

50+
orc::ThreadSafeContext locks occupy a special spot in the locking diagram. They are used to protect
51+
LLVM's global non-threadsafe state, but there may be an arbitrary number of them. For now, there is
52+
only one global context, and thus acquiring it is a level 5 lock. However, acquiring such a lock
53+
should only be done at the same time that the codegen lock is acquired.
54+
5055
The following are a level 6 lock, which can only recurse to acquire locks at lower levels:
5156

5257
> * codegen

src/aotcompile.cpp

Lines changed: 64 additions & 61 deletions
Large diffs are not rendered by default.

src/ccall.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,40 @@ GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M)
1111
// Find or create the GVs for the library and symbol lookup.
1212
// Return `runtime_lib` (whether the library name is a string)
1313
// The `lib` and `sym` GV returned may not be in the current module.
14-
static bool runtime_sym_gvs(jl_codegen_params_t &emission_context, LLVMContext &ctxt, const char *f_lib, const char *f_name,
14+
static bool runtime_sym_gvs(jl_codectx_t &ctx, const char *f_lib, const char *f_name,
1515
GlobalVariable *&lib, GlobalVariable *&sym)
1616
{
17-
Module *M = emission_context.shared_module(ctxt);
17+
auto &TSM = ctx.emission_context.shared_module(*jl_Module);
18+
//Safe b/c emission context holds context lock
19+
auto M = TSM.getModuleUnlocked();
1820
bool runtime_lib = false;
1921
GlobalVariable *libptrgv;
2022
jl_codegen_params_t::SymMapGV *symMap;
2123
#ifdef _OS_WINDOWS_
2224
if ((intptr_t)f_lib == (intptr_t)JL_EXE_LIBNAME) {
2325
libptrgv = prepare_global_in(M, jlexe_var);
24-
symMap = &emission_context.symMapExe;
26+
symMap = &ctx.emission_context.symMapExe;
2527
}
2628
else if ((intptr_t)f_lib == (intptr_t)JL_LIBJULIA_INTERNAL_DL_LIBNAME) {
2729
libptrgv = prepare_global_in(M, jldlli_var);
28-
symMap = &emission_context.symMapDlli;
30+
symMap = &ctx.emission_context.symMapDlli;
2931
}
3032
else if ((intptr_t)f_lib == (intptr_t)JL_LIBJULIA_DL_LIBNAME) {
3133
libptrgv = prepare_global_in(M, jldll_var);
32-
symMap = &emission_context.symMapDll;
34+
symMap = &ctx.emission_context.symMapDll;
3335
}
3436
else
3537
#endif
3638
if (f_lib == NULL) {
3739
libptrgv = jl_emit_RTLD_DEFAULT_var(M);
38-
symMap = &emission_context.symMapDefault;
40+
symMap = &ctx.emission_context.symMapDefault;
3941
}
4042
else {
4143
std::string name = "ccalllib_";
4244
name += llvm::sys::path::filename(f_lib);
4345
name += std::to_string(globalUniqueGeneratedNames++);
4446
runtime_lib = true;
45-
auto &libgv = emission_context.libMapGV[f_lib];
47+
auto &libgv = ctx.emission_context.libMapGV[f_lib];
4648
if (libgv.first == NULL) {
4749
libptrgv = new GlobalVariable(*M, getInt8PtrTy(M->getContext()), false,
4850
GlobalVariable::ExternalLinkage,
@@ -175,7 +177,7 @@ static Value *runtime_sym_lookup(
175177
Constant::getNullValue(T_pvoidfunc), gvname);
176178
}
177179
else {
178-
runtime_lib = runtime_sym_gvs(ctx.emission_context, ctx.builder.getContext(), f_lib, f_name, libptrgv, llvmgv);
180+
runtime_lib = runtime_sym_gvs(ctx, f_lib, f_name, libptrgv, llvmgv);
179181
libptrgv = prepare_global_in(jl_Module, libptrgv);
180182
}
181183
llvmgv = prepare_global_in(jl_Module, llvmgv);
@@ -185,13 +187,14 @@ static Value *runtime_sym_lookup(
185187
// Emit a "PLT" entry that will be lazily initialized
186188
// when being called the first time.
187189
static GlobalVariable *emit_plt_thunk(
188-
jl_codegen_params_t &emission_context,
190+
jl_codectx_t &ctx,
189191
FunctionType *functype, const AttributeList &attrs,
190192
CallingConv::ID cc, const char *f_lib, const char *f_name,
191193
GlobalVariable *libptrgv, GlobalVariable *llvmgv,
192194
bool runtime_lib)
193195
{
194-
Module *M = emission_context.shared_module(functype->getContext());
196+
auto &TSM = ctx.emission_context.shared_module(*jl_Module);
197+
Module *M = TSM.getModuleUnlocked();
195198
PointerType *funcptype = PointerType::get(functype, 0);
196199
libptrgv = prepare_global_in(M, libptrgv);
197200
llvmgv = prepare_global_in(M, llvmgv);
@@ -211,7 +214,7 @@ static GlobalVariable *emit_plt_thunk(
211214
fname);
212215
BasicBlock *b0 = BasicBlock::Create(M->getContext(), "top", plt);
213216
IRBuilder<> irbuilder(b0);
214-
Value *ptr = runtime_sym_lookup(emission_context, irbuilder, NULL, funcptype, f_lib, NULL, f_name, plt, libptrgv,
217+
Value *ptr = runtime_sym_lookup(ctx.emission_context, irbuilder, NULL, funcptype, f_lib, NULL, f_name, plt, libptrgv,
215218
llvmgv, runtime_lib);
216219
StoreInst *store = irbuilder.CreateAlignedStore(irbuilder.CreateBitCast(ptr, T_pvoidfunc), got, Align(sizeof(void*)));
217220
store->setAtomic(AtomicOrdering::Release);
@@ -266,14 +269,14 @@ static Value *emit_plt(
266269
assert(!functype->isVarArg());
267270
GlobalVariable *libptrgv;
268271
GlobalVariable *llvmgv;
269-
bool runtime_lib = runtime_sym_gvs(ctx.emission_context, ctx.builder.getContext(), f_lib, f_name, libptrgv, llvmgv);
272+
bool runtime_lib = runtime_sym_gvs(ctx, f_lib, f_name, libptrgv, llvmgv);
270273
PointerType *funcptype = PointerType::get(functype, 0);
271274

272275
auto &pltMap = ctx.emission_context.allPltMap[attrs];
273276
auto key = std::make_tuple(llvmgv, functype, cc);
274277
GlobalVariable *&sharedgot = pltMap[key];
275278
if (!sharedgot) {
276-
sharedgot = emit_plt_thunk(ctx.emission_context,
279+
sharedgot = emit_plt_thunk(ctx,
277280
functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib);
278281
}
279282
GlobalVariable *got = prepare_global_in(jl_Module, sharedgot);
@@ -921,7 +924,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
921924
// save the module to be linked later.
922925
// we cannot do this right now, because linking mutates the destination module,
923926
// which might invalidate LLVM values cached in cgval_t's (specifically constant arrays)
924-
ctx.llvmcall_modules.push_back(std::move(Mod));
927+
ctx.llvmcall_modules.push_back(orc::ThreadSafeModule(std::move(Mod), ctx.emission_context.tsctx));
925928

926929
JL_GC_POP();
927930

src/codegen-stubs.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ JL_DLLEXPORT void jl_extern_c_fallback(jl_function_t *f, jl_value_t *rt, jl_valu
1919
JL_DLLEXPORT jl_value_t *jl_dump_method_asm_fallback(jl_method_instance_t *linfo, size_t world,
2020
char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
2121
JL_DLLEXPORT jl_value_t *jl_dump_function_ir_fallback(void *f, char strip_ir_metadata, char dump_module, const char *debuginfo) UNAVAILABLE
22-
JL_DLLEXPORT void *jl_get_llvmf_defn_fallback(jl_method_instance_t *linfo, LLVMContextRef ctxt, size_t world, char getwrapper, char optimize, const jl_cgparams_t params) UNAVAILABLE
22+
JL_DLLEXPORT void *jl_get_llvmf_defn_fallback(jl_method_instance_t *linfo, size_t world, char getwrapper, char optimize, const jl_cgparams_t params) UNAVAILABLE
2323

2424
JL_DLLEXPORT void *jl_LLVMCreateDisasm_fallback(const char *TripleName, void *DisInfo, int TagType, void *GetOpInfo, void *SymbolLookUp) UNAVAILABLE
2525
JL_DLLEXPORT size_t jl_LLVMDisasmInstruction_fallback(void *DC, uint8_t *Bytes, uint64_t BytesSize, uint64_t PC, char *OutString, size_t OutStringSize) UNAVAILABLE
@@ -52,7 +52,7 @@ JL_DLLEXPORT uint32_t jl_get_LLVM_VERSION_fallback(void)
5252
return 0;
5353
}
5454

55-
JL_DLLEXPORT int jl_compile_extern_c_fallback(LLVMModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
55+
JL_DLLEXPORT int jl_compile_extern_c_fallback(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
5656
{
5757
return 0;
5858
}
@@ -74,7 +74,7 @@ JL_DLLEXPORT void jl_unlock_profile_fallback(void)
7474
{
7575
}
7676

77-
JL_DLLEXPORT void *jl_create_native_fallback(jl_array_t *methods, LLVMContextRef llvmctxt, const jl_cgparams_t *cgparams, int _policy) UNAVAILABLE
77+
JL_DLLEXPORT void *jl_create_native_fallback(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmctxt, const jl_cgparams_t *cgparams, int _policy) UNAVAILABLE
7878

7979
JL_DLLEXPORT void jl_dump_compiles_fallback(void *s)
8080
{
@@ -92,16 +92,13 @@ JL_DLLEXPORT jl_value_t *jl_dump_fptr_asm_fallback(uint64_t fptr, char raw_mc, c
9292

9393
JL_DLLEXPORT jl_value_t *jl_dump_function_asm_fallback(void *F, char raw_mc, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
9494

95-
JL_DLLEXPORT LLVMContextRef jl_get_ee_context_fallback(void) UNAVAILABLE
96-
9795
JL_DLLEXPORT void jl_get_function_id_fallback(void *native_code, jl_code_instance_t *ncode,
9896
int32_t *func_idx, int32_t *specfunc_idx) UNAVAILABLE
9997

100-
JL_DLLEXPORT void *jl_get_llvm_context_fallback(void *native_code) UNAVAILABLE
10198

10299
JL_DLLEXPORT void *jl_get_llvm_function_fallback(void *native_code, uint32_t idx) UNAVAILABLE
103100

104-
JL_DLLEXPORT void *jl_get_llvm_module_fallback(void *native_code) UNAVAILABLE
101+
JL_DLLEXPORT LLVMOrcThreadSafeModuleRef jl_get_llvm_module_fallback(void *native_code) UNAVAILABLE
105102

106103
JL_DLLEXPORT void *jl_type_to_llvm_fallback(jl_value_t *jt, LLVMContextRef llvmctxt, bool_t *isboxed) UNAVAILABLE
107104

0 commit comments

Comments
 (0)