Skip to content

Commit 93ceadf

Browse files
committedMar 6, 2015
PECOFF: Optimize the writer using parallel_for.
Previously applying 1 million relocations took about 2 seconds on my Xeon 2.4GHz 8 core workstation. After this patch, it takes about 300 milliseconds. As a result, time to link chrome.dll becomes 23 seconds to 21 seconds. llvm-svn: 231454
1 parent e105ea8 commit 93ceadf

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed
 

‎lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -602,8 +602,9 @@ void AtomChunk::applyRelocationsARM(uint8_t *Buffer,
602602
std::vector<uint64_t> &SectionRVA,
603603
uint64_t ImageBase) {
604604
Buffer = Buffer + _fileOffset;
605-
for (const auto *Layout : _atomLayouts) {
606-
const DefinedAtom *Atom = cast<DefinedAtom>(Layout->_atom);
605+
parallel_for_each(_atomLayouts.begin(), _atomLayouts.end(),
606+
[&](const AtomLayout *layout) {
607+
const DefinedAtom *Atom = cast<DefinedAtom>(layout->_atom);
607608
for (const Reference *R : *Atom) {
608609
if (R->kindNamespace() != Reference::KindNamespace::COFF)
609610
continue;
@@ -614,7 +615,7 @@ void AtomChunk::applyRelocationsARM(uint8_t *Buffer,
614615
Target->permissions() == DefinedAtom::permRWX;
615616

616617
const auto AtomOffset = R->offsetInAtom();
617-
const auto FileOffset = Layout->_fileOffset;
618+
const auto FileOffset = layout->_fileOffset;
618619
const auto TargetAddr = AtomRVA[R->target()] | (AssumeTHUMBCode ? 1 : 0);
619620
auto RelocSite16 =
620621
reinterpret_cast<ulittle16_t *>(Buffer + FileOffset + AtomOffset);
@@ -645,15 +646,16 @@ void AtomChunk::applyRelocationsARM(uint8_t *Buffer,
645646
break;
646647
}
647648
}
648-
}
649+
});
649650
}
650651

651652
void AtomChunk::applyRelocationsX86(uint8_t *buffer,
652653
std::map<const Atom *, uint64_t> &atomRva,
653654
std::vector<uint64_t> &sectionRva,
654655
uint64_t imageBaseAddress) {
655656
buffer += _fileOffset;
656-
for (const auto *layout : _atomLayouts) {
657+
parallel_for_each(_atomLayouts.begin(), _atomLayouts.end(),
658+
[&](const AtomLayout *layout) {
657659
const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
658660
for (const Reference *ref : *atom) {
659661
// Skip if this reference is not for COFF relocation.
@@ -702,15 +704,16 @@ void AtomChunk::applyRelocationsX86(uint8_t *buffer,
702704
llvm::report_fatal_error("Unsupported relocation kind");
703705
}
704706
}
705-
}
707+
});
706708
}
707709

708710
void AtomChunk::applyRelocationsX64(uint8_t *buffer,
709711
std::map<const Atom *, uint64_t> &atomRva,
710712
std::vector<uint64_t> &sectionRva,
711713
uint64_t imageBase) {
712714
buffer += _fileOffset;
713-
for (const auto *layout : _atomLayouts) {
715+
parallel_for_each(_atomLayouts.begin(), _atomLayouts.end(),
716+
[&](const AtomLayout *layout) {
714717
const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
715718
for (const Reference *ref : *atom) {
716719
if (ref->kindNamespace() != Reference::KindNamespace::COFF)
@@ -762,7 +765,7 @@ void AtomChunk::applyRelocationsX64(uint8_t *buffer,
762765
llvm::report_fatal_error("Unsupported relocation kind");
763766
}
764767
}
765-
}
768+
});
766769
}
767770

768771
/// Print atom VAs. Used only for debugging.

0 commit comments

Comments
 (0)