Skip to content

Commit

Permalink
Migrate codegen to operate on orc::ThreadSafeModule (#44440)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
pchintalapudi authored Apr 1, 2022
1 parent 48ae154 commit 4422a1d
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 273 deletions.
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

0 comments on commit 4422a1d

Please sign in to comment.