From c81be651662e09a736d1d210deda25eacd4673df Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 26 Nov 2018 21:15:47 +0000 Subject: [PATCH] ELF: ICF: Include contents of referenced sections in initial partitioning hash. NFCI. On my machine this reduced median link time of lld-speed-test/chrome from 2.68s to 2.41s. It also reduces link time of Chrome for Android with a prototype compiler change that causes the compiler to create large numbers of identical (modulo relocations) sections from >15 minutes to a few seconds. Differential Revision: https://reviews.llvm.org/D54773 llvm-svn: 347594 --- lld/ELF/ICF.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index 176c627..8446661 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -119,6 +119,9 @@ private: 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 @@ void ICF::forEachClass(llvm::function_ref Fn) { ++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 @@ template void ICF::run() { // 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 -- 2.7.4