summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-10-05 19:36:02 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-10-05 19:36:02 +0000
commit5fc2b1d2feb023ceb4d60dc5bff63e88cf0c246c (patch)
treee94b031daf5efcf65d47598b6d0980726b2cdb16
parentd799d28540921986e2d336073c535d192c7bcebc (diff)
downloadbcm5719-llvm-5fc2b1d2feb023ceb4d60dc5bff63e88cf0c246c.tar.gz
bcm5719-llvm-5fc2b1d2feb023ceb4d60dc5bff63e88cf0c246c.zip
Store the hash in SectionPiece.
This spreads out computing the hash and using it in a hash table. The speedups are: firefox master 6.811232891 patch 6.559280249 1.03841162939x faster chromium master 4.369323666 patch 4.33171853 1.00868134338x faster chromium fast master 1.856679971 patch 1.850617741 1.00327578725x faster the gold plugin master 0.32917962 patch 0.325711944 1.01064645023x faster clang master 0.558015452 patch 0.550284165 1.01404962652x faster llvm-as master 0.032563515 patch 0.032152077 1.01279662275x faster the gold plugin fsds master 0.356221362 patch 0.352772162 1.00977741549x faster clang fsds master 0.635096494 patch 0.627249229 1.01251060127x faster llvm-as fsds master 0.030183188 patch 0.029889544 1.00982430511x faster scylla master 3.071448906 patch 2.938484138 1.04524944215x faster This seems to be because we don't stall as much. When linking firefox stalled-cycles-frontend goes from 57.56% to 55.55%. With -O2 the difference is even more significant since we avoid recomputing the hash. For firefox we go from 9.990295265 to 9.149627521 seconds (1.09x faster). llvm-svn: 283367
-rw-r--r--lld/ELF/InputSection.cpp3
-rw-r--r--lld/ELF/InputSection.h9
-rw-r--r--lld/ELF/OutputSections.cpp6
-rw-r--r--lld/ELF/OutputSections.h2
4 files changed, 14 insertions, 6 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 1e9e96eb631..d709626722e 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -644,7 +644,8 @@ template <class ELFT> void MergeInputSection<ELFT>::finalizePieces() {
auto *OutSec = static_cast<MergeOutputSection<ELFT> *>(this->OutSec);
ArrayRef<uint8_t> D = this->getData(Piece);
StringRef S((const char *)D.data(), D.size());
- Piece.OutputOff = OutSec->getOffset(S);
+ CachedHashString V(S, Piece.Hash);
+ Piece.OutputOff = OutSec->getOffset(V);
}
OffsetMap[Piece.InputOff] = Piece.OutputOff;
}
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index b5ff603a87c..b3c7f689795 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -124,14 +124,19 @@ 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, uint32_t Hash, bool Live)
+ : InputOff(Off), Hash(Hash), Size(Data.size()),
+ Live(Live || !Config->GcSections) {}
SectionPiece(size_t Off, ArrayRef<uint8_t> Data, bool Live = false)
- : InputOff(Off), Size(Data.size()), Live(Live || !Config->GcSections) {}
+ : SectionPiece(Off, Data, hash_value(Data), Live) {}
size_t size() const { return Size; }
size_t InputOff;
size_t OutputOff = -1;
+ uint32_t Hash;
+
private:
// We use bitfields because SplitInputSection is accessed by
// std::upper_bound very often.
@@ -181,7 +186,7 @@ private:
struct EhSectionPiece : public SectionPiece {
EhSectionPiece(size_t Off, ArrayRef<uint8_t> Data, unsigned FirstRelocation)
- : SectionPiece(Off, Data), Data(Data.data()),
+ : SectionPiece(Off, Data, 0, false), Data(Data.data()),
FirstRelocation(FirstRelocation) {}
const uint8_t *Data;
ArrayRef<uint8_t> data() { return {Data, size()}; }
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 683c15c6060..c2d736d3b1f 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -1244,14 +1244,16 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
for (SectionPiece &Piece : Sec->Pieces) {
if (!Piece.Live)
continue;
- uintX_t OutputOffset = Builder.add(toStringRef(Sec->getData(Piece)));
+ StringRef Data = toStringRef(Sec->getData(Piece));
+ CachedHashString V(Data, Piece.Hash);
+ uintX_t OutputOffset = Builder.add(V);
if (!shouldTailMerge())
Piece.OutputOff = OutputOffset;
}
}
template <class ELFT>
-unsigned MergeOutputSection<ELFT>::getOffset(StringRef Val) {
+unsigned MergeOutputSection<ELFT>::getOffset(CachedHashString Val) {
return Builder.getOffset(Val);
}
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 5dd6c46c25b..a405934b0de 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -427,7 +427,7 @@ public:
uintX_t Alignment);
void addSection(InputSectionBase<ELFT> *S) override;
void writeTo(uint8_t *Buf) override;
- unsigned getOffset(StringRef Val);
+ unsigned getOffset(llvm::CachedHashString Val);
void finalize() override;
void finalizePieces() override;
bool shouldTailMerge() const;
OpenPOWER on IntegriCloud