[lld] 7a8ee92 - [lld][WebAssembly] Process stub libraries in a loop
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 11 11:22:58 PDT 2023
Author: Sam Clegg
Date: 2023-08-11T11:07:40-07:00
New Revision: 7a8ee92fa83c13967e916868541518e7cebdead7
URL: https://github.com/llvm/llvm-project/commit/7a8ee92fa83c13967e916868541518e7cebdead7
DIFF: https://github.com/llvm/llvm-project/commit/7a8ee92fa83c13967e916868541518e7cebdead7.diff
LOG: [lld][WebAssembly] Process stub libraries in a loop
When stub libraries trigger the fetching of new object files we can
potentially introduce new undefined symbols so process the stub in
loop until no new objects are pulled in.
Differential Revision: https://reviews.llvm.org/D153466
Added:
lld/test/wasm/stub-library-archive.s
Modified:
lld/test/wasm/Inputs/libstub.so
lld/wasm/Driver.cpp
Removed:
################################################################################
diff --git a/lld/test/wasm/Inputs/libstub.so b/lld/test/wasm/Inputs/libstub.so
index 57e61f632b1017..f7e38b4272f249 100644
--- a/lld/test/wasm/Inputs/libstub.so
+++ b/lld/test/wasm/Inputs/libstub.so
@@ -3,3 +3,4 @@
foo: foodep1,foodep2
# This symbols as no dependencies
bar
+baz: bazdep
diff --git a/lld/test/wasm/stub-library-archive.s b/lld/test/wasm/stub-library-archive.s
new file mode 100644
index 00000000000000..7aacf676b34360
--- /dev/null
+++ b/lld/test/wasm/stub-library-archive.s
@@ -0,0 +1,60 @@
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %t/main.s
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t/foodeps.o %t/foodeps.s
+# RUN: rm -f %t/libfoodeps.a
+# RUN: llvm-ar rcs %t/libfoodeps.a %t/foodeps.o
+# RUN: wasm-ld %t.o %p/Inputs/libstub.so %t/libfoodeps.a -o %t.wasm
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+#--- main.s
+
+# The function foo is defined in libstub.so but depends on foodep1 and foodep2
+
+# foodep1 and foodep2 a defined libfoodeps.a(foodeps.o) but this function
+# depeds on baz which is also defined in libstub.so.
+
+.functype foo () -> ()
+
+.globl _start
+_start:
+ .functype _start () -> ()
+ call foo
+ end_function
+
+.globl bazdep
+bazdep:
+ .functype bazdep () -> ()
+ end_function
+
+#--- foodeps.s
+
+.functype baz () -> ()
+
+.globl foodep1
+foodep1:
+ .functype foodep1 () -> ()
+ call baz
+ end_function
+
+.globl foodep2
+foodep2:
+ .functype foodep2 () -> ()
+ end_function
+
+# CHECK: - Type: EXPORT
+# CHECK-NEXT: Exports:
+# CHECK-NEXT: - Name: memory
+# CHECK-NEXT: Kind: MEMORY
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: - Name: _start
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: - Name: bazdep
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: - Name: foodep1
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Index: 4
+# CHECK-NEXT: - Name: foodep2
+# CHECK-NEXT: Kind: FUNCTION
+# CHECK-NEXT: Index: 5
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index b0d6d1147e6b0b..c98d3522a5a227 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -898,52 +898,61 @@ static void processStubLibrariesPreLTO() {
static void processStubLibraries() {
log("-- processStubLibraries");
- for (auto &stub_file : symtab->stubFiles) {
- LLVM_DEBUG(llvm::dbgs()
- << "processing stub file: " << stub_file->getName() << "\n");
- for (auto [name, deps]: stub_file->symbolDependencies) {
- auto* sym = symtab->find(name);
- if (!sym || !sym->isUndefined()) {
- LLVM_DEBUG(llvm::dbgs() << "stub symbol not needed: " << name << "\n");
- continue;
- }
- // The first stub library to define a given symbol sets this and
- // definitions in later stub libraries are ignored.
- if (sym->forceImport)
- continue; // Already handled
- sym->forceImport = true;
- if (sym->traced)
- message(toString(stub_file) + ": importing " + name);
- else
- LLVM_DEBUG(llvm::dbgs()
- << toString(stub_file) << ": importing " << name << "\n");
- for (const auto dep : deps) {
- auto* needed = symtab->find(dep);
- if (!needed) {
- error(toString(stub_file) + ": undefined symbol: " + dep +
- ". Required by " + toString(*sym));
- } else if (needed->isUndefined()) {
- error(toString(stub_file) +
- ": undefined symbol: " + toString(*needed) +
- ". Required by " + toString(*sym));
- } else {
- if (needed->traced)
- message(toString(stub_file) + ": exported " + toString(*needed) +
- " due to import of " + name);
+ bool depsAdded = false;
+ do {
+ depsAdded = false;
+ for (auto &stub_file : symtab->stubFiles) {
+ LLVM_DEBUG(llvm::dbgs()
+ << "processing stub file: " << stub_file->getName() << "\n");
+ for (auto [name, deps]: stub_file->symbolDependencies) {
+ auto* sym = symtab->find(name);
+ if (!sym || !sym->isUndefined()) {
+ if (sym && sym->traced)
+ message(toString(stub_file) + ": stub symbol not needed: " + name);
else
- LLVM_DEBUG(llvm::dbgs()
- << "force export: " << toString(*needed) << "\n");
- needed->forceExport = true;
- if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
- lazy->fetch();
- if (!config->whyExtract.empty())
- config->whyExtractRecords.emplace_back(stub_file->getName(),
- sym->getFile(), *sym);
+ LLVM_DEBUG(llvm::dbgs() << "stub symbol not needed: `" << name << "`\n");
+ continue;
+ }
+ // The first stub library to define a given symbol sets this and
+ // definitions in later stub libraries are ignored.
+ if (sym->forceImport)
+ continue; // Already handled
+ sym->forceImport = true;
+ if (sym->traced)
+ message(toString(stub_file) + ": importing " + name);
+ else
+ LLVM_DEBUG(llvm::dbgs()
+ << toString(stub_file) << ": importing " << name << "\n");
+ for (const auto dep : deps) {
+ auto* needed = symtab->find(dep);
+ if (!needed) {
+ error(toString(stub_file) + ": undefined symbol: " + dep +
+ ". Required by " + toString(*sym));
+ } else if (needed->isUndefined()) {
+ error(toString(stub_file) +
+ ": undefined symbol: " + toString(*needed) +
+ ". Required by " + toString(*sym));
+ } else {
+ if (needed->traced)
+ message(toString(stub_file) + ": exported " + toString(*needed) +
+ " due to import of " + name);
+ else
+ LLVM_DEBUG(llvm::dbgs()
+ << "force export: " << toString(*needed) << "\n");
+ needed->forceExport = true;
+ if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
+ depsAdded = true;
+ lazy->fetch();
+ if (!config->whyExtract.empty())
+ config->whyExtractRecords.emplace_back(stub_file->getName(),
+ sym->getFile(), *sym);
+ }
}
}
}
}
- }
+ } while (depsAdded);
+
log("-- done processStubLibraries");
}
More information about the llvm-commits
mailing list