[lld] 3736d08 - [ELF] Optimize -z combreloc

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 15 22:33:55 PST 2022


Author: Fangrui Song
Date: 2022-01-15T22:33:51-08:00
New Revision: 3736d0854a003ef7896a23014857a76472128342

URL: https://github.com/llvm/llvm-project/commit/3736d0854a003ef7896a23014857a76472128342
DIFF: https://github.com/llvm/llvm-project/commit/3736d0854a003ef7896a23014857a76472128342.diff

LOG: [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.

Added: 
    

Modified: 
    lld/ELF/SyntheticSections.cpp
    lld/test/ELF/mips-32.s
    lld/test/ELF/mips-64.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index f41459dc70d42..aef6434dca799 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);
     });
   }
 

diff  --git a/lld/test/ELF/mips-32.s b/lld/test/ELF/mips-32.s
index 0a19700fb3dac..61f1dbfbdb8aa 100644
--- a/lld/test/ELF/mips-32.s
+++ b/lld/test/ELF/mips-32.s
@@ -41,8 +41,8 @@ v2:
 # REL-NOT: (RELCOUNT)
 
 # REL: Relocation section
-# REL:      {{.*}} R_MIPS_REL32
-# REL-NEXT: {{.*}} R_MIPS_REL32 [[V2:[0-9a-f]+]]
+# REL:      {{.*}} R_MIPS_REL32 [[V2:[0-9a-f]+]]
+# REL-NEXT: {{.*}} R_MIPS_REL32 {{$}}
 
 # REL: Symbol table
 # REL: {{.*}}: [[V2]] {{.*}} v2

diff  --git a/lld/test/ELF/mips-64.s b/lld/test/ELF/mips-64.s
index f978a550f3704..ebfad068b5724 100644
--- a/lld/test/ELF/mips-64.s
+++ b/lld/test/ELF/mips-64.s
@@ -32,8 +32,8 @@ v2:
 # CHECK: (RELENT)  16 (bytes)
 
 # CHECK: Relocation section
-# CHECK: [[V2:[0-9a-f]+]]  {{.*}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE
-# CHECK: [[V1:[0-9a-f]+]]  {{.*}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE [[V2]] v2
+# CHECK:      [[V1:[0-9a-f]+]]  {{.*}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE [[V2:[0-9a-f]+]] v2
+# CHECK-NEXT: [[V2]]            {{.*}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE {{$}}
 
 # CHECK: Symbol table '.symtab'
 # CHECK: {{.*}}: [[V1]]  {{.*}}  v1


        


More information about the llvm-commits mailing list