summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-03-05 19:25:58 +0000
committerRui Ueyama <ruiu@google.com>2015-03-05 19:25:58 +0000
commite5bf7694432e3253b6d46bbc5d65318373beb5ff (patch)
treea358aba7d7f6c5937f2e81dfe1c09e4f6e1556ec
parentaa1ae6f660491edb0270f0ad833388cdc9776483 (diff)
downloadbcm5719-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.h4
-rw-r--r--lld/lib/Core/Resolver.cpp25
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();
OpenPOWER on IntegriCloud