diff options
author | Sam Clegg <sbc@chromium.org> | 2023-04-13 11:41:27 -0700 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2023-04-13 20:32:05 -0700 |
commit | d43f0889dd5415ca43e246c6a44d688aec454ec6 (patch) | |
tree | 79f5dcc4c1bef2c579aff6a4640e59186acba9d6 /lld/wasm | |
parent | fd5d0a88dde007728004e43cb28f3c8c0be7b97c (diff) | |
download | llvm-d43f0889dd5415ca43e246c6a44d688aec454ec6.zip llvm-d43f0889dd5415ca43e246c6a44d688aec454ec6.tar.gz llvm-d43f0889dd5415ca43e246c6a44d688aec454ec6.tar.bz2 |
[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: https://github.com/emscripten-core/emscripten/pull/18905
Differential Revision: https://reviews.llvm.org/D148287
Diffstat (limited to 'lld/wasm')
-rw-r--r-- | lld/wasm/Driver.cpp | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 8b02c9a..baca939 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -874,6 +874,28 @@ static void createOptionalSymbols() { WasmSym::tlsBase = createOptionalGlobal("__tls_base", false); } +static void processStubLibrariesPreLTO() { + log("-- processStubLibrariesPreLTO"); + 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 the symbol is not present at all (yet), or if it is present but + // undefined, then mark the dependent symbols as used by a regular + // object so they will be preserved and exported by the LTO process. + if (!sym || sym->isUndefined()) { + for (const auto dep : deps) { + auto* needed = symtab->find(dep); + if (needed ) { + needed->isUsedInRegularObj = true; + } + } + } + } + } +} + static void processStubLibraries() { log("-- processStubLibraries"); for (auto &stub_file : symtab->stubFiles) { @@ -881,12 +903,14 @@ static void processStubLibraries() { << "processing stub file: " << stub_file->getName() << "\n"); for (auto [name, deps]: stub_file->symbolDependencies) { auto* sym = symtab->find(name); - if (!sym || !sym->isUndefined() || sym->forceImport) { - LLVM_DEBUG(llvm::dbgs() << "stub not in needed: " << name << "\n"); + 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); @@ -1213,9 +1237,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { if (errorCount()) return; - // processStubLibraries must happen before LTO because it can trigger the - // export of arbirary symbols that might themselves be defined in LTO objects. - processStubLibraries(); + // We process the stub libraries once beofore LTO to ensure that any possible + // required exports are preserved by the LTO process. + processStubLibrariesPreLTO(); // Do link-time optimization if given files are LLVM bitcode files. // This compiles bitcode files into real object files. @@ -1225,8 +1249,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) { // The LTO process can generate new undefined symbols, specifically libcall // functions. Because those symbols might be declared in a stub library we - // need the process the stub libraries once again after LTO to handle any - // newly undefined symbols. + // need the process the stub libraries once again after LTO to handle all + // undefined symbols, including ones that didn't exist prior to LTO. processStubLibraries(); writeWhyExtract(); |