std::vector<SectionChunk *> Chunks;
int Cnt = 0;
- std::atomic<uint32_t> NextId = {1};
std::atomic<bool> Repeat = {false};
};
});
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)
// call Fn sequentially.
if (Chunks.size() < 1024) {
forEachClassRange(0, Chunks.size(), Fn);
+ ++Cnt;
return;
}
size_t End = (I == NumShards - 1) ? Chunks.size() : (I + 1) * Step;
forEachClassRange(I * Step, End, Fn);
});
+ ++Cnt;
}
// Merge identical COMDAT sections.
// contents and relocations are all the same.
void ICF::run(const std::vector<Chunk *> &Vec) {
// Collect only mergeable sections and group by hash value.
- for (Chunk *C : Vec) {
- auto *SC = dyn_cast<SectionChunk>(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<SectionChunk>(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.
// 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");