[PATCH] [lld][Driver] Parallelize reading initial object files.
Michael Spencer
bigcheesegs at gmail.com
Fri Apr 19 17:31:31 PDT 2013
Address comments and split out reader fix.
Hi shankarke, kledzik,
http://llvm-reviews.chandlerc.com/D664
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D664?vs=1614&id=1699#toc
Files:
lib/Driver/Driver.cpp
lib/ReaderWriter/ELF/File.h
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -8,10 +8,12 @@
//===----------------------------------------------------------------------===//
#include "lld/Driver/Driver.h"
+
#include "lld/Core/LLVM.h"
#include "lld/Core/InputFiles.h"
-#include "lld/Core/Resolver.h"
#include "lld/Core/PassManager.h"
+#include "lld/Core/Parallel.h"
+#include "lld/Core/Resolver.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
@@ -39,20 +41,33 @@
}
// Read inputs
- InputFiles inputs;
+ std::vector<std::vector<std::unique_ptr<File>>> files(
+ targetInfo.inputFiles().size());
+ size_t index = 0;
+ std::atomic<bool> fail(false);
+ TaskGroup tg;
for (const auto &input : targetInfo.inputFiles()) {
- std::vector<std::unique_ptr<File>> files;
if (targetInfo.logInputFiles())
llvm::outs() << input.getPath() << "\n";
-
- error_code ec = targetInfo.readFile(input.getPath(), files);
- if (ec) {
- diagnostics << "Failed to read file: " << input.getPath() << ": "
- << ec.message() << "\n";
- return true;
- }
- inputs.appendFiles(files);
+
+ tg.spawn([&, index] {
+ if (error_code ec = targetInfo.readFile(input.getPath(), files[index])) {
+ diagnostics << "Failed to read file: " << input.getPath()
+ << ": " << ec.message() << "\n";
+ fail = true;
+ return;
+ }
+ });
+ ++index;
}
+ tg.sync();
+
+ if (fail)
+ return true;
+
+ InputFiles inputs;
+ for (auto &f : files)
+ inputs.appendFiles(f);
// Give target a chance to add files.
targetInfo.addImplicitFiles(inputs);
Index: lib/ReaderWriter/ELF/File.h
===================================================================
--- lib/ReaderWriter/ELF/File.h
+++ lib/ReaderWriter/ELF/File.h
@@ -114,6 +114,8 @@
typedef std::unordered_map<MergeSectionKey, DefinedAtom *, MergeSectionEq,
MergeSectionEq> MergedSectionMapT;
typedef typename MergedSectionMapT::iterator MergedSectionMapIterT;
+ typedef llvm::DenseMap<const Elf_Shdr *, std::vector<const Elf_Sym *>>
+ SectionSymbolsT;
public:
ELFFile(const ELFTargetInfo &ti, StringRef name)
@@ -140,7 +142,8 @@
binaryFile.take();
- std::map<const Elf_Shdr *, std::vector<const Elf_Sym *> > sectionSymbols;
+ /// \brief Map from sections to a list of symbols that section contains.
+ SectionSymbolsT sectionSymbols;
// Sections that have merge string property
std::vector<const Elf_Shdr *> mergeStringSections;
@@ -308,24 +311,37 @@
}
}
+ // Iterate over sections by object file position. The pointers point into
+ // the memory mapped file, so it's valid to sort based on them.
+ std::vector<typename SectionSymbolsT::value_type *> secSyms;
+ secSyms.reserve(sectionSymbols.size());
for (auto &i : sectionSymbols) {
- auto &symbols = i.second;
+ secSyms.push_back(&i);
+ }
+ std::sort(secSyms.begin(), secSyms.end(),
+ [](const typename SectionSymbolsT::value_type *a,
+ const typename SectionSymbolsT::value_type *b) {
+ return a->first < b->first;
+ });
+
+ for (auto &i : secSyms) {
+ auto &symbols = i->second;
// Sort symbols by position.
std::stable_sort(symbols.begin(), symbols.end(),
[](const Elf_Sym * A, const Elf_Sym * B) {
return A->st_value < B->st_value;
});
StringRef sectionContents;
- if ((EC = _objFile->getSectionContents(i.first, sectionContents)))
+ if ((EC = _objFile->getSectionContents(i->first, sectionContents)))
return;
StringRef sectionName;
- if ((EC = _objFile->getSectionName(i.first, sectionName)))
+ if ((EC = _objFile->getSectionName(i->first, sectionName)))
return;
// If the section has no symbols, create a custom atom for it.
- if (i.first->sh_type == llvm::ELF::SHT_PROGBITS && symbols.empty() &&
+ if (i->first->sh_type == llvm::ELF::SHT_PROGBITS && symbols.empty() &&
!sectionContents.empty()) {
Elf_Sym *sym = new (_readerStorage) Elf_Sym;
sym->st_name = 0;
@@ -337,7 +353,7 @@
ArrayRef<uint8_t> content((const uint8_t *)sectionContents.data(),
sectionContents.size());
auto newAtom = new (_readerStorage)
- ELFDefinedAtom<ELFT>(*this, sectionName, sectionName, sym, i.first,
+ ELFDefinedAtom<ELFT>(*this, sectionName, sectionName, sym, i->first,
content, 0, 0, _references);
newAtom->setOrdinal(++ordinal);
_definedAtoms._atoms.push_back(newAtom);
@@ -350,10 +366,10 @@
ELFReference<ELFT> *anonPrecededBy = nullptr;
ELFReference<ELFT> *anonFollowedBy = nullptr;
- // i.first is the section the symbol lives in
+ // i->first is the section the symbol lives in
for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
StringRef symbolName;
- if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
+ if ((EC = _objFile->getSymbolName(i->first, *si, symbolName)))
return;
const Elf_Shdr *section = _objFile->getSection(*si);
@@ -378,7 +394,7 @@
uint64_t contentSize;
if (si + 1 == se) {
// if this is the last symbol, take up the remaining data.
- contentSize = isCommon ? 0 : i.first->sh_size - (*si)->st_value;
+ contentSize = isCommon ? 0 : i->first->sh_size - (*si)->st_value;
} else {
contentSize = isCommon ? 0 : (*(si + 1))->st_value - (*si)->st_value;
}
@@ -412,7 +428,7 @@
*sym = **si;
sym->setBinding(llvm::ELF::STB_GLOBAL);
anonAtom = createDefinedAtomAndAssignRelocations(
- "", sectionName, sym, i.first,
+ "", sectionName, sym, i->first,
ArrayRef<uint8_t>(
(uint8_t *)sectionContents.data() + (*si)->st_value,
contentSize));
@@ -457,7 +473,7 @@
}
auto newAtom = createDefinedAtomAndAssignRelocations(
- symbolName, sectionName, *si, i.first, symbolData);
+ symbolName, sectionName, *si, i->first, symbolData);
newAtom->setOrdinal(++ordinal);
@@ -584,7 +600,7 @@
(rai.r_offset < symbol->st_value + content.size())))
continue;
bool isMips64EL = _objFile->isMips64EL();
- Kind kind = (Kind) rai.getType(isMips64EL);
+ Reference::Kind kind = (Reference::Kind) rai.getType(isMips64EL);
uint32_t symbolIndex = rai.getSymbol(isMips64EL);
auto *ERef = new (_readerStorage)
ELFReference<ELFT>(&rai, rai.r_offset - symbol->st_value, nullptr,
@@ -598,7 +614,7 @@
if ((ri.r_offset >= symbol->st_value) &&
(ri.r_offset < symbol->st_value + content.size())) {
bool isMips64EL = _objFile->isMips64EL();
- Kind kind = (Kind) ri.getType(isMips64EL);
+ Reference::Kind kind = (Reference::Kind) ri.getType(isMips64EL);
uint32_t symbolIndex = ri.getSymbol(isMips64EL);
auto *ERef = new (_readerStorage)
ELFReference<ELFT>(&ri, ri.r_offset - symbol->st_value, nullptr,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D664.2.patch
Type: text/x-patch
Size: 7453 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130419/f2e48000/attachment.bin>
More information about the llvm-commits
mailing list