diff options
| author | Rui Ueyama <ruiu@google.com> | 2015-03-05 19:25:58 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2015-03-05 19:25:58 +0000 |
| commit | e5bf7694432e3253b6d46bbc5d65318373beb5ff (patch) | |
| tree | a358aba7d7f6c5937f2e81dfe1c09e4f6e1556ec | |
| parent | aa1ae6f660491edb0270f0ad833388cdc9776483 (diff) | |
| download | bcm5719-llvm-e5bf7694432e3253b6d46bbc5d65318373beb5ff.tar.gz bcm5719-llvm-e5bf7694432e3253b6d46bbc5d65318373beb5ff.zip | |
Resolver: Update preload map after File::beforeLink().
We maintain a map from symbols to archive files for the archive file
pre-loading. That map is created at the beginning of the resolve()
and is never updated. However, the input file list may be updated by
File::beforeLink(). This is a patch to update the map after beforeLink.
llvm-svn: 231395
| -rw-r--r-- | lld/include/lld/Core/Resolver.h | 4 | ||||
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 25 |
2 files changed, 20 insertions, 9 deletions
diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h index 12948ba1baa..b70b5b58730 100644 --- a/lld/include/lld/Core/Resolver.h +++ b/lld/include/lld/Core/Resolver.h @@ -18,6 +18,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include <set> +#include <unordered_set> #include <vector> namespace lld { @@ -64,7 +65,7 @@ private: void maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom); /// \brief The main function that iterates over the files to resolve - void makePreloadArchiveMap(); + void updatePreloadArchiveMap(); bool resolveUndefines(); void updateReferences(); void deadStripOptimize(); @@ -99,6 +100,7 @@ private: // Preloading std::map<StringRef, ArchiveLibraryFile *> _archiveMap; + std::unordered_set<ArchiveLibraryFile *> _archiveSeen; }; } // namespace lld diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 13b48c7e42e..8b86f59e56e 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -83,6 +83,7 @@ bool Resolver::handleArchiveFile(File &file) { if (File *member = archiveFile->find(undefName, dataSymbolOnly)) { member->setOrdinal(_ctx.getNextOrdinalAndIncrement()); member->beforeLink(); + updatePreloadArchiveMap(); undefAdded = handleFile(*member) || undefAdded; } }); @@ -274,14 +275,21 @@ File *Resolver::getFile(int &index) { return cast<FileNode>(inputs[index++].get())->getFile(); } -// Make a map of Symbol -> ArchiveFile. -void Resolver::makePreloadArchiveMap() { +// Update a map of Symbol -> ArchiveFile. The map is used for speculative +// file loading. +void Resolver::updatePreloadArchiveMap() { std::vector<std::unique_ptr<Node>> &nodes = _ctx.getNodes(); - for (int i = nodes.size() - 1; i >= 0; --i) - if (auto *fnode = dyn_cast<FileNode>(nodes[i].get())) - if (auto *archive = dyn_cast<ArchiveLibraryFile>(fnode->getFile())) - for (StringRef sym : archive->getDefinedSymbols()) - _archiveMap[sym] = archive; + for (int i = nodes.size() - 1; i >= 0; --i) { + auto *fnode = dyn_cast<FileNode>(nodes[i].get()); + if (!fnode) + continue; + auto *archive = dyn_cast<ArchiveLibraryFile>(fnode->getFile()); + if (!archive || _archiveSeen.count(archive)) + continue; + _archiveSeen.insert(archive); + for (StringRef sym : archive->getDefinedSymbols()) + _archiveMap[sym] = archive; + } } // Keep adding atoms until _ctx.getNextFile() returns an error. This @@ -301,6 +309,7 @@ bool Resolver::resolveUndefines() { return false; } file->beforeLink(); + updatePreloadArchiveMap(); switch (file->kind()) { case File::kindObject: // The same file may be visited more than once if the file is @@ -477,7 +486,7 @@ void Resolver::removeCoalescedAwayAtoms() { } bool Resolver::resolve() { - makePreloadArchiveMap(); + updatePreloadArchiveMap(); if (!resolveUndefines()) return false; updateReferences(); |

