Make SectionPiece 8 bytes smaller on LP64.

This patch makes SectionPiece class 8 bytes smaller on platforms
on which pointer size is 8 bytes. Sean suggested in a post commit
review for r270340 that this could make a differentce, and it
actually is. Time to link clang (with debug info) improved from
6.725 seconds to 6.589 seconds or by about 2%.

Differential Revision: http://reviews.llvm.org/D20613

llvm-svn: 270717
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 028c3be..2c3d3ac 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -87,13 +87,24 @@
 // SectionPiece represents a piece of splittable section contents.
 struct SectionPiece {
   SectionPiece(size_t Off, ArrayRef<uint8_t> Data)
-      : InputOff(Off), Data(Data), Live(!Config->GcSections) {}
-  size_t size() const { return Data.size(); }
+      : InputOff(Off), Data((uint8_t *)Data.data()), Size(Data.size()),
+        Live(!Config->GcSections) {}
+
+  ArrayRef<uint8_t> data() { return {Data, Size}; }
+  size_t size() const { return Size; }
 
   size_t InputOff;
   size_t OutputOff = -1;
-  ArrayRef<uint8_t> Data; // slice of the input section
-  bool Live;
+
+private:
+  // We use bitfields because SplitInputSection is accessed by
+  // std::upper_bound very often.
+  // We want to save bits to make it cache friendly.
+  uint8_t *Data;
+  uint32_t Size : 31;
+
+public:
+  uint32_t Live : 1;
 };
 
 // Usually sections are copied to the output as atomic chunks of data,
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index d10488c..77dce45 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -946,7 +946,7 @@
                                          EhInputSection<ELFT> *Sec,
                                          ArrayRef<RelTy> &Rels) {
   const endianness E = ELFT::TargetEndianness;
-  if (read32<E>(Piece.Data.data() + 4) != 0)
+  if (read32<E>(Piece.data().data() + 4) != 0)
     fatal("CIE expected at beginning of .eh_frame: " + Sec->getSectionName());
 
   SymbolBody *Personality = nullptr;
@@ -954,7 +954,7 @@
     Personality = &Sec->getFile()->getRelocTargetSym(*Rel);
 
   // Search for an existing CIE by CIE contents/relocation target pair.
-  CieRecord *Cie = &CieMap[{Piece.Data, Personality}];
+  CieRecord *Cie = &CieMap[{Piece.data(), Personality}];
 
   // If not found, create a new one.
   if (Cie->Piece == nullptr) {
@@ -995,11 +995,11 @@
   DenseMap<size_t, CieRecord *> OffsetToCie;
   for (SectionPiece &Piece : Sec->Pieces) {
     // The empty record is the end marker.
-    if (Piece.Data.size() == 4)
+    if (Piece.size() == 4)
       return;
 
     size_t Offset = Piece.InputOff;
-    uint32_t ID = read32<E>(Piece.Data.data() + 4);
+    uint32_t ID = read32<E>(Piece.data().data() + 4);
     if (ID == 0) {
       OffsetToCie[Offset] = addCie(Piece, Sec, Rels);
       continue;
@@ -1106,11 +1106,11 @@
   const endianness E = ELFT::TargetEndianness;
   for (CieRecord *Cie : Cies) {
     size_t CieOffset = Cie->Piece->OutputOff;
-    writeCieFde<ELFT>(Buf + CieOffset, Cie->Piece->Data);
+    writeCieFde<ELFT>(Buf + CieOffset, Cie->Piece->data());
 
     for (SectionPiece *Fde : Cie->FdePieces) {
       size_t Off = Fde->OutputOff;
-      writeCieFde<ELFT>(Buf + Off, Fde->Data);
+      writeCieFde<ELFT>(Buf + Off, Fde->data());
 
       // FDE's second word should have the offset to an associated CIE.
       // Write it.
@@ -1126,7 +1126,7 @@
   // we obtain two addresses and pass them to EhFrameHdr object.
   if (Out<ELFT>::EhFrameHdr) {
     for (CieRecord *Cie : Cies) {
-      uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece->Data);
+      uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece->data());
       for (SectionPiece *Fde : Cie->FdePieces) {
         uintX_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
         uintX_t FdeVA = this->getVA() + Fde->OutputOff;
@@ -1170,7 +1170,7 @@
   for (SectionPiece &Piece : Sec->Pieces) {
     if (!Piece.Live)
       continue;
-    uintX_t OutputOffset = Builder.add(toStringRef(Piece.Data));
+    uintX_t OutputOffset = Builder.add(toStringRef(Piece.data()));
     if (!IsString || !shouldTailMerge())
       Piece.OutputOff = OutputOffset;
   }