|
20 | 20 | #include <llvm/Analysis/BasicAliasAnalysis.h> |
21 | 21 | #include <llvm/Analysis/TypeBasedAliasAnalysis.h> |
22 | 22 | #include <llvm/Analysis/ScopedNoAliasAA.h> |
| 23 | +#include <llvm/IR/IRBuilder.h> |
23 | 24 | #include <llvm/IR/PassManager.h> |
24 | 25 | #include <llvm/IR/Verifier.h> |
25 | 26 | #include <llvm/Transforms/IPO.h> |
@@ -434,6 +435,24 @@ static void reportWriterError(const ErrorInfoBase &E) |
434 | 435 | jl_safe_printf("ERROR: failed to emit output file %s\n", err.c_str()); |
435 | 436 | } |
436 | 437 |
|
| 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 | + |
437 | 456 |
|
438 | 457 | // takes the running content that has collected in the shadow module and dump it to disk |
439 | 458 | // 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, |
546 | 565 | "jl_RTLD_DEFAULT_handle_pointer")); |
547 | 566 | } |
548 | 567 |
|
| 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 | + |
549 | 582 | // do the actual work |
550 | 583 | auto add_output = [&] (Module &M, StringRef unopt_bc_Name, StringRef bc_Name, StringRef obj_Name, StringRef asm_Name) { |
551 | 584 | preopt.run(M); |
|
0 commit comments