[lld] d496abb - [lld-link] Replace LazyObjFile with lazy ObjFile/BitcodeFile
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 4 15:11:53 PST 2022
Author: Fangrui Song
Date: 2022-01-04T15:11:44-08:00
New Revision: d496abbe2a03721d5d22a697a3a1c5961a55f7f2
URL: https://github.com/llvm/llvm-project/commit/d496abbe2a03721d5d22a697a3a1c5961a55f7f2
DIFF: https://github.com/llvm/llvm-project/commit/d496abbe2a03721d5d22a697a3a1c5961a55f7f2.diff
LOG: [lld-link] Replace LazyObjFile with lazy ObjFile/BitcodeFile
Similar to ELF 3a5fb57393c3bc77be9e7afc2ec9d4ec3c9bbf70.
* 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
Added:
Modified:
lld/COFF/Driver.cpp
lld/COFF/InputFiles.cpp
lld/COFF/InputFiles.h
lld/COFF/SymbolTable.cpp
lld/COFF/SymbolTable.h
lld/COFF/Symbols.h
Removed:
################################################################################
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 07b60673577e2..6178d328e3f56 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -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;
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 4b38e3d1a99bc..06eec40d3a229 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -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:
diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index 801c668d3ae45..2cabb54cb3863 100644
--- a/lld/COFF/InputFiles.h
+++ b/lld/COFF/InputFiles.h
@@ -95,13 +95,17 @@ class InputFile {
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 @@ class ArchiveFile : public InputFile {
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 @@ class ImportFile : public InputFile {
// 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:
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 679c91ad06e6b..9ceac7af7f914 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -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,
diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h
index 3e76b416d1a0d..47f3238fd75b4 100644
--- a/lld/COFF/SymbolTable.h
+++ b/lld/COFF/SymbolTable.h
@@ -91,7 +91,7 @@ class SymbolTable {
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,
diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h
index bb911171b1f5e..c8865d128fb84 100644
--- a/lld/COFF/Symbols.h
+++ b/lld/COFF/Symbols.h
@@ -305,10 +305,9 @@ class LazyArchive : public Symbol {
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.
More information about the llvm-commits
mailing list