From: Rui Ueyama Date: Wed, 24 May 2017 19:56:29 +0000 (+0000) Subject: Close the gap between ELF and COFF ICF implementations. NFC. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=27abe98cfabaffe66cbe3eef9cc11fbd3ef43921;p=platform%2Fupstream%2Fllvm.git Close the gap between ELF and COFF ICF implementations. NFC. We originally wrote the ICF code for COFF and ported it to ELF. They started diverging since then. This patch closes the gap. llvm-svn: 303801 --- diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index aa08095..2e26eb0 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -56,7 +56,6 @@ private: std::vector Chunks; int Cnt = 0; - std::atomic NextId = {1}; std::atomic Repeat = {false}; }; @@ -98,10 +97,10 @@ void ICF::segregate(size_t Begin, size_t End, bool Constant) { }); size_t Mid = Bound - Chunks.begin(); - // Split [Begin, End) into [Begin, Mid) and [Mid, End). - uint32_t Id = NextId++; + // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an + // equivalence class ID because every group ends with a unique index. for (size_t I = Begin; I < Mid; ++I) - Chunks[I]->Class[(Cnt + 1) % 2] = Id; + Chunks[I]->Class[(Cnt + 1) % 2] = Mid; // If we created a group, we need to iterate the main loop again. if (Mid != End) @@ -186,6 +185,7 @@ void ICF::forEachClass(std::function Fn) { // call Fn sequentially. if (Chunks.size() < 1024) { forEachClassRange(0, Chunks.size(), Fn); + ++Cnt; return; } @@ -196,6 +196,7 @@ void ICF::forEachClass(std::function Fn) { size_t End = (I == NumShards - 1) ? Chunks.size() : (I + 1) * Step; forEachClassRange(I * Step, End, Fn); }); + ++Cnt; } // Merge identical COMDAT sections. @@ -203,22 +204,15 @@ void ICF::forEachClass(std::function Fn) { // contents and relocations are all the same. void ICF::run(const std::vector &Vec) { // Collect only mergeable sections and group by hash value. - for (Chunk *C : Vec) { - auto *SC = dyn_cast(C); - if (!SC) - continue; - - if (isEligible(SC)) { - // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[0] = getHash(SC) | (1 << 31); - Chunks.push_back(SC); - } else { - SC->Class[0] = NextId++; - } - } + for (Chunk *C : Vec) + if (auto *SC = dyn_cast(C)) + if (isEligible(SC)) + Chunks.push_back(SC); - if (Chunks.empty()) - return; + // Initially, we use hash values to partition sections. + for (SectionChunk *SC : Chunks) + // Set MSB to 1 to avoid collisions with non-hash classs. + SC->Class[0] = getHash(SC) | (1 << 31); // From now on, sections in Chunks are ordered so that sections in // the same group are consecutive in the vector. @@ -229,14 +223,12 @@ void ICF::run(const std::vector &Vec) { // Compare static contents and assign unique IDs for each static content. forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); }); - ++Cnt; // Split groups by comparing relocations until convergence is obtained. do { Repeat = false; forEachClass( [&](size_t Begin, size_t End) { segregate(Begin, End, false); }); - ++Cnt; } while (Repeat); log("ICF needed " + Twine(Cnt) + " iterations");