aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/SyntheticSections.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2022-01-15 22:33:51 -0800
committerFangrui Song <i@maskray.me>2022-01-15 22:33:51 -0800
commit3736d0854a003ef7896a23014857a76472128342 (patch)
tree6d2238bb88cdcba320a288bbda94b1cc8dbaffe2 /lld/ELF/SyntheticSections.cpp
parent89e968fe8e12f4b83ed911d06650a5b03c0509da (diff)
downloadllvm-3736d0854a003ef7896a23014857a76472128342.zip
llvm-3736d0854a003ef7896a23014857a76472128342.tar.gz
llvm-3736d0854a003ef7896a23014857a76472128342.tar.bz2
[ELF] Optimize -z combreloc
Sorting dynamic relocations is a bottleneck. Simplifying the comparator improves performance. Linking clang is 4~5% faster with --threads=8. This change may shuffle R_MIPS_REL32 for Mips and is a NFC for non-Mips.
Diffstat (limited to 'lld/ELF/SyntheticSections.cpp')
-rw-r--r--lld/ELF/SyntheticSections.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index f41459d..aef6434 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -1709,9 +1709,14 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
// is to make results easier to read.
if (sort) {
const RelType relativeRel = target->relativeRel;
- parallelSort(relocs, [&](const DynamicReloc &a, const DynamicReloc &b) {
- return std::make_tuple(a.type != relativeRel, a.r_sym, a.r_offset) <
- std::make_tuple(b.type != relativeRel, b.r_sym, b.r_offset);
+ auto nonRelative =
+ std::stable_partition(relocs.begin(), relocs.end(),
+ [=](auto &r) { return r.type == relativeRel; });
+ parallelSort(relocs.begin(), nonRelative,
+ [&](auto &a, auto &b) { return a.r_offset < b.r_offset; });
+ // Non-relative relocations are few, so don't bother with parallelSort.
+ std::sort(nonRelative, relocs.end(), [&](auto &a, auto &b) {
+ return std::tie(a.r_sym, a.r_offset) < std::tie(b.r_sym, b.r_offset);
});
}