[lld] r303801 - Close the gap between ELF and COFF ICF implementations. NFC.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed May 24 12:56:29 PDT 2017


Author: ruiu
Date: Wed May 24 14:56:29 2017
New Revision: 303801

URL: http://llvm.org/viewvc/llvm-project?rev=303801&view=rev
Log:
Close the gap between ELF and COFF ICF implementations. NFC.

We originally wrote the ICF code for COFF and ported it to ELF.
They started diverging since then. This patch closes the gap.

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=303801&r1=303800&r2=303801&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Wed May 24 14:56:29 2017
@@ -56,7 +56,6 @@ private:
 
   std::vector<SectionChunk *> Chunks;
   int Cnt = 0;
-  std::atomic<uint32_t> NextId = {1};
   std::atomic<bool> Repeat = {false};
 };
 
@@ -98,10 +97,10 @@ void ICF::segregate(size_t Begin, size_t
         });
     size_t Mid = Bound - Chunks.begin();
 
-    // Split [Begin, End) into [Begin, Mid) and [Mid, End).
-    uint32_t Id = NextId++;
+    // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an
+    // equivalence class ID because every group ends with a unique index.
     for (size_t I = Begin; I < Mid; ++I)
-      Chunks[I]->Class[(Cnt + 1) % 2] = Id;
+      Chunks[I]->Class[(Cnt + 1) % 2] = Mid;
 
     // If we created a group, we need to iterate the main loop again.
     if (Mid != End)
@@ -186,6 +185,7 @@ void ICF::forEachClass(std::function<voi
   // call Fn sequentially.
   if (Chunks.size() < 1024) {
     forEachClassRange(0, Chunks.size(), Fn);
+    ++Cnt;
     return;
   }
 
@@ -196,6 +196,7 @@ void ICF::forEachClass(std::function<voi
     size_t End = (I == NumShards - 1) ? Chunks.size() : (I + 1) * Step;
     forEachClassRange(I * Step, End, Fn);
   });
+  ++Cnt;
 }
 
 // Merge identical COMDAT sections.
@@ -203,22 +204,15 @@ void ICF::forEachClass(std::function<voi
 // contents and relocations are all the same.
 void ICF::run(const std::vector<Chunk *> &Vec) {
   // Collect only mergeable sections and group by hash value.
-  for (Chunk *C : Vec) {
-    auto *SC = dyn_cast<SectionChunk>(C);
-    if (!SC)
-      continue;
-
-    if (isEligible(SC)) {
-      // Set MSB to 1 to avoid collisions with non-hash classs.
-      SC->Class[0] = getHash(SC) | (1 << 31);
-      Chunks.push_back(SC);
-    } else {
-      SC->Class[0] = NextId++;
-    }
-  }
-
-  if (Chunks.empty())
-    return;
+  for (Chunk *C : Vec)
+    if (auto *SC = dyn_cast<SectionChunk>(C))
+      if (isEligible(SC))
+        Chunks.push_back(SC);
+
+  // Initially, we use hash values to partition sections.
+  for (SectionChunk *SC : Chunks)
+    // Set MSB to 1 to avoid collisions with non-hash classs.
+    SC->Class[0] = getHash(SC) | (1 << 31);
 
   // From now on, sections in Chunks are ordered so that sections in
   // the same group are consecutive in the vector.
@@ -229,14 +223,12 @@ void ICF::run(const std::vector<Chunk *>
 
   // Compare static contents and assign unique IDs for each static content.
   forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
-  ++Cnt;
 
   // Split groups by comparing relocations until convergence is obtained.
   do {
     Repeat = false;
     forEachClass(
         [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
-    ++Cnt;
   } while (Repeat);
 
   log("ICF needed " + Twine(Cnt) + " iterations");




More information about the llvm-commits mailing list