[NFC][LTO] Move isPreservedName out of IRSymtab into LTO's Symbol as isLibcall (#177046)
This resolves the FIXME in IRSymtab and cleans up the semantics of the IRSymtab. The list of preserved symbols really shouldn't be seen as a property of the IR symbol table, since it's an LTO-specific concern, and it's very tenuous to claim that this information is actually present in the bitcode file to be exposed through its symbol table. Instead, this PR moves this logic into LTO's view of the symbol, which allows consumers to determine preserved-ness themselves. This was broken out of #164916; this prevents that PR from introducing a circular dependency, but it still seems like an independently good idea by virtue of the above.
This commit is contained in:
parent
1d5e0408c9
commit
567fe2bbca
@ -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());
|
||||
|
||||
@ -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 <memory>
|
||||
|
||||
@ -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<InputFile::Symbol> Syms,
|
||||
ArrayRef<SymbolResolution> 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
|
||||
|
||||
@ -597,6 +597,11 @@ Expected<std::unique_ptr<InputFile>> 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<InputFile::Symbol> Syms,
|
||||
ArrayRef<SymbolResolution> 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<InputFile::Symbol> 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<InputFile::Symbol> 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<SymbolResolution> 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);
|
||||
|
||||
@ -290,11 +290,12 @@ static void optimizeModule(Module &TheModule, TargetMachine &TM,
|
||||
static void
|
||||
addUsedSymbolToPreservedGUID(const lto::InputFile &File,
|
||||
DenseSet<GlobalValue::GUID> &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.
|
||||
|
||||
@ -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<char, 0> &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<const Comdat *, int> ComdatMap;
|
||||
Mangler Mang;
|
||||
const Triple &TT;
|
||||
|
||||
// FIXME: This shouldn't be here.
|
||||
RTLIB::RuntimeLibcallsInfo Libcalls;
|
||||
|
||||
std::vector<storage::Comdat> Comdats;
|
||||
std::vector<storage::Module> Mods;
|
||||
std::vector<storage::Symbol> Syms;
|
||||
@ -94,10 +89,6 @@ struct Builder {
|
||||
|
||||
std::vector<storage::Str> 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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user