Skip to content

Commit 8d06ab5

Browse files
sbc100Ferdinand Lemaire
authored and
Ferdinand Lemaire
committed
[lld][WebAssembly] stub objects: Fix handling of LTO libcall dependencies
This actually simplifies the code by performs a pre-pass of the stub objects prior to LTO. This should be the final change needed before we can make the switch on the emscripten side: emscripten-core/emscripten#18905 Differential Revision: https://reviews.llvm.org/D148287
1 parent d6267d3 commit 8d06ab5

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

lld/test/wasm/lto/stub-library-libcall.s

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# RUN: split-file %s %t
22
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t_main.o %t/main.s
3-
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t_foo.o %t/foo.s
3+
# RUN: llvm-as %S/Inputs/foo.ll -o %t_foo.o
44
# RUN: llvm-as %S/Inputs/libcall.ll -o %t_libcall.o
55
# RUN: wasm-ld %t_main.o %t_libcall.o %t_foo.o %p/Inputs/stub.so -o %t.wasm
66
# RUN: obj2yaml %t.wasm | FileCheck %s
@@ -25,12 +25,6 @@ _start:
2525
call func_with_libcall
2626
end_function
2727

28-
#--- foo.s
29-
.globl foo
30-
foo:
31-
.functype foo () -> ()
32-
end_function
33-
3428
# CHECK: Imports:
3529
# CHECK-NEXT: - Module: env
3630
# CHECK-NEXT: Field: memcpy
@@ -46,4 +40,4 @@ foo:
4640
# CHECK-NEXT: Index: 1
4741
# CHECK-NEXT: - Name: foo
4842
# CHECK-NEXT: Kind: FUNCTION
49-
# CHECK-NEXT: Index: 2
43+
# CHECK-NEXT: Index: 3

lld/wasm/Driver.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -874,19 +874,43 @@ static void createOptionalSymbols() {
874874
WasmSym::tlsBase = createOptionalGlobal("__tls_base", false);
875875
}
876876

877+
static void processStubLibrariesPreLTO() {
878+
log("-- processStubLibrariesPreLTO");
879+
for (auto &stub_file : symtab->stubFiles) {
880+
LLVM_DEBUG(llvm::dbgs()
881+
<< "processing stub file: " << stub_file->getName() << "\n");
882+
for (auto [name, deps]: stub_file->symbolDependencies) {
883+
auto* sym = symtab->find(name);
884+
// If the symbol is not present at all (yet), or if it is present but
885+
// undefined, then mark the dependent symbols as used by a regular
886+
// object so they will be preserved and exported by the LTO process.
887+
if (!sym || sym->isUndefined()) {
888+
for (const auto dep : deps) {
889+
auto* needed = symtab->find(dep);
890+
if (needed ) {
891+
needed->isUsedInRegularObj = true;
892+
}
893+
}
894+
}
895+
}
896+
}
897+
}
898+
877899
static void processStubLibraries() {
878900
log("-- processStubLibraries");
879901
for (auto &stub_file : symtab->stubFiles) {
880902
LLVM_DEBUG(llvm::dbgs()
881903
<< "processing stub file: " << stub_file->getName() << "\n");
882904
for (auto [name, deps]: stub_file->symbolDependencies) {
883905
auto* sym = symtab->find(name);
884-
if (!sym || !sym->isUndefined() || sym->forceImport) {
885-
LLVM_DEBUG(llvm::dbgs() << "stub not in needed: " << name << "\n");
906+
if (!sym || !sym->isUndefined()) {
907+
LLVM_DEBUG(llvm::dbgs() << "stub symbol not needed: " << name << "\n");
886908
continue;
887909
}
888910
// The first stub library to define a given symbol sets this and
889911
// definitions in later stub libraries are ignored.
912+
if (sym->forceImport)
913+
continue; // Already handled
890914
sym->forceImport = true;
891915
if (sym->traced)
892916
message(toString(stub_file) + ": importing " + name);
@@ -1213,9 +1237,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
12131237
if (errorCount())
12141238
return;
12151239

1216-
// processStubLibraries must happen before LTO because it can trigger the
1217-
// export of arbirary symbols that might themselves be defined in LTO objects.
1218-
processStubLibraries();
1240+
// We process the stub libraries once beofore LTO to ensure that any possible
1241+
// required exports are preserved by the LTO process.
1242+
processStubLibrariesPreLTO();
12191243

12201244
// Do link-time optimization if given files are LLVM bitcode files.
12211245
// This compiles bitcode files into real object files.
@@ -1225,8 +1249,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
12251249

12261250
// The LTO process can generate new undefined symbols, specifically libcall
12271251
// functions. Because those symbols might be declared in a stub library we
1228-
// need the process the stub libraries once again after LTO to handle any
1229-
// newly undefined symbols.
1252+
// need the process the stub libraries once again after LTO to handle all
1253+
// undefined symbols, including ones that didn't exist prior to LTO.
12301254
processStubLibraries();
12311255

12321256
writeWhyExtract();

0 commit comments

Comments
 (0)