summaryrefslogtreecommitdiffstats
path: root/lld/wasm/SymbolTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/wasm/SymbolTable.cpp')
-rw-r--r--lld/wasm/SymbolTable.cpp58
1 files changed, 52 insertions, 6 deletions
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index c895ab5e9dc..6cc7c36db88 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -29,17 +29,46 @@ void SymbolTable::addFile(InputFile *File) {
log("Processing: " + toString(File));
File->parse();
- if (auto *F = dyn_cast<ObjFile>(File))
+ // LLVM bitcode file
+ if (auto *F = dyn_cast<BitcodeFile>(File))
+ BitcodeFiles.push_back(F);
+ else if (auto *F = dyn_cast<ObjFile>(File))
ObjectFiles.push_back(F);
}
+// This function is where all the optimizations of link-time
+// optimization happens. When LTO is in use, some input files are
+// not in native object file format but in the LLVM bitcode format.
+// This function compiles bitcode files into a few big native files
+// using LLVM functions and replaces bitcode symbols with the results.
+// Because all bitcode files that the program consists of are passed
+// to the compiler at once, it can do whole-program optimization.
+void SymbolTable::addCombinedLTOObject() {
+ if (BitcodeFiles.empty())
+ return;
+
+ // Compile bitcode files and replace bitcode symbols.
+ LTO.reset(new BitcodeCompiler);
+ for (BitcodeFile *F : BitcodeFiles)
+ LTO->add(*F);
+
+ for (StringRef Filename : LTO->compile()) {
+ auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"));
+ Obj->parse();
+ ObjectFiles.push_back(Obj);
+ }
+}
+
void SymbolTable::reportRemainingUndefines() {
SetVector<Symbol *> Undefs;
for (Symbol *Sym : SymVector) {
- if (Sym->isUndefined() && !Sym->isWeak() &&
- Config->AllowUndefinedSymbols.count(Sym->getName()) == 0) {
- Undefs.insert(Sym);
- }
+ if (!Sym->isUndefined() || Sym->isWeak())
+ continue;
+ if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0)
+ continue;
+ if (!Sym->IsUsedInRegularObj)
+ continue;
+ Undefs.insert(Sym);
}
if (Undefs.empty())
@@ -64,6 +93,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
if (Sym)
return {Sym, false};
Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
+ Sym->IsUsedInRegularObj = false;
SymVector.emplace_back(Sym);
return {Sym, true};
}
@@ -178,12 +208,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
+ if (!File || File->kind() == InputFile::ObjectKind)
+ S->IsUsedInRegularObj = true;
+
if (WasInserted || S->isLazy()) {
replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
return S;
}
- checkFunctionType(S, File, &Function->Signature);
+ if (Function)
+ checkFunctionType(S, File, &Function->Signature);
if (shouldReplace(S, File, Flags))
replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
@@ -199,6 +233,9 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
+ if (!File || File->kind() == InputFile::ObjectKind)
+ S->IsUsedInRegularObj = true;
+
if (WasInserted || S->isLazy()) {
replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
return S;
@@ -218,6 +255,9 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
+ if (!File || File->kind() == InputFile::ObjectKind)
+ S->IsUsedInRegularObj = true;
+
if (WasInserted || S->isLazy()) {
replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
return S;
@@ -239,6 +279,9 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
+ if (!File || File->kind() == InputFile::ObjectKind)
+ S->IsUsedInRegularObj = true;
+
if (WasInserted)
replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
@@ -274,6 +317,9 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
+ if (!File || File->kind() == InputFile::ObjectKind)
+ S->IsUsedInRegularObj = true;
+
if (WasInserted)
replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
else if (auto *Lazy = dyn_cast<LazySymbol>(S))
OpenPOWER on IntegriCloud