diff options
Diffstat (limited to 'COFF/ICF.cpp')
| -rw-r--r-- | COFF/ICF.cpp | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/COFF/ICF.cpp b/COFF/ICF.cpp index 7feb3c4e0b0c..34ea360fa925 100644 --- a/COFF/ICF.cpp +++ b/COFF/ICF.cpp @@ -22,6 +22,7 @@ #include "Chunks.h" #include "Symbols.h" #include "lld/Common/ErrorHandler.h" +#include "lld/Common/Threads.h" #include "lld/Common/Timer.h" #include "llvm/ADT/Hashing.h" #include "llvm/Support/Debug.h" @@ -80,7 +81,7 @@ private: bool ICF::isEligible(SectionChunk *C) { // Non-comdat chunks, dead chunks, and writable chunks are not elegible. bool Writable = C->getOutputCharacteristics() & llvm::COFF::IMAGE_SCN_MEM_WRITE; - if (!C->isCOMDAT() || !C->isLive() || Writable) + if (!C->isCOMDAT() || !C->Live || Writable) return false; // Code sections are eligible. @@ -93,7 +94,11 @@ bool ICF::isEligible(SectionChunk *C) { return true; // So are vtables. - return C->Sym && C->Sym->getName().startswith("??_7"); + if (C->Sym && C->Sym->getName().startswith("??_7")) + return true; + + // Anything else not in an address-significance table is eligible. + return !C->KeepUnique; } // Split an equivalence class into smaller classes. @@ -222,10 +227,10 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) { size_t Boundaries[NumShards + 1]; Boundaries[0] = 0; Boundaries[NumShards] = Chunks.size(); - for_each_n(parallel::par, size_t(1), NumShards, [&](size_t I) { + parallelForEachN(1, NumShards, [&](size_t I) { Boundaries[I] = findBoundary((I - 1) * Step, Chunks.size()); }); - for_each_n(parallel::par, size_t(1), NumShards + 1, [&](size_t I) { + parallelForEachN(1, NumShards + 1, [&](size_t I) { if (Boundaries[I - 1] < Boundaries[I]) { forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn); } @@ -257,9 +262,19 @@ void ICF::run(ArrayRef<Chunk *> Vec) { SC->Class[0] = NextId++; // Initially, we use hash values to partition sections. - for_each(parallel::par, Chunks.begin(), Chunks.end(), [&](SectionChunk *SC) { + parallelForEach(Chunks, [&](SectionChunk *SC) { + SC->Class[1] = xxHash64(SC->getContents()); + }); + + // Combine the hashes of the sections referenced by each section into its + // hash. + parallelForEach(Chunks, [&](SectionChunk *SC) { + uint32_t Hash = SC->Class[1]; + for (Symbol *B : SC->symbols()) + if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B)) + Hash ^= Sym->getChunk()->Class[1]; // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[0] = xxHash64(SC->getContents()) | (1 << 31); + SC->Class[0] = Hash | (1U << 31); }); // From now on, sections in Chunks are ordered so that sections in |
