Skip to content

Commit aed6adf

Browse files
committed
Emit aliases into the system image
1 parent 64798ca commit aed6adf

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

src/aotcompile.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <llvm/Analysis/BasicAliasAnalysis.h>
2121
#include <llvm/Analysis/TypeBasedAliasAnalysis.h>
2222
#include <llvm/Analysis/ScopedNoAliasAA.h>
23+
#include <llvm/IR/IRBuilder.h>
2324
#include <llvm/IR/PassManager.h>
2425
#include <llvm/IR/Verifier.h>
2526
#include <llvm/Transforms/IPO.h>
@@ -434,6 +435,24 @@ static void reportWriterError(const ErrorInfoBase &E)
434435
jl_safe_printf("ERROR: failed to emit output file %s\n", err.c_str());
435436
}
436437

438+
static void injectCRTAlias(Module &M, StringRef name, StringRef alias, FunctionType *FT)
439+
{
440+
Function *target = M.getFunction(alias);
441+
if (!target) {
442+
target = Function::Create(FT, Function::ExternalLinkage, alias, M);
443+
}
444+
// Weak so that this does not get discarded
445+
// maybe use llvm.compiler.used instead?
446+
Function *interposer = Function::Create(FT, Function::WeakAnyLinkage, name, M);
447+
448+
llvm::IRBuilder<> builder(BasicBlock::Create(M.getContext(), "top", interposer));
449+
SmallVector<Value *, 4> CallArgs;
450+
for (auto &arg : interposer->args())
451+
CallArgs.push_back(&arg);
452+
auto val = builder.CreateCall(target, CallArgs);
453+
builder.CreateRet(val);
454+
}
455+
437456

438457
// takes the running content that has collected in the shadow module and dump it to disk
439458
// this builds the object file portion of the sysimage files for fast startup
@@ -546,6 +565,20 @@ void jl_dump_native_impl(void *native_code,
546565
"jl_RTLD_DEFAULT_handle_pointer"));
547566
}
548567

568+
// We would like to emit an alias or an weakref alias to redirect these symbols
569+
// but LLVM doesn't let us emit a GlobalAlias to a declaration...
570+
// So for now we inject a definition of these functions that calls our runtime functions.
571+
injectCRTAlias(*dataM, "__gnu_h2f_ieee", "julia__gnu_h2f_ieee",
572+
FunctionType::get(Type::getFloatTy(Context), { Type::getHalfTy(Context) }, false));
573+
injectCRTAlias(*dataM, "__extendhfsf2", "julia__gnu_h2f_ieee",
574+
FunctionType::get(Type::getFloatTy(Context), { Type::getHalfTy(Context) }, false));
575+
injectCRTAlias(*dataM, "__gnu_f2h_ieee", "julia__gnu_f2h_ieee",
576+
FunctionType::get(Type::getHalfTy(Context), { Type::getFloatTy(Context) }, false));
577+
injectCRTAlias(*dataM, "__truncsfhf2", "julia__gnu_f2h_ieee",
578+
FunctionType::get(Type::getHalfTy(Context), { Type::getFloatTy(Context) }, false));
579+
injectCRTAlias(*dataM, "__truncdfhf2", "julia__truncdfhf2",
580+
FunctionType::get(Type::getHalfTy(Context), { Type::getDoubleTy(Context) }, false));
581+
549582
// do the actual work
550583
auto add_output = [&] (Module &M, StringRef unopt_bc_Name, StringRef bc_Name, StringRef obj_Name, StringRef asm_Name) {
551584
preopt.run(M);

0 commit comments

Comments
 (0)