Index: lld/COFF/ICF.cpp =================================================================== --- lld/COFF/ICF.cpp +++ lld/COFF/ICF.cpp @@ -263,24 +263,26 @@ // Initially, we use hash values to partition sections. parallelForEach(Chunks, [&](SectionChunk *SC) { - SC->Class[1] = xxHash64(SC->getContents()); + SC->Class[0] = 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(B)) { - // Rotate the hash by 1 to prevent it from being cancelled out by a - // self-relocation. - Hash = (Hash << 1) | (Hash >> 31); - Hash ^= Sym->getChunk()->Class[1]; + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Chunks, [&](SectionChunk *SC) { + uint32_t Hash = SC->Class[Cnt % 2]; + for (Symbol *B : SC->symbols()) { + if (auto *Sym = dyn_cast_or_null(B)) { + // Rotate the hash by 1 to prevent it from being cancelled out by a + // self-relocation. + Hash = (Hash << 1) | (Hash >> 31); + Hash ^= Sym->getChunk()->Class[Cnt % 2]; + } } - } - // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[0] = Hash | (1U << 31); - }); + // Set MSB to 1 to avoid collisions with non-hash classs. + SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31); + }); + } // From now on, sections in Chunks are ordered so that sections in // the same group are consecutive in the vector. Index: lld/ELF/ICF.cpp =================================================================== --- lld/ELF/ICF.cpp +++ lld/ELF/ICF.cpp @@ -426,8 +426,9 @@ // Combine the hashes of the sections referenced by the given section into its // hash. template -static void combineRelocHashes(InputSection *IS, ArrayRef Rels) { - uint32_t Hash = IS->Class[1]; +static void combineRelocHashes(unsigned Cnt, InputSection *IS, + ArrayRef Rels) { + uint32_t Hash = IS->Class[Cnt % 2]; for (RelTy Rel : Rels) { Symbol &S = IS->template getFile()->getRelocTargetSym(Rel); if (auto *D = dyn_cast(&S)) { @@ -435,12 +436,12 @@ // Rotate the hash by 1 to prevent it from being cancelled out by a // self-relocation. Hash = (Hash << 1) | (Hash >> 31); - Hash ^= RelSec->Class[1]; + Hash ^= RelSec->Class[Cnt % 2]; } } } // Set MSB to 1 to avoid collisions with non-hash IDs. - IS->Class[0] = Hash | (1U << 31); + IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31); } static void print(const Twine &S) { @@ -458,15 +459,17 @@ // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { - S->Class[1] = xxHash64(S->data()); + S->Class[0] = xxHash64(S->data()); }); - parallelForEach(Sections, [&](InputSection *S) { - if (S->AreRelocsRela) - combineRelocHashes(S, S->template relas()); - else - combineRelocHashes(S, S->template rels()); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Sections, [&](InputSection *S) { + if (S->AreRelocsRela) + combineRelocHashes(Cnt, S, S->template relas()); + else + combineRelocHashes(Cnt, S, S->template rels()); + }); + } // From now on, sections in Sections vector are ordered so that sections // in the same equivalence class are consecutive in the vector.