diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index 5c2116efa746..c44b269505aa 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -10,8 +10,6 @@ #include "Chunks.h" #include "InputFiles.h" #include "Writer.h" -#include "llvm/ADT/Hashing.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Object/COFF.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" @@ -211,58 +209,6 @@ StringRef SectionChunk::getDebugName() { return Sym->getName(); } -uint64_t SectionChunk::getHash() const { - ArrayRef A = getContents(); - return hash_combine(getPermissions(), - llvm::hash_value(SectionName), - NumRelocs, - uint32_t(Header->SizeOfRawData), - std::distance(Relocs.end(), Relocs.begin()), - hash_combine_range(A.data(), A.data() + A.size())); -} - -// Returns true if this and a given chunk are identical COMDAT sections. -bool SectionChunk::equals(const SectionChunk *X) const { - // Compare headers - if (getPermissions() != X->getPermissions()) - return false; - if (SectionName != X->SectionName) - return false; - if (Header->SizeOfRawData != X->Header->SizeOfRawData) - return false; - if (NumRelocs != X->NumRelocs) - return false; - - // Compare data - if (getContents() != X->getContents()) - return false; - - // Compare associative sections - if (AssocChildren.size() != X->AssocChildren.size()) - return false; - for (size_t I = 0, E = AssocChildren.size(); I != E; ++I) - if (AssocChildren[I]->Ptr != X->AssocChildren[I]->Ptr) - return false; - - // Compare relocations - auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { - if (R1.Type != R2.Type) - return false; - if (R1.VirtualAddress != R2.VirtualAddress) - return false; - SymbolBody *B1 = File->getSymbolBody(R1.SymbolTableIndex)->repl(); - SymbolBody *B2 = X->File->getSymbolBody(R2.SymbolTableIndex)->repl(); - if (B1 == B2) - return true; - auto *D1 = dyn_cast(B1); - auto *D2 = dyn_cast(B2); - return (D1 && D2 && - D1->getValue() == D2->getValue() && - D1->getChunk() == D2->getChunk()); - }; - return std::equal(Relocs.begin(), Relocs.end(), X->Relocs.begin(), Eq); -} - ArrayRef SectionChunk::getContents() const { ArrayRef A; File->getCOFFObj()->getSectionContents(Header, A); diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index 67ce67a4bcbe..4ec8f68fcf7a 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -12,10 +12,15 @@ //===----------------------------------------------------------------------===// #include "Chunks.h" +#include "Symbols.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/STLExtras.h" #include #include #include +using namespace llvm; + namespace lld { namespace coff { namespace { @@ -32,6 +37,58 @@ struct Equals { } // anonymous namespace +uint64_t SectionChunk::getHash() const { + ArrayRef A = getContents(); + return hash_combine(getPermissions(), + hash_value(SectionName), + NumRelocs, + uint32_t(Header->SizeOfRawData), + std::distance(Relocs.end(), Relocs.begin()), + hash_combine_range(A.data(), A.data() + A.size())); +} + +// Returns true if this and a given chunk are identical COMDAT sections. +bool SectionChunk::equals(const SectionChunk *X) const { + // Compare headers + if (getPermissions() != X->getPermissions()) + return false; + if (SectionName != X->SectionName) + return false; + if (Header->SizeOfRawData != X->Header->SizeOfRawData) + return false; + if (NumRelocs != X->NumRelocs) + return false; + + // Compare data + if (getContents() != X->getContents()) + return false; + + // Compare associative sections + if (AssocChildren.size() != X->AssocChildren.size()) + return false; + for (size_t I = 0, E = AssocChildren.size(); I != E; ++I) + if (AssocChildren[I]->Ptr != X->AssocChildren[I]->Ptr) + return false; + + // Compare relocations + auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) { + if (R1.Type != R2.Type) + return false; + if (R1.VirtualAddress != R2.VirtualAddress) + return false; + SymbolBody *B1 = File->getSymbolBody(R1.SymbolTableIndex)->repl(); + SymbolBody *B2 = X->File->getSymbolBody(R2.SymbolTableIndex)->repl(); + if (B1 == B2) + return true; + auto *D1 = dyn_cast(B1); + auto *D2 = dyn_cast(B2); + return (D1 && D2 && + D1->getValue() == D2->getValue() && + D1->getChunk() == D2->getChunk()); + }; + return std::equal(Relocs.begin(), Relocs.end(), X->Relocs.begin(), Eq); +} + // Merge identical COMDAT sections. // Two sections are considered as identical when their section headers, // contents and relocations are all the same.