<div dir="ltr">Sure, I have an idea to completely remove binary search from here. I'll try it first.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 25, 2016 at 9:51 AM, Sean Silva <span dir="ltr"><<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Seems fine. If you are making the Size field only 31 bits then you might as well make InputOff 32 bits as well so SectionPiece is 24 bytes instead of 32 bytes.<br></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 25, 2016 at 9:37 AM, 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: Wed May 25 11:37:01 2016<br>
New Revision: 270717<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=270717&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=270717&view=rev</a><br>
Log:<br>
Make SectionPiece 8 bytes smaller on LP64.<br>
<br>
This patch makes SectionPiece class 8 bytes smaller on platforms<br>
on which pointer size is 8 bytes. Sean suggested in a post commit<br>
review for r270340 that this could make a differentce, and it<br>
actually is. Time to link clang (with debug info) improved from<br>
6.725 seconds to 6.589 seconds or by about 2%.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D20613" rel="noreferrer" target="_blank">http://reviews.llvm.org/D20613</a><br>
<br>
Modified:<br>
    lld/trunk/ELF/InputSection.h<br>
    lld/trunk/ELF/OutputSections.cpp<br>
<br>
Modified: lld/trunk/ELF/InputSection.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=270717&r1=270716&r2=270717&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=270717&r1=270716&r2=270717&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputSection.h (original)<br>
+++ lld/trunk/ELF/InputSection.h Wed May 25 11:37:01 2016<br>
@@ -87,13 +87,24 @@ template <class ELFT> InputSectionBase<E<br>
 // SectionPiece represents a piece of splittable section contents.<br>
 struct SectionPiece {<br>
   SectionPiece(size_t Off, ArrayRef<uint8_t> Data)<br>
-      : InputOff(Off), Data(Data), Live(!Config->GcSections) {}<br>
-  size_t size() const { return Data.size(); }<br>
+      : InputOff(Off), Data((uint8_t *)Data.data()), Size(Data.size()),<br>
+        Live(!Config->GcSections) {}<br>
+<br>
+  ArrayRef<uint8_t> data() { return {Data, Size}; }<br>
+  size_t size() const { return Size; }<br>
<br>
   size_t InputOff;<br>
   size_t OutputOff = -1;<br>
-  ArrayRef<uint8_t> Data; // slice of the input section<br>
-  bool Live;<br>
+<br>
+private:<br>
+  // We use bitfields because SplitInputSection is accessed by<br>
+  // std::upper_bound very often.<br>
+  // We want to save bits to make it cache friendly.<br>
+  uint8_t *Data;<br>
+  uint32_t Size : 31;<br>
+<br>
+public:<br>
+  uint32_t Live : 1;<br>
 };<br>
<br>
 // Usually sections are copied to the output as atomic chunks of data,<br>
<br>
Modified: lld/trunk/ELF/OutputSections.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=270717&r1=270716&r2=270717&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=270717&r1=270716&r2=270717&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/OutputSections.cpp (original)<br>
+++ lld/trunk/ELF/OutputSections.cpp Wed May 25 11:37:01 2016<br>
@@ -946,7 +946,7 @@ CieRecord *EhOutputSection<ELFT>::addCie<br>
                                          EhInputSection<ELFT> *Sec,<br>
                                          ArrayRef<RelTy> &Rels) {<br>
   const endianness E = ELFT::TargetEndianness;<br>
-  if (read32<E>(Piece.Data.data() + 4) != 0)<br>
+  if (read32<E>(Piece.data().data() + 4) != 0)<br>
     fatal("CIE expected at beginning of .eh_frame: " + Sec->getSectionName());<br>
<br>
   SymbolBody *Personality = nullptr;<br>
@@ -954,7 +954,7 @@ CieRecord *EhOutputSection<ELFT>::addCie<br>
     Personality = &Sec->getFile()->getRelocTargetSym(*Rel);<br>
<br>
   // Search for an existing CIE by CIE contents/relocation target pair.<br>
-  CieRecord *Cie = &CieMap[{Piece.Data, Personality}];<br>
+  CieRecord *Cie = &CieMap[{Piece.data(), Personality}];<br>
<br>
   // If not found, create a new one.<br>
   if (Cie->Piece == nullptr) {<br>
@@ -995,11 +995,11 @@ void EhOutputSection<ELFT>::addSectionAu<br>
   DenseMap<size_t, CieRecord *> OffsetToCie;<br>
   for (SectionPiece &Piece : Sec->Pieces) {<br>
     // The empty record is the end marker.<br>
-    if (Piece.Data.size() == 4)<br>
+    if (Piece.size() == 4)<br>
       return;<br>
<br>
     size_t Offset = Piece.InputOff;<br>
-    uint32_t ID = read32<E>(Piece.Data.data() + 4);<br>
+    uint32_t ID = read32<E>(Piece.data().data() + 4);<br>
     if (ID == 0) {<br>
       OffsetToCie[Offset] = addCie(Piece, Sec, Rels);<br>
       continue;<br>
@@ -1106,11 +1106,11 @@ template <class ELFT> void EhOutputSecti<br>
   const endianness E = ELFT::TargetEndianness;<br>
   for (CieRecord *Cie : Cies) {<br>
     size_t CieOffset = Cie->Piece->OutputOff;<br>
-    writeCieFde<ELFT>(Buf + CieOffset, Cie->Piece->Data);<br>
+    writeCieFde<ELFT>(Buf + CieOffset, Cie->Piece->data());<br>
<br>
     for (SectionPiece *Fde : Cie->FdePieces) {<br>
       size_t Off = Fde->OutputOff;<br>
-      writeCieFde<ELFT>(Buf + Off, Fde->Data);<br>
+      writeCieFde<ELFT>(Buf + Off, Fde->data());<br>
<br>
       // FDE's second word should have the offset to an associated CIE.<br>
       // Write it.<br>
@@ -1126,7 +1126,7 @@ template <class ELFT> void EhOutputSecti<br>
   // we obtain two addresses and pass them to EhFrameHdr object.<br>
   if (Out<ELFT>::EhFrameHdr) {<br>
     for (CieRecord *Cie : Cies) {<br>
-      uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece->Data);<br>
+      uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece->data());<br>
       for (SectionPiece *Fde : Cie->FdePieces) {<br>
         uintX_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);<br>
         uintX_t FdeVA = this->getVA() + Fde->OutputOff;<br>
@@ -1170,7 +1170,7 @@ void MergeOutputSection<ELFT>::addSectio<br>
   for (SectionPiece &Piece : Sec->Pieces) {<br>
     if (!Piece.Live)<br>
       continue;<br>
-    uintX_t OutputOffset = Builder.add(toStringRef(Piece.Data));<br>
+    uintX_t OutputOffset = Builder.add(toStringRef(Piece.data()));<br>
     if (!IsString || !shouldTailMerge())<br>
       Piece.OutputOff = OutputOffset;<br>
   }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">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></div></blockquote></div><br></div>