Skip to content

Commit c03a346

Browse files
Optimize PLT and jl_load_and_lookup calls (#50745)
1 parent 881e08b commit c03a346

File tree

5 files changed

+220
-60
lines changed

5 files changed

+220
-60
lines changed

src/aotcompile.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,6 +2159,9 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, siz
21592159
global.second->setVisibility(GlobalValue::DefaultVisibility);
21602160
}
21612161
}
2162+
if (!jl_options.image_codegen) {
2163+
optimizeDLSyms(*m.getModuleUnlocked());
2164+
}
21622165
assert(!verifyLLVMIR(*m.getModuleUnlocked()));
21632166
if (optimize) {
21642167
#ifndef JL_USE_NEW_PM

src/ccall.cpp

Lines changed: 14 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ static Value *runtime_sym_lookup(
170170
// f_lib is actually one of the special sentinel values
171171
libname = ConstantExpr::getIntToPtr(ConstantInt::get(emission_context.DL.getIntPtrType(irbuilder.getContext()), (uintptr_t)f_lib), getInt8PtrTy(irbuilder.getContext()));
172172
}
173-
llvmf = irbuilder.CreateCall(prepare_call_in(jl_builderModule(irbuilder), jldlsym_func),
173+
auto lookup = irbuilder.CreateCall(prepare_call_in(jl_builderModule(irbuilder), jldlsym_func),
174174
{ libname, nameval, libptrgv });
175+
llvmf = lookup;
175176
}
176177
setName(emission_context, llvmf, f_name + StringRef(".found"));
177178
StoreInst *store = irbuilder.CreateAlignedStore(llvmf, llvmgv, Align(sizeof(void*)));
@@ -187,17 +188,6 @@ static Value *runtime_sym_lookup(
187188
return irbuilder.CreateBitCast(p, funcptype);
188189
}
189190

190-
static Value *runtime_sym_lookup(
191-
jl_codectx_t &ctx,
192-
PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
193-
const char *f_name, Function *f,
194-
GlobalVariable *libptrgv,
195-
GlobalVariable *llvmgv, bool runtime_lib)
196-
{
197-
return runtime_sym_lookup(ctx.emission_context, ctx.builder, &ctx, funcptype, f_lib, lib_expr,
198-
f_name, f, libptrgv, llvmgv, runtime_lib);
199-
}
200-
201191
static Value *runtime_sym_lookup(
202192
jl_codectx_t &ctx,
203193
PointerType *funcptype, const char *f_lib, jl_value_t *lib_expr,
@@ -225,7 +215,7 @@ static Value *runtime_sym_lookup(
225215
libptrgv = prepare_global_in(jl_Module, libptrgv);
226216
}
227217
llvmgv = prepare_global_in(jl_Module, llvmgv);
228-
return runtime_sym_lookup(ctx, funcptype, f_lib, lib_expr, f_name, f, libptrgv, llvmgv, runtime_lib);
218+
return runtime_sym_lookup(ctx.emission_context, ctx.builder, &ctx, funcptype, f_lib, lib_expr, f_name, f, libptrgv, llvmgv, runtime_lib);
229219
}
230220

231221
// Emit a "PLT" entry that will be lazily initialized
@@ -250,21 +240,26 @@ static GlobalVariable *emit_plt_thunk(
250240
plt->setAttributes(attrs);
251241
if (cc != CallingConv::C)
252242
plt->setCallingConv(cc);
253-
fname += "_got";
254243
auto T_pvoidfunc = JuliaType::get_pvoidfunc_ty(M->getContext());
255244
GlobalVariable *got = new GlobalVariable(*M, T_pvoidfunc, false,
256245
GlobalVariable::ExternalLinkage,
257246
ConstantExpr::getBitCast(plt, T_pvoidfunc),
258-
fname);
247+
fname + "_got");
248+
if (runtime_lib) {
249+
got->addAttribute("julia.libname", f_lib);
250+
} else {
251+
got->addAttribute("julia.libidx", std::to_string((uintptr_t) f_lib));
252+
}
253+
got->addAttribute("julia.fname", f_name);
259254
BasicBlock *b0 = BasicBlock::Create(M->getContext(), "top", plt);
260255
IRBuilder<> irbuilder(b0);
261256
Value *ptr = runtime_sym_lookup(ctx.emission_context, irbuilder, NULL, funcptype, f_lib, NULL, f_name, plt, libptrgv,
262257
llvmgv, runtime_lib);
263258
StoreInst *store = irbuilder.CreateAlignedStore(irbuilder.CreateBitCast(ptr, T_pvoidfunc), got, Align(sizeof(void*)));
264259
store->setAtomic(AtomicOrdering::Release);
265260
SmallVector<Value*, 16> args;
266-
for (Function::arg_iterator arg = plt->arg_begin(), arg_e = plt->arg_end(); arg != arg_e; ++arg)
267-
args.push_back(&*arg);
261+
for (auto &arg : plt->args())
262+
args.push_back(&arg);
268263
assert(cast<PointerType>(ptr->getType())->isOpaqueOrPointeeTypeMatches(functype));
269264
CallInst *ret = irbuilder.CreateCall(
270265
functype,
@@ -307,7 +302,6 @@ static Value *emit_plt(
307302
CallingConv::ID cc, const char *f_lib, const char *f_name)
308303
{
309304
++PLT;
310-
assert(ctx.emission_context.imaging);
311305
// Don't do this for vararg functions so that the `musttail` is only
312306
// an optimization and is not required to function correctly.
313307
assert(!functype->isVarArg());
@@ -724,26 +718,10 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
724718
if (sym.lib_expr) {
725719
res = runtime_sym_lookup(ctx, cast<PointerType>(getInt8PtrTy(ctx.builder.getContext())), NULL, sym.lib_expr, sym.f_name, ctx.f);
726720
}
727-
else if (ctx.emission_context.imaging) {
721+
else /*if (ctx.emission_context.imaging) */{
728722
res = runtime_sym_lookup(ctx, cast<PointerType>(getInt8PtrTy(ctx.builder.getContext())), sym.f_lib, NULL, sym.f_name, ctx.f);
729723
res = ctx.builder.CreatePtrToInt(res, lrt);
730724
}
731-
else {
732-
void *symaddr;
733-
734-
void* libsym = jl_get_library_(sym.f_lib, 0);
735-
int symbol_found = jl_dlsym(libsym, sym.f_name, &symaddr, 0);
736-
if (!libsym || !symbol_found) {
737-
// Error mode, either the library or the symbol couldn't be find during compiletime.
738-
// Fallback to a runtime symbol lookup.
739-
res = runtime_sym_lookup(ctx, cast<PointerType>(getInt8PtrTy(ctx.builder.getContext())), sym.f_lib, NULL, sym.f_name, ctx.f);
740-
res = ctx.builder.CreatePtrToInt(res, lrt);
741-
} else {
742-
// since we aren't saving this code, there's no sense in
743-
// putting anything complicated here: just JIT the address of the cglobal
744-
res = ConstantInt::get(lrt, (uint64_t)symaddr);
745-
}
746-
}
747725
}
748726

749727
JL_GC_POP();
@@ -2106,7 +2084,7 @@ jl_cgval_t function_sig_t::emit_a_ccall(
21062084
++DeferredCCallLookups;
21072085
llvmf = runtime_sym_lookup(ctx, funcptype, NULL, symarg.lib_expr, symarg.f_name, ctx.f);
21082086
}
2109-
else if (ctx.emission_context.imaging) {
2087+
else /*if (ctx.emission_context.imaging) */{
21102088
++DeferredCCallLookups;
21112089
// vararg requires musttail,
21122090
// but musttail is incompatible with noreturn.
@@ -2115,22 +2093,6 @@ jl_cgval_t function_sig_t::emit_a_ccall(
21152093
else
21162094
llvmf = emit_plt(ctx, functype, attributes, cc, symarg.f_lib, symarg.f_name);
21172095
}
2118-
else {
2119-
void *symaddr;
2120-
void *libsym = jl_get_library_(symarg.f_lib, 0);
2121-
int symbol_found = jl_dlsym(libsym, symarg.f_name, &symaddr, 0);
2122-
if (!libsym || !symbol_found) {
2123-
++DeferredCCallLookups;
2124-
// either the library or the symbol could not be found, place a runtime
2125-
// lookup here instead.
2126-
llvmf = runtime_sym_lookup(ctx, funcptype, symarg.f_lib, NULL, symarg.f_name, ctx.f);
2127-
} else {
2128-
++LiteralCCalls;
2129-
// since we aren't saving this code, there's no sense in
2130-
// putting anything complicated here: just JIT the function address
2131-
llvmf = literal_static_pointer_val(symaddr, funcptype);
2132-
}
2133-
}
21342096
}
21352097

21362098
OperandBundleDef OpBundle("jl_roots", gc_uses);

src/codegen.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,6 +2368,8 @@ std::unique_ptr<Module> jl_create_llvm_module(StringRef name, LLVMContext &conte
23682368
if (!m->getModuleFlag("Debug Info Version"))
23692369
m->addModuleFlag(llvm::Module::Warning, "Debug Info Version",
23702370
llvm::DEBUG_METADATA_VERSION);
2371+
if (imaging_mode)
2372+
m->addModuleFlag(llvm::Module::Error, "julia.imaging_mode", 1);
23712373
m->setDataLayout(DL);
23722374
m->setTargetTriple(triple.str());
23732375

0 commit comments

Comments
 (0)