Index: ELF/ICF.cpp =================================================================== --- ELF/ICF.cpp +++ ELF/ICF.cpp @@ -119,6 +119,9 @@ void forEachClass(llvm::function_ref Fn); + template + void combineRelocHashes(InputSection *IS, ArrayRef Rels); + std::vector Sections; // We repeat the main loop while `Repeat` is true. @@ -423,6 +426,22 @@ ++Cnt; } +// Combine the hashes of the sections referenced by the given section into its +// hash. +template +template +void ICF::combineRelocHashes(InputSection *IS, ArrayRef Rels) { + uint32_t Hash = IS->Class[1]; + for (RelTy Rel : Rels) { + Symbol &S = IS->template getFile()->getRelocTargetSym(Rel); + if (auto *D = dyn_cast(&S)) + if (auto *RelSec = dyn_cast_or_null(D->Section)) + Hash ^= RelSec->Class[1]; + } + // Set MSB to 1 to avoid collisions with non-hash IDs. + IS->Class[0] = Hash | (1U << 31); +} + static void print(const Twine &S) { if (Config->PrintIcfSections) message(S); @@ -438,8 +457,14 @@ // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { - // Set MSB to 1 to avoid collisions with non-hash IDs. - S->Class[0] = xxHash64(S->data()) | (1U << 31); + S->Class[1] = xxHash64(S->data()); + }); + + parallelForEach(Sections, [&](InputSection *S) { + if (S->AreRelocsRela) + combineRelocHashes(S, S->template relas()); + else + combineRelocHashes(S, S->template rels()); }); // From now on, sections in Sections vector are ordered so that sections