diff options
author | Rui Ueyama <ruiu@google.com> | 2016-05-25 16:37:01 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2016-05-25 16:37:01 +0000 |
commit | d884927463d772adbbbf1073b2a3187c2a82d5b0 (patch) | |
tree | 960ecba6f2fa3e900d30a6e43360b05935f75c1c | |
parent | bf9d1aa9310dd3fbb53b885469cdf3dc87e85480 (diff) | |
download | bcm5719-llvm-d884927463d772adbbbf1073b2a3187c2a82d5b0.tar.gz bcm5719-llvm-d884927463d772adbbbf1073b2a3187c2a82d5b0.zip |
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
-rw-r--r-- | lld/ELF/InputSection.h | 19 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 16 |
2 files changed, 23 insertions, 12 deletions
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 028c3be8ae9..2c3d3ac1b01 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -87,13 +87,24 @@ template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded; // 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 d10488cf58d..77dce452291 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -946,7 +946,7 @@ CieRecord *EhOutputSection<ELFT>::addCie(SectionPiece &Piece, 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 @@ CieRecord *EhOutputSection<ELFT>::addCie(SectionPiece &Piece, 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 @@ void EhOutputSection<ELFT>::addSectionAux(EhInputSection<ELFT> *Sec, 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 @@ template <class ELFT> void EhOutputSection<ELFT>::writeTo(uint8_t *Buf) { 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 @@ template <class ELFT> void EhOutputSection<ELFT>::writeTo(uint8_t *Buf) { // 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 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { 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; } |