summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-05-24 19:56:29 +0000
committerRui Ueyama <ruiu@google.com>2017-05-24 19:56:29 +0000
commit27abe98cfabaffe66cbe3eef9cc11fbd3ef43921 (patch)
treeb86b92fe7ddf8e5ac3f5256db88567ba76e23499
parentbb20b5d5c31b7f6326c7b0db5e6b3357150be83f (diff)
downloadbcm5719-llvm-27abe98cfabaffe66cbe3eef9cc11fbd3ef43921.tar.gz
bcm5719-llvm-27abe98cfabaffe66cbe3eef9cc11fbd3ef43921.zip
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
-rw-r--r--lld/COFF/ICF.cpp34
1 files changed, 13 insertions, 21 deletions
diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
index aa080958fe1..2e26eb05b53 100644
--- a/lld/COFF/ICF.cpp
+++ b/lld/COFF/ICF.cpp
@@ -56,7 +56,6 @@ private:
std::vector<SectionChunk *> Chunks;
int Cnt = 0;
- std::atomic<uint32_t> NextId = {1};
std::atomic<bool> 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<void(size_t, size_t)> Fn) {
// call Fn sequentially.
if (Chunks.size() < 1024) {
forEachClassRange(0, Chunks.size(), Fn);
+ ++Cnt;
return;
}
@@ -196,6 +196,7 @@ void ICF::forEachClass(std::function<void(size_t, size_t)> 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<void(size_t, size_t)> Fn) {
// 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.
@@ -229,14 +223,12 @@ void ICF::run(const std::vector<Chunk *> &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");
OpenPOWER on IntegriCloud