Reland r338088, "ELF: Make --print-icf-sections output deterministic."
The xxHash64 function has been made unsigned-char-independent, so we can reland this change now. Original commit message: > The icf-safe.s test currently fails on 32-bit platforms because it uses > the --print-icf-sections flag and depends on the output appearing in > a specific order. However, this flag causes the output to depend on > the order of the sections in the Sections array, which depends on the > hash values returned from hash_combine, which happen to be different > for that test between 32-bit and 64-bit platforms. > > This change makes the output deterministic by using xxHash64 instead of > hash_combine. Differential Revision: https://reviews.llvm.org/D49877 llvm-svn: 338153
This commit is contained in:
parent
f611ce82c0
commit
e6c78eafde
|
@ -80,9 +80,10 @@
|
||||||
#include "SyntheticSections.h"
|
#include "SyntheticSections.h"
|
||||||
#include "Writer.h"
|
#include "Writer.h"
|
||||||
#include "lld/Common/Threads.h"
|
#include "lld/Common/Threads.h"
|
||||||
#include "llvm/ADT/Hashing.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/BinaryFormat/ELF.h"
|
#include "llvm/BinaryFormat/ELF.h"
|
||||||
#include "llvm/Object/ELF.h"
|
#include "llvm/Object/ELF.h"
|
||||||
|
#include "llvm/Support/xxhash.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
@ -155,12 +156,6 @@ private:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a hash value for S. Note that the information about
|
|
||||||
// relocation targets is not included in the hash value.
|
|
||||||
template <class ELFT> static uint32_t getHash(InputSection *S) {
|
|
||||||
return hash_combine(S->Flags, S->getSize(), S->NumRelocations, S->Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if section S is subject of ICF.
|
// Returns true if section S is subject of ICF.
|
||||||
static bool isEligible(InputSection *S) {
|
static bool isEligible(InputSection *S) {
|
||||||
if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC))
|
if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC))
|
||||||
|
@ -441,7 +436,7 @@ template <class ELFT> void ICF<ELFT>::run() {
|
||||||
// Initially, we use hash values to partition sections.
|
// Initially, we use hash values to partition sections.
|
||||||
parallelForEach(Sections, [&](InputSection *S) {
|
parallelForEach(Sections, [&](InputSection *S) {
|
||||||
// Set MSB to 1 to avoid collisions with non-hash IDs.
|
// Set MSB to 1 to avoid collisions with non-hash IDs.
|
||||||
S->Class[0] = getHash<ELFT>(S) | (1U << 31);
|
S->Class[0] = xxHash64(toStringRef(S->Data)) | (1U << 31);
|
||||||
});
|
});
|
||||||
|
|
||||||
// From now on, sections in Sections vector are ordered so that sections
|
// From now on, sections in Sections vector are ordered so that sections
|
||||||
|
|
|
@ -10,10 +10,6 @@
|
||||||
# RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections --export-dynamic | FileCheck --check-prefix=ALL-EXPORT %s
|
# RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections --export-dynamic | FileCheck --check-prefix=ALL-EXPORT %s
|
||||||
# RUN: ld.lld %t1copy.o -o %t4 --icf=safe 2>&1 | FileCheck --check-prefix=OBJCOPY %s
|
# RUN: ld.lld %t1copy.o -o %t4 --icf=safe 2>&1 | FileCheck --check-prefix=OBJCOPY %s
|
||||||
|
|
||||||
# CHECK-NOT: selected section {{.*}}:(.rodata.l1)
|
|
||||||
# CHECK: selected section {{.*}}:(.rodata.l3)
|
|
||||||
# CHECK: removing identical section {{.*}}:(.rodata.l4)
|
|
||||||
|
|
||||||
# CHECK-NOT: selected section {{.*}}:(.text.f1)
|
# CHECK-NOT: selected section {{.*}}:(.text.f1)
|
||||||
# CHECK: selected section {{.*}}:(.text.f3)
|
# CHECK: selected section {{.*}}:(.text.f3)
|
||||||
# CHECK: removing identical section {{.*}}:(.text.f4)
|
# CHECK: removing identical section {{.*}}:(.text.f4)
|
||||||
|
@ -22,6 +18,10 @@
|
||||||
# CHECK: selected section {{.*}}:(.rodata.h3)
|
# CHECK: selected section {{.*}}:(.rodata.h3)
|
||||||
# CHECK: removing identical section {{.*}}:(.rodata.h4)
|
# CHECK: removing identical section {{.*}}:(.rodata.h4)
|
||||||
|
|
||||||
|
# CHECK-NOT: selected section {{.*}}:(.rodata.l1)
|
||||||
|
# CHECK: selected section {{.*}}:(.rodata.l3)
|
||||||
|
# CHECK: removing identical section {{.*}}:(.rodata.l4)
|
||||||
|
|
||||||
# CHECK-NOT: selected section {{.*}}:(.rodata.g1)
|
# CHECK-NOT: selected section {{.*}}:(.rodata.g1)
|
||||||
# CHECK: selected section {{.*}}:(.rodata.g3)
|
# CHECK: selected section {{.*}}:(.rodata.g3)
|
||||||
# CHECK: removing identical section {{.*}}:(.rodata.g4)
|
# CHECK: removing identical section {{.*}}:(.rodata.g4)
|
||||||
|
@ -30,26 +30,26 @@
|
||||||
|
|
||||||
# With --icf=all address-significance implies keep-unique only for rodata, not
|
# With --icf=all address-significance implies keep-unique only for rodata, not
|
||||||
# text.
|
# text.
|
||||||
# ALL-NOT: selected section {{.*}}:(.rodata.l1)
|
|
||||||
# ALL: selected section {{.*}}:(.rodata.l3)
|
|
||||||
# ALL: removing identical section {{.*}}:(.rodata.l4)
|
|
||||||
|
|
||||||
# ALL: selected section {{.*}}:(.text.f3)
|
# ALL: selected section {{.*}}:(.text.f3)
|
||||||
# ALL: removing identical section {{.*}}:(.text.f4)
|
# ALL: removing identical section {{.*}}:(.text.f4)
|
||||||
|
|
||||||
# ALL: selected section {{.*}}:(.text.f1)
|
|
||||||
# ALL: removing identical section {{.*}}:(.text.f2)
|
|
||||||
# ALL: removing identical section {{.*}}:(.text.non_addrsig1)
|
|
||||||
# ALL: removing identical section {{.*}}:(.text.non_addrsig2)
|
|
||||||
|
|
||||||
# ALL-NOT: selected section {{.*}}:(.rodata.h1)
|
# ALL-NOT: selected section {{.*}}:(.rodata.h1)
|
||||||
# ALL: selected section {{.*}}:(.rodata.h3)
|
# ALL: selected section {{.*}}:(.rodata.h3)
|
||||||
# ALL: removing identical section {{.*}}:(.rodata.h4)
|
# ALL: removing identical section {{.*}}:(.rodata.h4)
|
||||||
|
|
||||||
|
# ALL-NOT: selected section {{.*}}:(.rodata.l1)
|
||||||
|
# ALL: selected section {{.*}}:(.rodata.l3)
|
||||||
|
# ALL: removing identical section {{.*}}:(.rodata.l4)
|
||||||
|
|
||||||
# ALL-NOT: selected section {{.*}}:(.rodata.g1)
|
# ALL-NOT: selected section {{.*}}:(.rodata.g1)
|
||||||
# ALL: selected section {{.*}}:(.rodata.g3)
|
# ALL: selected section {{.*}}:(.rodata.g3)
|
||||||
# ALL: removing identical section {{.*}}:(.rodata.g4)
|
# ALL: removing identical section {{.*}}:(.rodata.g4)
|
||||||
|
|
||||||
|
# ALL: selected section {{.*}}:(.text.f1)
|
||||||
|
# ALL: removing identical section {{.*}}:(.text.f2)
|
||||||
|
# ALL: removing identical section {{.*}}:(.text.non_addrsig1)
|
||||||
|
# ALL: removing identical section {{.*}}:(.text.non_addrsig2)
|
||||||
|
|
||||||
# llvm-mc normally emits an empty .text section into every object file. Since
|
# llvm-mc normally emits an empty .text section into every object file. Since
|
||||||
# nothing actually refers to it via a relocation, it doesn't have any associated
|
# nothing actually refers to it via a relocation, it doesn't have any associated
|
||||||
# symbols (thus nor can anything refer to it via a relocation, making it safe to
|
# symbols (thus nor can anything refer to it via a relocation, making it safe to
|
||||||
|
@ -58,36 +58,36 @@
|
||||||
# STB_LOCAL or STV_HIDDEN symbols. The dynsym entries should have prevented
|
# STB_LOCAL or STV_HIDDEN symbols. The dynsym entries should have prevented
|
||||||
# anything else from being merged.
|
# anything else from being merged.
|
||||||
# EXPORT-NOT: selected section
|
# EXPORT-NOT: selected section
|
||||||
# EXPORT: selected section {{.*}}:(.rodata.l3)
|
|
||||||
# EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
|
||||||
# EXPORT-NOT: selected section
|
|
||||||
# EXPORT: selected section {{.*}}:(.rodata.h3)
|
# EXPORT: selected section {{.*}}:(.rodata.h3)
|
||||||
# EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
# EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
||||||
# EXPORT-NOT: selected section
|
# EXPORT-NOT: selected section
|
||||||
# EXPORT: selected section {{.*}}:(.text)
|
# EXPORT: selected section {{.*}}:(.text)
|
||||||
# EXPORT: removing identical section {{.*}}:(.text)
|
# EXPORT: removing identical section {{.*}}:(.text)
|
||||||
# EXPORT-NOT: selected section
|
# EXPORT-NOT: selected section
|
||||||
|
# EXPORT: selected section {{.*}}:(.rodata.l3)
|
||||||
|
# EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
||||||
|
# EXPORT-NOT: selected section
|
||||||
|
|
||||||
# If --icf=all is specified when exporting we can also merge the exported text
|
# If --icf=all is specified when exporting we can also merge the exported text
|
||||||
# sections, but not the exported rodata.
|
# sections, but not the exported rodata.
|
||||||
# ALL-EXPORT-NOT: selected section
|
# ALL-EXPORT-NOT: selected section
|
||||||
# ALL-EXPORT: selected section {{.*}}:(.rodata.l3)
|
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
|
||||||
# ALL-EXPORT-NOT: selected section
|
|
||||||
# ALL-EXPORT: selected section {{.*}}:(.text.f3)
|
# ALL-EXPORT: selected section {{.*}}:(.text.f3)
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.f4)
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.f4)
|
||||||
# ALL-EXPORT-NOT: selected section
|
# ALL-EXPORT-NOT: selected section
|
||||||
# ALL-EXPORT: selected section {{.*}}:(.text.f1)
|
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.f2)
|
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1)
|
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2)
|
|
||||||
# ALL-EXPORT-NOT: selected section
|
|
||||||
# ALL-EXPORT: selected section {{.*}}:(.rodata.h3)
|
# ALL-EXPORT: selected section {{.*}}:(.rodata.h3)
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
||||||
# ALL-EXPORT-NOT: selected section
|
# ALL-EXPORT-NOT: selected section
|
||||||
# ALL-EXPORT: selected section {{.*}}:(.text)
|
# ALL-EXPORT: selected section {{.*}}:(.text)
|
||||||
# ALL-EXPORT: removing identical section {{.*}}:(.text)
|
# ALL-EXPORT: removing identical section {{.*}}:(.text)
|
||||||
# ALL-EXPORT-NOT: selected section
|
# ALL-EXPORT-NOT: selected section
|
||||||
|
# ALL-EXPORT: selected section {{.*}}:(.rodata.l3)
|
||||||
|
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
||||||
|
# ALL-EXPORT-NOT: selected section
|
||||||
|
# ALL-EXPORT: selected section {{.*}}:(.text.f1)
|
||||||
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.f2)
|
||||||
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1)
|
||||||
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2)
|
||||||
|
# ALL-EXPORT-NOT: selected section
|
||||||
|
|
||||||
# OBJCOPY: --icf=safe is incompatible with object files created using objcopy or ld -r
|
# OBJCOPY: --icf=safe is incompatible with object files created using objcopy or ld -r
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue