14
14
#include " llvm/IR/DiagnosticInfo.h"
15
15
#include " llvm/IR/DiagnosticPrinter.h"
16
16
#include " llvm/Linker/IRMover.h"
17
+ #include " llvm/Object/ModuleSymbolTable.h"
17
18
#include " llvm/Support/Error.h"
18
19
19
20
#include " LLVMWrapper.h"
@@ -44,7 +45,10 @@ enum class LinkFrom { Dst, Src, Both };
44
45
// / entrypoint for this file.
45
46
class ModuleLinker {
46
47
IRMover &Mover;
48
+ const StringSet<> &CompilerBuiltinsSymbols;
49
+ StringSet<> UserBuiltinsSymbols;
47
50
std::unique_ptr<Module> SrcM;
51
+ bool SrcIsCompilerBuiltins;
48
52
49
53
SetVector<GlobalValue *> ValuesToLink;
50
54
@@ -122,11 +126,14 @@ class ModuleLinker {
122
126
bool linkIfNeeded (GlobalValue &GV, SmallVectorImpl<GlobalValue *> &GVToClone);
123
127
124
128
public:
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,
126
132
std::function<void (Module &, const StringSet<> &)>
127
133
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)) {}
130
137
131
138
bool run ();
132
139
};
@@ -342,6 +349,10 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
342
349
343
350
bool ModuleLinker::linkIfNeeded (GlobalValue &GV,
344
351
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 ;
345
356
GlobalValue *DGV = getLinkedToGlobal (&GV);
346
357
347
358
if (shouldLinkOnlyNeeded ()) {
@@ -501,6 +512,27 @@ bool ModuleLinker::run() {
501
512
ReplacedDstComdats.insert (DstC);
502
513
}
503
514
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
+
504
536
// Alias have to go first, since we are not able to find their comdats
505
537
// otherwise.
506
538
for (GlobalAlias &GV : llvm::make_early_inc_range (DstM.aliases ()))
@@ -617,6 +649,7 @@ namespace {
617
649
struct RustLinker {
618
650
IRMover Mover;
619
651
LLVMContext &Ctx;
652
+ StringSet<> CompilerBuiltinsSymbols;
620
653
621
654
enum Flags {
622
655
None = 0 ,
@@ -634,37 +667,44 @@ struct RustLinker {
634
667
// / callback.
635
668
// /
636
669
// / 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,
638
672
std::function<void (Module &, const StringSet<> &)>
639
673
InternalizeCallback = {});
640
674
641
- RustLinker (Module &M) : Mover(M), Ctx(M.getContext()) {}
675
+ RustLinker (Module &M, StringSet<> CompilerBuiltinsSymbols)
676
+ : Mover(M), Ctx(M.getContext()),
677
+ CompilerBuiltinsSymbols (CompilerBuiltinsSymbols) {}
642
678
};
643
679
644
680
} // namespace
645
681
646
682
bool RustLinker::linkInModule (
647
- std::unique_ptr<Module> Src, unsigned Flags,
683
+ std::unique_ptr<Module> Src, bool SrcIsCompilerBuiltins, unsigned Flags,
648
684
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,
650
687
std::move (InternalizeCallback));
651
688
return ModLinker.run ();
652
689
}
653
690
654
- extern " C" RustLinker*
655
- LLVMRustLinkerNew (LLVMModuleRef DstRef ) {
691
+ extern " C" RustLinker * LLVMRustLinkerNew (LLVMModuleRef DstRef, char **Symbols,
692
+ size_t Len ) {
656
693
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);
659
699
}
660
700
661
701
extern " C" void
662
702
LLVMRustLinkerFree (RustLinker *L) {
663
703
delete L;
664
704
}
665
705
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 ) {
668
708
std::unique_ptr<MemoryBuffer> Buf =
669
709
MemoryBuffer::getMemBufferCopy (StringRef (BC, Len));
670
710
@@ -677,7 +717,7 @@ LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) {
677
717
678
718
auto Src = std::move (*SrcOrError);
679
719
680
- if (L->linkInModule (std::move (Src))) {
720
+ if (L->linkInModule (std::move (Src), CompilerBuiltins )) {
681
721
LLVMRustSetLastError (" " );
682
722
return false ;
683
723
}
0 commit comments