[lld] r347429 - COFF: ICF: Include contents of referenced sections in initial partitioning hash. NFCI.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 21 13:29:35 PST 2018


Author: pcc
Date: Wed Nov 21 13:29:35 2018
New Revision: 347429

URL: http://llvm.org/viewvc/llvm-project?rev=347429&view=rev
Log:
COFF: ICF: Include contents of referenced sections in initial partitioning hash. NFCI.

Previously we were taking over 13 minutes to link Firefox's xul.dll
on ARM64; this reduces link time to around 18s on my machine.

The root cause of the problem was that all of the input .pdata sections
had the same unrelocated section data and therefore the same hash,
which made segregation quadratic in the number of .pdata sections. The
reason why we weren't observing this on other architectures was that
ARM has a different .pdata format. On non-ARM the format is (start
address, end address, .xdata), which caused the size of the function
to appear in the unrelocated section data where the end address field
is. However, the ARM format omits the end address field.

Fixes PR39667.

Differential Revision: https://reviews.llvm.org/D54809

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=347429&r1=347428&r2=347429&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Wed Nov 21 13:29:35 2018
@@ -262,8 +262,18 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
 
   // Initially, we use hash values to partition sections.
   for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) {
+    SC->Class[1] = xxHash64(SC->getContents());
+  });
+
+  // Combine the hashes of the sections referenced by each section into its
+  // hash.
+  for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) {
+    uint32_t Hash = SC->Class[1];
+    for (Symbol *B : SC->symbols())
+      if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
+        Hash ^= Sym->getChunk()->Class[1];
     // Set MSB to 1 to avoid collisions with non-hash classs.
-    SC->Class[0] = xxHash64(SC->getContents()) | (1 << 31);
+    SC->Class[0] = Hash | (1U << 31);
   });
 
   // From now on, sections in Chunks are ordered so that sections in




More information about the llvm-commits mailing list