1414#include " llvm/IR/DiagnosticInfo.h"
1515#include " llvm/IR/DiagnosticPrinter.h"
1616#include " llvm/Linker/IRMover.h"
17+ #include " llvm/Object/ModuleSymbolTable.h"
1718#include " llvm/Support/Error.h"
1819
1920#include " LLVMWrapper.h"
@@ -44,7 +45,10 @@ enum class LinkFrom { Dst, Src, Both };
4445// / entrypoint for this file.
4546class ModuleLinker {
4647 IRMover &Mover;
48+ const StringSet<> &CompilerBuiltinsSymbols;
49+ StringSet<> UserBuiltinsSymbols;
4750 std::unique_ptr<Module> SrcM;
51+ bool SrcIsCompilerBuiltins;
4852
4953 SetVector<GlobalValue *> ValuesToLink;
5054
@@ -122,11 +126,14 @@ class ModuleLinker {
122126 bool linkIfNeeded (GlobalValue &GV, SmallVectorImpl<GlobalValue *> &GVToClone);
123127
124128public:
125- ModuleLinker (IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags,
129+ ModuleLinker (IRMover &Mover, const StringSet<> &CompilerBuiltinsSymbols,
130+ std::unique_ptr<Module> SrcM, bool SrcIsCompilerBuiltins,
131+ unsigned Flags,
126132 std::function<void (Module &, const StringSet<> &)>
127133 InternalizeCallback = {})
128- : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags),
129- InternalizeCallback (std::move(InternalizeCallback)) {}
134+ : Mover(Mover), CompilerBuiltinsSymbols(CompilerBuiltinsSymbols),
135+ SrcM (std::move(SrcM)), SrcIsCompilerBuiltins(SrcIsCompilerBuiltins),
136+ Flags(Flags), InternalizeCallback(std::move(InternalizeCallback)) {}
130137
131138 bool run ();
132139};
@@ -342,6 +349,10 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
342349
343350bool ModuleLinker::linkIfNeeded (GlobalValue &GV,
344351 SmallVectorImpl<GlobalValue *> &GVToClone) {
352+ // If a builtin symbol is defined in a non-compiler-builtins, the symbol of
353+ // compiler-builtins is a non-prevailing symbol.
354+ if (SrcIsCompilerBuiltins && UserBuiltinsSymbols.contains (GV.getName ()))
355+ return false ;
345356 GlobalValue *DGV = getLinkedToGlobal (&GV);
346357
347358 if (shouldLinkOnlyNeeded ()) {
@@ -501,6 +512,27 @@ bool ModuleLinker::run() {
501512 ReplacedDstComdats.insert (DstC);
502513 }
503514
515+ if (SrcIsCompilerBuiltins) {
516+ ModuleSymbolTable SymbolTable;
517+ SymbolTable.addModule (&DstM);
518+ for (auto &Sym : SymbolTable.symbols ()) {
519+ uint32_t Flags = SymbolTable.getSymbolFlags (Sym);
520+ if ((Flags & object::BasicSymbolRef::SF_Weak) ||
521+ !(Flags & object::BasicSymbolRef::SF_Global))
522+ continue ;
523+ if (GlobalValue *GV = dyn_cast_if_present<GlobalValue *>(Sym)) {
524+ if (CompilerBuiltinsSymbols.contains (GV->getName ()))
525+ UserBuiltinsSymbols.insert (GV->getName ());
526+ } else if (auto *AS =
527+ dyn_cast_if_present<ModuleSymbolTable::AsmSymbol *>(Sym)) {
528+ if (CompilerBuiltinsSymbols.contains (AS->first ))
529+ UserBuiltinsSymbols.insert (AS->first );
530+ } else {
531+ llvm::report_fatal_error (" unknown symbol type" );
532+ }
533+ }
534+ }
535+
504536 // Alias have to go first, since we are not able to find their comdats
505537 // otherwise.
506538 for (GlobalAlias &GV : llvm::make_early_inc_range (DstM.aliases ()))
@@ -617,6 +649,7 @@ namespace {
617649struct RustLinker {
618650 IRMover Mover;
619651 LLVMContext &Ctx;
652+ StringSet<> CompilerBuiltinsSymbols;
620653
621654 enum Flags {
622655 None = 0 ,
@@ -634,37 +667,44 @@ struct RustLinker {
634667 // / callback.
635668 // /
636669 // / Returns true on error.
637- bool linkInModule (std::unique_ptr<Module> Src, unsigned Flags = Flags::None,
670+ bool linkInModule (std::unique_ptr<Module> Src, bool SrcIsCompilerBuiltins,
671+ unsigned Flags = Flags::None,
638672 std::function<void (Module &, const StringSet<> &)>
639673 InternalizeCallback = {});
640674
641- RustLinker (Module &M) : Mover(M), Ctx(M.getContext()) {}
675+ RustLinker (Module &M, StringSet<> CompilerBuiltinsSymbols)
676+ : Mover(M), Ctx(M.getContext()),
677+ CompilerBuiltinsSymbols (CompilerBuiltinsSymbols) {}
642678};
643679
644680} // namespace
645681
646682bool RustLinker::linkInModule (
647- std::unique_ptr<Module> Src, unsigned Flags,
683+ std::unique_ptr<Module> Src, bool SrcIsCompilerBuiltins, unsigned Flags,
648684 std::function<void (Module &, const StringSet<> &)> InternalizeCallback) {
649- ModuleLinker ModLinker (Mover, std::move (Src), Flags,
685+ ModuleLinker ModLinker (Mover, CompilerBuiltinsSymbols, std::move (Src),
686+ SrcIsCompilerBuiltins, Flags,
650687 std::move (InternalizeCallback));
651688 return ModLinker.run ();
652689}
653690
654- extern " C" RustLinker*
655- LLVMRustLinkerNew (LLVMModuleRef DstRef ) {
691+ extern " C" RustLinker * LLVMRustLinkerNew (LLVMModuleRef DstRef, char **Symbols,
692+ size_t Len ) {
656693 Module *Dst = unwrap (DstRef);
657-
658- return new RustLinker (*Dst);
694+ StringSet<> CompilerBuiltinsSymbols;
695+ for (size_t I = 0 ; I < Len; I++) {
696+ CompilerBuiltinsSymbols.insert (Symbols[I]);
697+ }
698+ return new RustLinker (*Dst, CompilerBuiltinsSymbols);
659699}
660700
661701extern " C" void
662702LLVMRustLinkerFree (RustLinker *L) {
663703 delete L;
664704}
665705
666- extern " C" bool
667- LLVMRustLinkerAdd (RustLinker *L, char *BC, size_t Len ) {
706+ extern " C" bool LLVMRustLinkerAdd (RustLinker *L, char *BC, size_t Len,
707+ bool CompilerBuiltins ) {
668708 std::unique_ptr<MemoryBuffer> Buf =
669709 MemoryBuffer::getMemBufferCopy (StringRef (BC, Len));
670710
@@ -677,7 +717,7 @@ LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) {
677717
678718 auto Src = std::move (*SrcOrError);
679719
680- if (L->linkInModule (std::move (Src))) {
720+ if (L->linkInModule (std::move (Src), CompilerBuiltins )) {
681721 LLVMRustSetLastError (" " );
682722 return false ;
683723 }
0 commit comments