summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2019-01-22 23:51:35 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2019-01-22 23:51:35 +0000
commit342611114580412d814ae435e1d1b37be22f86e8 (patch)
treebe9da1f9b94ef2bc3a9eb0c35b387e1941e0287e
parent881cae7a4576c477d38da864bc97ceaed2484617 (diff)
downloadbcm5719-llvm-342611114580412d814ae435e1d1b37be22f86e8.tar.gz
bcm5719-llvm-342611114580412d814ae435e1d1b37be22f86e8.zip
COFF, ELF: Adjust ICF hash computation to account for self relocations.
It turns out that sections in PGO instrumented object files on Windows contain a large number of relocations pointing to themselves. With r347429 this can cause many sections to receive the same hash (usually zero) as a result of a section's hash being xor'ed with itself. This patch causes the COFF and ELF linkers to avoid this problem by adding the hash of the relocated section instead of xor'ing it. On my machine this causes the regressing test case provided by Mozilla to terminate in 2m41s. Differential Revision: https://reviews.llvm.org/D56955 llvm-svn: 351898
-rw-r--r--lld/COFF/ICF.cpp2
-rw-r--r--lld/ELF/ICF.cpp2
2 files changed, 2 insertions, 2 deletions
diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
index 84709de2a6f..88e67443c26 100644
--- a/lld/COFF/ICF.cpp
+++ b/lld/COFF/ICF.cpp
@@ -271,7 +271,7 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
uint32_t Hash = SC->Class[1];
for (Symbol *B : SC->symbols())
if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
- Hash ^= Sym->getChunk()->Class[1];
+ Hash += Sym->getChunk()->Class[1];
// Set MSB to 1 to avoid collisions with non-hash classs.
SC->Class[0] = Hash | (1U << 31);
});
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 14dbd4e122c..3f326fa337b 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -431,7 +431,7 @@ static void combineRelocHashes(InputSection *IS, ArrayRef<RelTy> Rels) {
Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
if (auto *D = dyn_cast<Defined>(&S))
if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
- Hash ^= RelSec->Class[1];
+ Hash += RelSec->Class[1];
}
// Set MSB to 1 to avoid collisions with non-hash IDs.
IS->Class[0] = Hash | (1U << 31);
OpenPOWER on IntegriCloud