[lld] r247961 - COFF: Optimize ICF by comparing relocations before section contents.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 18:30:57 PDT 2015


Author: ruiu
Date: Thu Sep 17 20:30:56 2015
New Revision: 247961

URL: http://llvm.org/viewvc/llvm-project?rev=247961&view=rev
Log:
COFF: Optimize ICF by comparing relocations before section contents.

equalsConstants() is the heaviest function in ICF, and that consumes
more than half of total ICF execution time. Of which, section content
comparison accounts for roughly one third.

Previously, we compared section contents at the beginning of the
function after comparing their checksums. The comparison is very
likely to succeed because when the control reaches that comparison,
their checksums are always equal. And because checksums are 64-bit
CRC, they are unlikely to collide.

We compared relocations and associative sections after that.
If they are different, the time we spent on byte-by-byte comparison
of section contents were wasted.

This patch moves the comparison at the end of function. If the
comparison fails, the time we spent on relocation comparison are
wasted, but as I wrote it's very unlikely to happen.

LLD took 1198 ms to link itself to produce a 27.11 MB executable.
Of which, ICF accounted for 536 ms. This patch cuts it by 90 ms,
which is 17% speedup of ICF and 7.5% speedup overall. All numbers
are median of ten runs.

Modified:
    lld/trunk/COFF/ICF.cpp

Modified: lld/trunk/COFF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=247961&r1=247960&r2=247961&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Thu Sep 17 20:30:56 2015
@@ -95,16 +95,16 @@ bool ICF::equalsConstant(const SectionCh
       A->Header->SizeOfRawData != B->Header->SizeOfRawData ||
       A->NumRelocs != B->NumRelocs ||
       A->Checksum != B->Checksum ||
-      A->AssocChildren.size() != B->AssocChildren.size() ||
-      A->getContents() != B->getContents()) {
+      A->AssocChildren.size() != B->AssocChildren.size()) {
     return false;
   }
 
+  // Compare associative sections.
   for (size_t I = 0, E = A->AssocChildren.size(); I != E; ++I)
     if (A->AssocChildren[I]->GroupID != B->AssocChildren[I]->GroupID)
       return false;
 
-  // Compare relocations
+  // Compare relocations.
   auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
     if (R1.Type != R2.Type ||
         R1.VirtualAddress != R2.VirtualAddress) {
@@ -120,7 +120,11 @@ bool ICF::equalsConstant(const SectionCh
            D1->getValue() == D2->getValue() &&
            D1->getChunk()->GroupID == D2->getChunk()->GroupID;
   };
-  return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq);
+  if (!std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq))
+    return false;
+
+  // Compare section contents.
+  return A->getContents() == B->getContents();
 }
 
 bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) {




More information about the llvm-commits mailing list