[lld-link] Replace LazyObjFile with lazy ObjFile/BitcodeFile
Similar to ELF 3a5fb57393.
* previously when a LazyObjFile was extracted, a new ObjFile/BitcodeFile was created; now the file is reused, just with `lazy` cleared
* avoid the confusing transfer of `symbols` from LazyObjFile to the new file
* simpler code, smaller executable (5200+ bytes smaller on x86-64)
* make eager parsing feasible (for parallel section/symbol table initialization)
Reviewed By: aganea, rnk
Differential Revision: https://reviews.llvm.org/D116434
This commit is contained in:
@@ -208,17 +208,11 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
|
||||
ctx.symtab.addFile(make<ArchiveFile>(ctx, mbref));
|
||||
break;
|
||||
case file_magic::bitcode:
|
||||
if (lazy)
|
||||
ctx.symtab.addFile(make<LazyObjFile>(ctx, mbref));
|
||||
else
|
||||
ctx.symtab.addFile(make<BitcodeFile>(ctx, mbref, "", 0));
|
||||
ctx.symtab.addFile(make<BitcodeFile>(ctx, mbref, "", 0, lazy));
|
||||
break;
|
||||
case file_magic::coff_object:
|
||||
case file_magic::coff_import_library:
|
||||
if (lazy)
|
||||
ctx.symtab.addFile(make<LazyObjFile>(ctx, mbref));
|
||||
else
|
||||
ctx.symtab.addFile(make<ObjFile>(ctx, mbref));
|
||||
ctx.symtab.addFile(make<ObjFile>(ctx, mbref, lazy));
|
||||
break;
|
||||
case file_magic::pdb:
|
||||
ctx.symtab.addFile(make<PDBInputFile>(ctx, mbref));
|
||||
@@ -282,7 +276,8 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
|
||||
if (magic == file_magic::coff_object) {
|
||||
obj = make<ObjFile>(ctx, mb);
|
||||
} else if (magic == file_magic::bitcode) {
|
||||
obj = make<BitcodeFile>(ctx, mb, parentName, offsetInArchive);
|
||||
obj =
|
||||
make<BitcodeFile>(ctx, mb, parentName, offsetInArchive, /*lazy=*/false);
|
||||
} else {
|
||||
error("unknown file type: " + mb.getBufferIdentifier());
|
||||
return;
|
||||
|
||||
@@ -135,31 +135,7 @@ std::vector<MemoryBufferRef> lld::coff::getArchiveMembers(Archive *file) {
|
||||
return v;
|
||||
}
|
||||
|
||||
void LazyObjFile::fetch() {
|
||||
if (mb.getBuffer().empty())
|
||||
return;
|
||||
|
||||
InputFile *file;
|
||||
if (isBitcode(mb))
|
||||
file = make<BitcodeFile>(ctx, mb, "", 0, std::move(symbols));
|
||||
else
|
||||
file = make<ObjFile>(ctx, mb, std::move(symbols));
|
||||
mb = {};
|
||||
ctx.symtab.addFile(file);
|
||||
}
|
||||
|
||||
void LazyObjFile::parse() {
|
||||
if (isBitcode(this->mb)) {
|
||||
// Bitcode file.
|
||||
std::unique_ptr<lto::InputFile> obj =
|
||||
CHECK(lto::InputFile::create(this->mb), this);
|
||||
for (const lto::InputFile::Symbol &sym : obj->symbols()) {
|
||||
if (!sym.isUndefined())
|
||||
ctx.symtab.addLazyObject(this, sym.getName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void ObjFile::parseLazy() {
|
||||
// Native object file.
|
||||
std::unique_ptr<Binary> coffObjPtr = CHECK(createBinary(mb), this);
|
||||
COFFObjectFile *coffObj = cast<COFFObjectFile>(coffObjPtr.get());
|
||||
@@ -1005,14 +981,10 @@ void ImportFile::parse() {
|
||||
name, cast_or_null<DefinedImportData>(impSym), hdr->Machine);
|
||||
}
|
||||
|
||||
BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
|
||||
StringRef archiveName, uint64_t offsetInArchive)
|
||||
: BitcodeFile(ctx, mb, archiveName, offsetInArchive, {}) {}
|
||||
|
||||
BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
|
||||
StringRef archiveName, uint64_t offsetInArchive,
|
||||
std::vector<Symbol *> &&symbols)
|
||||
: InputFile(ctx, BitcodeKind, mb), symbols(std::move(symbols)) {
|
||||
bool lazy)
|
||||
: InputFile(ctx, BitcodeKind, mb, lazy) {
|
||||
std::string path = mb.getBufferIdentifier().str();
|
||||
if (config->thinLTOIndexOnly)
|
||||
path = replaceThinLTOSuffix(mb.getBufferIdentifier());
|
||||
@@ -1107,6 +1079,13 @@ void BitcodeFile::parse() {
|
||||
directives = obj->getCOFFLinkerOpts();
|
||||
}
|
||||
|
||||
void BitcodeFile::parseLazy() {
|
||||
std::unique_ptr<lto::InputFile> obj = CHECK(lto::InputFile::create(mb), this);
|
||||
for (const lto::InputFile::Symbol &sym : obj->symbols())
|
||||
if (!sym.isUndefined())
|
||||
ctx.symtab.addLazyObject(this, sym.getName());
|
||||
}
|
||||
|
||||
MachineTypes BitcodeFile::getMachineType() {
|
||||
switch (Triple(obj->getTargetTriple()).getArch()) {
|
||||
case Triple::x86_64:
|
||||
|
||||
@@ -95,13 +95,17 @@ public:
|
||||
COFFLinkerContext &ctx;
|
||||
|
||||
protected:
|
||||
InputFile(COFFLinkerContext &c, Kind k, MemoryBufferRef m)
|
||||
: mb(m), ctx(c), fileKind(k) {}
|
||||
InputFile(COFFLinkerContext &c, Kind k, MemoryBufferRef m, bool lazy = false)
|
||||
: mb(m), ctx(c), fileKind(k), lazy(lazy) {}
|
||||
|
||||
StringRef directives;
|
||||
|
||||
private:
|
||||
const Kind fileKind;
|
||||
|
||||
public:
|
||||
// True if this is a lazy ObjFile or BitcodeFile.
|
||||
bool lazy = false;
|
||||
};
|
||||
|
||||
// .lib or .a file.
|
||||
@@ -121,33 +125,14 @@ private:
|
||||
llvm::DenseSet<uint64_t> seen;
|
||||
};
|
||||
|
||||
// .obj or .o file between -start-lib and -end-lib.
|
||||
class LazyObjFile : public InputFile {
|
||||
public:
|
||||
explicit LazyObjFile(COFFLinkerContext &ctx, MemoryBufferRef m)
|
||||
: InputFile(ctx, LazyObjectKind, m) {}
|
||||
static bool classof(const InputFile *f) {
|
||||
return f->kind() == LazyObjectKind;
|
||||
}
|
||||
// Makes this object file part of the link.
|
||||
void fetch();
|
||||
// Adds the symbols in this file to the symbol table as LazyObject symbols.
|
||||
void parse() override;
|
||||
|
||||
private:
|
||||
std::vector<Symbol *> symbols;
|
||||
};
|
||||
|
||||
// .obj or .o file. This may be a member of an archive file.
|
||||
class ObjFile : public InputFile {
|
||||
public:
|
||||
explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m)
|
||||
: InputFile(ctx, ObjectKind, m) {}
|
||||
explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m,
|
||||
std::vector<Symbol *> &&symbols)
|
||||
: InputFile(ctx, ObjectKind, m), symbols(std::move(symbols)) {}
|
||||
explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy = false)
|
||||
: InputFile(ctx, ObjectKind, m, lazy) {}
|
||||
static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
|
||||
void parse() override;
|
||||
void parseLazy();
|
||||
MachineTypes getMachineType() override;
|
||||
ArrayRef<Chunk *> getChunks() { return chunks; }
|
||||
ArrayRef<SectionChunk *> getDebugChunks() { return debugChunks; }
|
||||
@@ -380,15 +365,14 @@ public:
|
||||
// Used for LTO.
|
||||
class BitcodeFile : public InputFile {
|
||||
public:
|
||||
BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb, StringRef archiveName,
|
||||
uint64_t offsetInArchive);
|
||||
explicit BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef m,
|
||||
explicit BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
|
||||
StringRef archiveName, uint64_t offsetInArchive,
|
||||
std::vector<Symbol *> &&symbols);
|
||||
bool lazy);
|
||||
~BitcodeFile();
|
||||
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
|
||||
ArrayRef<Symbol *> getSymbols() { return symbols; }
|
||||
MachineTypes getMachineType() override;
|
||||
void parseLazy();
|
||||
std::unique_ptr<llvm::lto::InputFile> obj;
|
||||
|
||||
private:
|
||||
|
||||
@@ -37,7 +37,21 @@ StringRef ltrim1(StringRef s, const char *chars) {
|
||||
|
||||
void SymbolTable::addFile(InputFile *file) {
|
||||
log("Reading " + toString(file));
|
||||
file->parse();
|
||||
if (file->lazy) {
|
||||
if (auto *f = dyn_cast<BitcodeFile>(file))
|
||||
f->parseLazy();
|
||||
else
|
||||
cast<ObjFile>(file)->parseLazy();
|
||||
} else {
|
||||
file->parse();
|
||||
if (auto *f = dyn_cast<ObjFile>(file)) {
|
||||
ctx.objFileInstances.push_back(f);
|
||||
} else if (auto *f = dyn_cast<BitcodeFile>(file)) {
|
||||
ctx.bitcodeFileInstances.push_back(f);
|
||||
} else if (auto *f = dyn_cast<ImportFile>(file)) {
|
||||
ctx.importFileInstances.push_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
MachineTypes mt = file->getMachineType();
|
||||
if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||
@@ -48,14 +62,6 @@ void SymbolTable::addFile(InputFile *file) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto *f = dyn_cast<ObjFile>(file)) {
|
||||
ctx.objFileInstances.push_back(f);
|
||||
} else if (auto *f = dyn_cast<BitcodeFile>(file)) {
|
||||
ctx.bitcodeFileInstances.push_back(f);
|
||||
} else if (auto *f = dyn_cast<ImportFile>(file)) {
|
||||
ctx.importFileInstances.push_back(f);
|
||||
}
|
||||
|
||||
driver->parseDirectives(file);
|
||||
}
|
||||
|
||||
@@ -75,9 +81,11 @@ static void forceLazy(Symbol *s) {
|
||||
l->file->addMember(l->sym);
|
||||
break;
|
||||
}
|
||||
case Symbol::Kind::LazyObjectKind:
|
||||
cast<LazyObject>(s)->file->fetch();
|
||||
case Symbol::Kind::LazyObjectKind: {
|
||||
InputFile *file = cast<LazyObject>(s)->file;
|
||||
file->ctx.symtab.addFile(file);
|
||||
break;
|
||||
}
|
||||
case Symbol::Kind::LazyDLLSymbolKind: {
|
||||
auto *l = cast<LazyDLLSymbol>(s);
|
||||
l->file->makeImport(l->sym);
|
||||
@@ -562,7 +570,8 @@ void SymbolTable::addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym) {
|
||||
f->addMember(sym);
|
||||
}
|
||||
|
||||
void SymbolTable::addLazyObject(LazyObjFile *f, StringRef n) {
|
||||
void SymbolTable::addLazyObject(InputFile *f, StringRef n) {
|
||||
assert(f->lazy);
|
||||
Symbol *s;
|
||||
bool wasInserted;
|
||||
std::tie(s, wasInserted) = insert(n, f);
|
||||
@@ -574,7 +583,8 @@ void SymbolTable::addLazyObject(LazyObjFile *f, StringRef n) {
|
||||
if (!u || u->weakAlias || s->pendingArchiveLoad)
|
||||
return;
|
||||
s->pendingArchiveLoad = true;
|
||||
f->fetch();
|
||||
f->lazy = false;
|
||||
addFile(f);
|
||||
}
|
||||
|
||||
void SymbolTable::addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym,
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
|
||||
Symbol *addUndefined(StringRef name, InputFile *f, bool isWeakAlias);
|
||||
void addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym);
|
||||
void addLazyObject(LazyObjFile *f, StringRef n);
|
||||
void addLazyObject(InputFile *f, StringRef n);
|
||||
void addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym, StringRef n);
|
||||
Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
|
||||
Symbol *addRegular(InputFile *f, StringRef n,
|
||||
|
||||
@@ -305,10 +305,9 @@ public:
|
||||
|
||||
class LazyObject : public Symbol {
|
||||
public:
|
||||
LazyObject(LazyObjFile *f, StringRef n)
|
||||
: Symbol(LazyObjectKind, n), file(f) {}
|
||||
LazyObject(InputFile *f, StringRef n) : Symbol(LazyObjectKind, n), file(f) {}
|
||||
static bool classof(const Symbol *s) { return s->kind() == LazyObjectKind; }
|
||||
LazyObjFile *file;
|
||||
InputFile *file;
|
||||
};
|
||||
|
||||
// MinGW only.
|
||||
|
||||
Reference in New Issue
Block a user