[lld] r287466 - Refactor ICF.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 19 15:14:23 PST 2016


Author: ruiu
Date: Sat Nov 19 17:14:23 2016
New Revision: 287466

URL: http://llvm.org/viewvc/llvm-project?rev=287466&view=rev
Log:
Refactor ICF.

In order to use forEachGroup in the final loop in ICF::run,
I changed some function parameter types.

Modified:
    lld/trunk/ELF/ICF.cpp

Modified: lld/trunk/ELF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=287466&r1=287465&r2=287466&view=diff
==============================================================================
--- lld/trunk/ELF/ICF.cpp (original)
+++ lld/trunk/ELF/ICF.cpp Sat Nov 19 17:14:23 2016
@@ -95,10 +95,11 @@ private:
   static bool isEligible(InputSectionBase<ELFT> *Sec);
   static std::vector<InputSection<ELFT> *> getSections();
 
-  void segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
-                 Comparator Eq);
+  void segregate(MutableArrayRef<InputSection<ELFT> *> Arr, Comparator Eq);
 
-  void forEachGroup(std::vector<InputSection<ELFT> *> &V, Comparator Eq);
+  void
+  forEachGroup(std::vector<InputSection<ELFT> *> &V,
+               std::function<void(MutableArrayRef<InputSection<ELFT> *>)> Fn);
 
   template <class RelTy>
   static bool relocationEq(ArrayRef<RelTy> RA, ArrayRef<RelTy> RB);
@@ -153,18 +154,18 @@ std::vector<InputSection<ELFT> *> ICF<EL
 // you call this function. This function compare sections between Begin
 // and End using Eq and assign new group IDs for new groups.
 template <class ELFT>
-void ICF<ELFT>::segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
+void ICF<ELFT>::segregate(MutableArrayRef<InputSection<ELFT> *> Arr,
                           Comparator Eq) {
   // This loop rearranges [Begin, End) so that all sections that are
   // equal in terms of Eq are contiguous. The algorithm is quadratic in
   // the worst case, but that is not an issue in practice because the
   // number of distinct sections in [Begin, End) is usually very small.
-  InputSection<ELFT> **I = Begin;
+  InputSection<ELFT> **I = Arr.begin();
   for (;;) {
     InputSection<ELFT> *Head = *I;
     auto Bound = std::stable_partition(
-        I + 1, End, [&](InputSection<ELFT> *S) { return Eq(Head, S); });
-    if (Bound == End)
+        I + 1, Arr.end(), [&](InputSection<ELFT> *S) { return Eq(Head, S); });
+    if (Bound == Arr.end())
       return;
     uint64_t Id = NextId++;
     for (; I != Bound; ++I)
@@ -173,14 +174,15 @@ void ICF<ELFT>::segregate(InputSection<E
 }
 
 template <class ELFT>
-void ICF<ELFT>::forEachGroup(std::vector<InputSection<ELFT> *> &V,
-                             Comparator Eq) {
+void ICF<ELFT>::forEachGroup(
+    std::vector<InputSection<ELFT> *> &V,
+    std::function<void(MutableArrayRef<InputSection<ELFT> *>)> Fn) {
   for (InputSection<ELFT> **I = V.data(), **E = I + V.size(); I != E;) {
     InputSection<ELFT> *Head = *I;
     auto Bound = std::find_if(I + 1, E, [&](InputSection<ELFT> *S) {
       return S->GroupId != Head->GroupId;
     });
-    segregate(I, Bound, Eq);
+    Fn({I, Bound});
     I = Bound;
   }
 }
@@ -259,14 +261,14 @@ template <class ELFT> void ICF<ELFT>::ru
   // Initially, we use hash values as section group IDs. Therefore,
   // if two sections have the same ID, they are likely (but not
   // guaranteed) to have the same static contents in terms of ICF.
-  std::vector<InputSection<ELFT> *> V = getSections();
-  for (InputSection<ELFT> *S : V)
+  std::vector<InputSection<ELFT> *> Sections = getSections();
+  for (InputSection<ELFT> *S : Sections)
     // Set MSB on to avoid collisions with serial group IDs
     S->GroupId = getHash(S) | (uint64_t(1) << 63);
 
   // From now on, sections in V are ordered so that sections in
   // the same group are consecutive in the vector.
-  std::stable_sort(V.begin(), V.end(),
+  std::stable_sort(Sections.begin(), Sections.end(),
                    [](InputSection<ELFT> *A, InputSection<ELFT> *B) {
                      if (A->GroupId != B->GroupId)
                        return A->GroupId < B->GroupId;
@@ -276,34 +278,32 @@ template <class ELFT> void ICF<ELFT>::ru
                    });
 
   // Compare static contents and assign unique IDs for each static content.
-  forEachGroup(V, equalsConstant);
+  forEachGroup(Sections, [&](MutableArrayRef<InputSection<ELFT> *> V) {
+    segregate(V, equalsConstant);
+  });
 
   // Split groups by comparing relocations until we get a convergence.
   int Cnt = 1;
   for (;;) {
     ++Cnt;
     uint64_t Id = NextId;
-    forEachGroup(V, equalsVariable);
+    forEachGroup(Sections, [&](MutableArrayRef<InputSection<ELFT> *> V) {
+      segregate(V, equalsVariable);
+    });
     if (Id == NextId)
       break;
   }
   log("ICF needed " + Twine(Cnt) + " iterations.");
 
   // Merge sections in the same group.
-  for (auto I = V.begin(), E = V.end(); I != E;) {
-    InputSection<ELFT> *Head = *I++;
-    auto Bound = std::find_if(I, E, [&](InputSection<ELFT> *S) {
-      return Head->GroupId != S->GroupId;
-    });
-    if (I == Bound)
-      continue;
+  forEachGroup(Sections, [&](MutableArrayRef<InputSection<ELFT> *> V) {
+    InputSection<ELFT> *Head = V[0];
     log("selected " + Head->Name);
-    while (I != Bound) {
-      InputSection<ELFT> *S = *I++;
+    for (InputSection<ELFT> *S : V.slice(1)) {
       log("  removed " + S->Name);
       Head->replace(S);
     }
-  }
+  });
 }
 
 // ICF entry point function.




More information about the llvm-commits mailing list