<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 17, 2015 at 6:51 PM, Rui Ueyama via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ruiu<br>
Date: Thu Sep 17 20:51:37 2015<br>
New Revision: 247963<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=247963&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=247963&view=rev</a><br>
Log:<br>
COFF: Optimize ICF by not creating temporary vectors.<br>
<br>
Previously, ICF created a vector for each SectionChunk. The vector<br>
contained pointers to successors, which are namely associative sections<br>
and COMDAT relocation targets. The reason I created vectors is because<br>
I thought that that would make section comparison faster.<br>
<br>
It did make the comparison faster. When self-linking, for example, it<br>
saved about 10 ms on each iteration. </blockquote><div><br></div><div>(haven't looked at the algorithm, but just wondering) is there any possibility of keeping them up-to-date cheaply, rather than constructing them on every iteration?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The time we spent on constructing<br>
the vectors was 124 ms. If we iterate more than 12 times, return from<br>
the investment exceeds the initial cost.<br>
<br>
In reality, it usually needs 5 iterations. So we shouldn't construct<br>
the vectors.<br>
<br>
Modified:<br>
    lld/trunk/COFF/Chunks.h<br>
    lld/trunk/COFF/ICF.cpp<br>
<br>
Modified: lld/trunk/COFF/Chunks.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=247963&r1=247962&r2=247963&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=247963&r1=247962&r2=247963&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/COFF/Chunks.h (original)<br>
+++ lld/trunk/COFF/Chunks.h Thu Sep 17 20:51:37 2015<br>
@@ -203,7 +203,6 @@ private:<br>
<br>
   // Used for ICF (Identical COMDAT Folding)<br>
   void replaceWith(SectionChunk *Other);<br>
-  std::vector<SectionChunk *> Successors;<br>
   uint64_t GroupID;<br>
<br>
   // Chunks are basically unnamed chunks of bytes.<br>
<br>
Modified: lld/trunk/COFF/ICF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=247963&r1=247962&r2=247963&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=247963&r1=247962&r2=247963&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/COFF/ICF.cpp (original)<br>
+++ lld/trunk/COFF/ICF.cpp Thu Sep 17 20:51:37 2015<br>
@@ -128,12 +128,22 @@ bool ICF::equalsConstant(const SectionCh<br>
 }<br>
<br>
 bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) {<br>
-  assert(A->Successors.size() == B->Successors.size());<br>
-  return std::equal(A->Successors.begin(), A->Successors.end(),<br>
-                    B->Successors.begin(),<br>
-                    [](const SectionChunk *X, const SectionChunk *Y) {<br>
-                      return X->GroupID == Y->GroupID;<br>
-                    });<br>
+  // Compare associative sections.<br>
+  for (size_t I = 0, E = A->AssocChildren.size(); I != E; ++I)<br>
+    if (A->AssocChildren[I]->GroupID != B->AssocChildren[I]->GroupID)<br>
+      return false;<br>
+<br>
+  // Compare relocations.<br>
+  auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {<br>
+    SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex)->repl();<br>
+    SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex)->repl();<br>
+    if (B1 == B2)<br>
+      return true;<br>
+    auto *D1 = dyn_cast<DefinedRegular>(B1);<br>
+    auto *D2 = dyn_cast<DefinedRegular>(B2);<br>
+    return D1 && D2 && D1->getChunk()->GroupID == D2->getChunk()->GroupID;<br>
+  };<br>
+  return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq);<br>
 }<br>
<br>
 bool ICF::partition(ChunkIterator Begin, ChunkIterator End, Comparator Eq) {<br>
@@ -191,16 +201,6 @@ void ICF::run() {<br>
               return A->GroupID < B->GroupID;<br>
             });<br>
<br>
-  // Initialize chunk successors for equalsVariable.<br>
-  for (SectionChunk *SC : SChunks) {<br>
-    SC->Successors = SC->AssocChildren;<br>
-    for (const coff_relocation &R : SC->Relocs) {<br>
-      SymbolBody *B = SC->File->getSymbolBody(R.SymbolTableIndex)->repl();<br>
-      if (auto D = dyn_cast<DefinedRegular>(B))<br>
-        SC->Successors.push_back(D->getChunk());<br>
-    }<br>
-  }<br>
-<br>
   // Split groups until we get a convergence.<br>
   int Cnt = 1;<br>
   forEachGroup(SChunks, equalsConstant);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>