Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate codegen to operate on orc::ThreadSafeModule #44440

Merged
merged 7 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/src/devdocs/locks.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ The following is a level 4 lock, which can only recurse to acquire level 1, 2, o

No Julia code may be called while holding a lock above this point.

orc::ThreadSafeContext locks occupy a special spot in the locking diagram. They are used to protect
LLVM's global non-threadsafe state, but there may be an arbitrary number of them. For now, there is
only one global context, and thus acquiring it is a level 5 lock. However, acquiring such a lock
should only be done at the same time that the codegen lock is acquired.

The following are a level 6 lock, which can only recurse to acquire locks at lower levels:

> * codegen
Expand Down
125 changes: 64 additions & 61 deletions src/aotcompile.cpp

Large diffs are not rendered by default.

31 changes: 17 additions & 14 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,40 @@ GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M)
// Find or create the GVs for the library and symbol lookup.
// Return `runtime_lib` (whether the library name is a string)
// The `lib` and `sym` GV returned may not be in the current module.
static bool runtime_sym_gvs(jl_codegen_params_t &emission_context, LLVMContext &ctxt, const char *f_lib, const char *f_name,
static bool runtime_sym_gvs(jl_codectx_t &ctx, const char *f_lib, const char *f_name,
GlobalVariable *&lib, GlobalVariable *&sym)
{
Module *M = emission_context.shared_module(ctxt);
auto &TSM = ctx.emission_context.shared_module(*jl_Module);
//Safe b/c emission context holds context lock
auto M = TSM.getModuleUnlocked();
bool runtime_lib = false;
GlobalVariable *libptrgv;
jl_codegen_params_t::SymMapGV *symMap;
#ifdef _OS_WINDOWS_
if ((intptr_t)f_lib == (intptr_t)JL_EXE_LIBNAME) {
libptrgv = prepare_global_in(M, jlexe_var);
symMap = &emission_context.symMapExe;
symMap = &ctx.emission_context.symMapExe;
}
else if ((intptr_t)f_lib == (intptr_t)JL_LIBJULIA_INTERNAL_DL_LIBNAME) {
libptrgv = prepare_global_in(M, jldlli_var);
symMap = &emission_context.symMapDlli;
symMap = &ctx.emission_context.symMapDlli;
}
else if ((intptr_t)f_lib == (intptr_t)JL_LIBJULIA_DL_LIBNAME) {
libptrgv = prepare_global_in(M, jldll_var);
symMap = &emission_context.symMapDll;
symMap = &ctx.emission_context.symMapDll;
}
else
#endif
if (f_lib == NULL) {
libptrgv = jl_emit_RTLD_DEFAULT_var(M);
symMap = &emission_context.symMapDefault;
symMap = &ctx.emission_context.symMapDefault;
}
else {
std::string name = "ccalllib_";
name += llvm::sys::path::filename(f_lib);
name += std::to_string(globalUniqueGeneratedNames++);
runtime_lib = true;
auto &libgv = emission_context.libMapGV[f_lib];
auto &libgv = ctx.emission_context.libMapGV[f_lib];
if (libgv.first == NULL) {
libptrgv = new GlobalVariable(*M, getInt8PtrTy(M->getContext()), false,
GlobalVariable::ExternalLinkage,
Expand Down Expand Up @@ -175,7 +177,7 @@ static Value *runtime_sym_lookup(
Constant::getNullValue(T_pvoidfunc), gvname);
}
else {
runtime_lib = runtime_sym_gvs(ctx.emission_context, ctx.builder.getContext(), f_lib, f_name, libptrgv, llvmgv);
runtime_lib = runtime_sym_gvs(ctx, f_lib, f_name, libptrgv, llvmgv);
libptrgv = prepare_global_in(jl_Module, libptrgv);
}
llvmgv = prepare_global_in(jl_Module, llvmgv);
Expand All @@ -185,13 +187,14 @@ static Value *runtime_sym_lookup(
// Emit a "PLT" entry that will be lazily initialized
// when being called the first time.
static GlobalVariable *emit_plt_thunk(
jl_codegen_params_t &emission_context,
jl_codectx_t &ctx,
FunctionType *functype, const AttributeList &attrs,
CallingConv::ID cc, const char *f_lib, const char *f_name,
GlobalVariable *libptrgv, GlobalVariable *llvmgv,
bool runtime_lib)
{
Module *M = emission_context.shared_module(functype->getContext());
auto &TSM = ctx.emission_context.shared_module(*jl_Module);
Module *M = TSM.getModuleUnlocked();
PointerType *funcptype = PointerType::get(functype, 0);
libptrgv = prepare_global_in(M, libptrgv);
llvmgv = prepare_global_in(M, llvmgv);
Expand All @@ -211,7 +214,7 @@ static GlobalVariable *emit_plt_thunk(
fname);
BasicBlock *b0 = BasicBlock::Create(M->getContext(), "top", plt);
IRBuilder<> irbuilder(b0);
Value *ptr = runtime_sym_lookup(emission_context, irbuilder, NULL, funcptype, f_lib, NULL, f_name, plt, libptrgv,
Value *ptr = runtime_sym_lookup(ctx.emission_context, irbuilder, NULL, funcptype, f_lib, NULL, f_name, plt, libptrgv,
llvmgv, runtime_lib);
StoreInst *store = irbuilder.CreateAlignedStore(irbuilder.CreateBitCast(ptr, T_pvoidfunc), got, Align(sizeof(void*)));
store->setAtomic(AtomicOrdering::Release);
Expand Down Expand Up @@ -266,14 +269,14 @@ static Value *emit_plt(
assert(!functype->isVarArg());
GlobalVariable *libptrgv;
GlobalVariable *llvmgv;
bool runtime_lib = runtime_sym_gvs(ctx.emission_context, ctx.builder.getContext(), f_lib, f_name, libptrgv, llvmgv);
bool runtime_lib = runtime_sym_gvs(ctx, f_lib, f_name, libptrgv, llvmgv);
PointerType *funcptype = PointerType::get(functype, 0);

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

JL_GC_POP();

Expand Down
11 changes: 4 additions & 7 deletions src/codegen-stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ JL_DLLEXPORT void jl_extern_c_fallback(jl_function_t *f, jl_value_t *rt, jl_valu
JL_DLLEXPORT jl_value_t *jl_dump_method_asm_fallback(jl_method_instance_t *linfo, size_t world,
char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE
JL_DLLEXPORT jl_value_t *jl_dump_function_ir_fallback(void *f, char strip_ir_metadata, char dump_module, const char *debuginfo) UNAVAILABLE
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
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

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

JL_DLLEXPORT int jl_compile_extern_c_fallback(LLVMModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
JL_DLLEXPORT int jl_compile_extern_c_fallback(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
{
return 0;
}
Expand All @@ -74,7 +74,7 @@ JL_DLLEXPORT void jl_unlock_profile_fallback(void)
{
}

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

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

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

JL_DLLEXPORT LLVMContextRef jl_get_ee_context_fallback(void) UNAVAILABLE

JL_DLLEXPORT void jl_get_function_id_fallback(void *native_code, jl_code_instance_t *ncode,
int32_t *func_idx, int32_t *specfunc_idx) UNAVAILABLE

JL_DLLEXPORT void *jl_get_llvm_context_fallback(void *native_code) UNAVAILABLE

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

JL_DLLEXPORT void *jl_get_llvm_module_fallback(void *native_code) UNAVAILABLE
JL_DLLEXPORT LLVMOrcThreadSafeModuleRef jl_get_llvm_module_fallback(void *native_code) UNAVAILABLE

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

Expand Down
Loading