summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-09-04 20:45:50 +0000
committerRui Ueyama <ruiu@google.com>2015-09-04 20:45:50 +0000
commit2dcc23580e8a1f3e5667726dd5f997b280f4b273 (patch)
tree70523bf07ba963c3a49f95725867648bab186b40
parentbaec437f54765e82b693fe924588db488ef16521 (diff)
downloadbcm5719-llvm-2dcc23580e8a1f3e5667726dd5f997b280f4b273.tar.gz
bcm5719-llvm-2dcc23580e8a1f3e5667726dd5f997b280f4b273.zip
COFF: Use section content checksum for ICF.
Previously, we calculated our own hash values for section contents. Of coruse that's slow because we had to access all bytes in sections. Fortunately, COFF objects usually contain hash values for COMDAT sections. We can use that to speed up Identical COMDAT Folding. llvm-svn: 246869
-rw-r--r--lld/COFF/Chunks.h4
-rw-r--r--lld/COFF/ICF.cpp4
-rw-r--r--lld/COFF/InputFiles.cpp3
3 files changed, 9 insertions, 2 deletions
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index dc6de568c02..e5f5289ea98 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -183,6 +183,10 @@ public:
// and this chunk is considrered as dead.
SectionChunk *Ptr;
+ // The CRC of the contents as described in the COFF spec 4.5.5.
+ // Auxiliary Format 5: Section Definitions. Used for ICF.
+ uint32_t Checksum = 0;
+
private:
ArrayRef<uint8_t> getContents() const;
diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
index 4ec8f68fcf7..1c23722d9bc 100644
--- a/lld/COFF/ICF.cpp
+++ b/lld/COFF/ICF.cpp
@@ -44,7 +44,7 @@ uint64_t SectionChunk::getHash() const {
NumRelocs,
uint32_t(Header->SizeOfRawData),
std::distance(Relocs.end(), Relocs.begin()),
- hash_combine_range(A.data(), A.data() + A.size()));
+ Checksum);
}
// Returns true if this and a given chunk are identical COMDAT sections.
@@ -58,6 +58,8 @@ bool SectionChunk::equals(const SectionChunk *X) const {
return false;
if (NumRelocs != X->NumRelocs)
return false;
+ if (Checksum != X->Checksum)
+ return false;
// Compare data
if (getContents() != X->getContents())
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index a8a35a5cfde..a8537ec3965 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -225,13 +225,14 @@ Defined *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
if (!SC)
return nullptr;
- // Handle associative sections
+ // Handle section definitions
if (IsFirst && AuxP) {
auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP);
if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
if (auto *ParentSC = cast_or_null<SectionChunk>(
SparseChunks[Aux->getNumber(Sym.isBigObj())]))
ParentSC->addAssociative(SC);
+ SC->Checksum = Aux->CheckSum;
}
auto *B = new (Alloc) DefinedRegular(this, Sym, SC);
OpenPOWER on IntegriCloud