diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index d415955b6093..492b2ad80166 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -25,6 +25,7 @@ #include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/IR/Mangler.h" +#include "llvm/IR/RuntimeLibcalls.h" #include "llvm/LTO/LTO.h" #include "llvm/Object/Binary.h" #include "llvm/Object/COFF.h" @@ -1395,6 +1396,8 @@ void BitcodeFile::parse() { // FIXME: Check nodeduplicate comdat[i] = symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first)); + Triple tt(obj->getTargetTriple()); + RTLIB::RuntimeLibcallsInfo libcalls(tt); for (const lto::InputFile::Symbol &objSym : obj->symbols()) { StringRef symName = saver.save(objSym.getName()); int comdatIndex = objSym.getComdatIndex(); @@ -1444,7 +1447,7 @@ void BitcodeFile::parse() { symtab.addRegular(this, symName, nullptr, fakeSC, 0, objSym.isWeak()); } symbols.push_back(sym); - if (objSym.isUsed()) + if (objSym.isUsed() || objSym.isLibcall(libcalls)) symtab.ctx.config.gcroot.push_back(sym); } directives = saver.save(obj->getCOFFLinkerOpts()); diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h index cba5cf7eb9e6..4011065ec37a 100644 --- a/llvm/include/llvm/LTO/LTO.h +++ b/llvm/include/llvm/LTO/LTO.h @@ -16,6 +16,7 @@ #define LLVM_LTO_LTO_H #include "llvm/IR/LLVMRemarkStreamer.h" +#include "llvm/IR/RuntimeLibcalls.h" #include "llvm/Support/Compiler.h" #include @@ -167,6 +168,12 @@ public: using irsymtab::Symbol::getSectionName; using irsymtab::Symbol::isExecutable; using irsymtab::Symbol::isUsed; + + // Returns whether this symbol is a library call that LTO code generation + // may emit references to. Such symbols must be considered external, as + // removing them or modifying their interfaces would invalidate the code + // generator's knowledge about them. + bool isLibcall(const RTLIB::RuntimeLibcallsInfo &Libcalls) const; }; /// A range over the symbols in this InputFile. @@ -583,7 +590,7 @@ private: void addModuleToGlobalRes(ArrayRef Syms, ArrayRef Res, unsigned Partition, - bool InSummary); + bool InSummary, const Triple &TT); // These functions take a range of symbol resolutions and consume the // resolutions used by a single input module. Functions return ranges refering diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 955a19db4860..152b2beeae12 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -597,6 +597,11 @@ Expected> InputFile::create(MemoryBufferRef Object) { return std::move(File); } +bool InputFile::Symbol::isLibcall( + const RTLIB::RuntimeLibcallsInfo &Libcalls) const { + return Libcalls.getSupportedLibcallImpl(IRName) != RTLIB::Unsupported; +} + StringRef InputFile::getName() const { return Mods[0].getModuleIdentifier(); } @@ -642,11 +647,13 @@ LTO::~LTO() = default; // their partitions. void LTO::addModuleToGlobalRes(ArrayRef Syms, ArrayRef Res, - unsigned Partition, bool InSummary) { + unsigned Partition, bool InSummary, + const Triple &TT) { llvm::TimeTraceScope timeScope("LTO add module to global resolution"); auto *ResI = Res.begin(); auto *ResE = Res.end(); (void)ResE; + RTLIB::RuntimeLibcallsInfo Libcalls(TT); for (const InputFile::Symbol &Sym : Syms) { assert(ResI != ResE); SymbolResolution Res = *ResI++; @@ -689,11 +696,14 @@ void LTO::addModuleToGlobalRes(ArrayRef Syms, GlobalRes.VisibleOutsideSummary = true; } + bool IsLibcall = Sym.isLibcall(Libcalls); + // Set the partition to external if we know it is re-defined by the linker // with -defsym or -wrap options, used elsewhere, e.g. it is visible to a // regular object, is referenced from llvm.compiler.used/llvm.used, or was // already recorded as being referenced from a different partition. if (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() || + IsLibcall || (GlobalRes.Partition != GlobalResolution::Unknown && GlobalRes.Partition != Partition)) { GlobalRes.Partition = GlobalResolution::External; @@ -704,7 +714,7 @@ void LTO::addModuleToGlobalRes(ArrayRef Syms, // Flag as visible outside of summary if visible from a regular object or // from a module that does not have a summary. GlobalRes.VisibleOutsideSummary |= - (Res.VisibleToRegularObj || Sym.isUsed() || !InSummary); + (Res.VisibleToRegularObj || Sym.isUsed() || IsLibcall || !InSummary); GlobalRes.ExportDynamic |= Res.ExportDynamic; } @@ -811,7 +821,7 @@ LTO::addModule(InputFile &Input, ArrayRef InputRes, auto ModSyms = Input.module_symbols(ModI); addModuleToGlobalRes(ModSyms, Res, IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0, - LTOInfo->HasSummary); + LTOInfo->HasSummary, Triple(Input.getTargetTriple())); if (IsThinLTO) return addThinLTO(BM, ModSyms, Res); diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp index 961dd0ee4337..93b672ae7840 100644 --- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -290,11 +290,12 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM, static void addUsedSymbolToPreservedGUID(const lto::InputFile &File, DenseSet &PreservedGUID) { - for (const auto &Sym : File.symbols()) { - if (Sym.isUsed()) + Triple TT(File.getTargetTriple()); + RTLIB::RuntimeLibcallsInfo Libcalls(TT); + for (const auto &Sym : File.symbols()) + if (Sym.isUsed() || Sym.isLibcall(Libcalls)) PreservedGUID.insert( GlobalValue::getGUIDAssumingExternalLinkage(Sym.getIRName())); - } } // Convert the PreservedSymbols map from "Name" based to "GUID" based. diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp index 20610262f6a1..878f4c911475 100644 --- a/llvm/lib/Object/IRSymtab.cpp +++ b/llvm/lib/Object/IRSymtab.cpp @@ -22,7 +22,6 @@ #include "llvm/IR/Mangler.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" -#include "llvm/IR/RuntimeLibcalls.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Object/SymbolicFile.h" @@ -74,16 +73,12 @@ struct Builder { // so this provides somewhere to store any strings that we create. Builder(SmallVector &Symtab, StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc, const Triple &TT) - : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc), TT(TT), - Libcalls(TT) {} + : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc), TT(TT) {} DenseMap ComdatMap; Mangler Mang; const Triple &TT; - // FIXME: This shouldn't be here. - RTLIB::RuntimeLibcallsInfo Libcalls; - std::vector Comdats; std::vector Mods; std::vector Syms; @@ -94,10 +89,6 @@ struct Builder { std::vector DependentLibraries; - bool isPreservedName(StringRef Name) { - return Libcalls.getSupportedLibcallImpl(Name) != RTLIB::Unsupported; - } - void setStr(storage::Str &S, StringRef Value) { S.Offset = StrtabBuilder.add(Value); S.Size = Value.size(); @@ -269,7 +260,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab, StringRef GVName = GV->getName(); setStr(Sym.IRName, GVName); - if (Used.count(GV) || isPreservedName(GVName)) + if (Used.count(GV)) Sym.Flags |= 1 << storage::Symbol::FB_used; if (GV->isThreadLocal()) Sym.Flags |= 1 << storage::Symbol::FB_tls;